@blocklet/list 0.8.14 → 0.8.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/base.js +21 -24
  2. package/lib/components/{aside.js → aside/aside.js} +11 -12
  3. package/lib/components/aside/category-link-list.js +78 -0
  4. package/lib/components/aside/index.js +13 -0
  5. package/lib/components/category-select.js +55 -0
  6. package/lib/components/{button.js → custom-select/button.js} +1 -1
  7. package/lib/components/{custom-select.js → custom-select/custom-select.js} +8 -6
  8. package/lib/components/custom-select/index.js +13 -0
  9. package/lib/components/filter-author.js +2 -3
  10. package/lib/components/{empty.js → list/empty.js} +6 -8
  11. package/lib/components/list/index.js +13 -0
  12. package/lib/components/{list.js → list/list.js} +12 -12
  13. package/lib/components/search.js +21 -19
  14. package/lib/contexts/filter.js +268 -0
  15. package/lib/index.js +6 -16
  16. package/lib/libs/prop-types.js +34 -0
  17. package/lib/{tools → libs}/utils.js +6 -6
  18. package/package.json +60 -64
  19. package/src/base.js +17 -18
  20. package/src/components/{aside.js → aside/aside.js} +7 -8
  21. package/src/components/aside/category-link-list.js +53 -0
  22. package/src/components/aside/index.js +3 -0
  23. package/src/components/category-select.js +43 -0
  24. package/src/components/{button.js → custom-select/button.js} +0 -0
  25. package/src/components/{custom-select.js → custom-select/custom-select.js} +5 -4
  26. package/src/components/custom-select/index.js +3 -0
  27. package/src/components/filter-author.js +2 -3
  28. package/src/components/{empty.js → list/empty.js} +7 -8
  29. package/src/components/list/index.js +3 -0
  30. package/src/components/{list.js → list/list.js} +10 -10
  31. package/src/components/search.js +18 -14
  32. package/src/contexts/filter.js +197 -0
  33. package/src/index.js +6 -16
  34. package/src/libs/prop-types.js +26 -0
  35. package/src/{tools → libs}/utils.js +6 -6
  36. package/lib/components/categories.js +0 -143
  37. package/lib/contexts/store.js +0 -336
  38. package/lib/hooks/page-state.js +0 -69
  39. package/src/components/categories.js +0 -129
  40. package/src/contexts/store.js +0 -266
  41. package/src/hooks/page-state.js +0 -53
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FilterConsumer = void 0;
7
+ exports.FilterProvider = FilterProvider;
8
+ exports.useFilterContext = useFilterContext;
9
+
10
+ var _react = _interopRequireWildcard(require("react"));
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _ahooks = require("ahooks");
15
+
16
+ var _orderBy = _interopRequireDefault(require("lodash/orderBy"));
17
+
18
+ var _axios = _interopRequireDefault(require("axios"));
19
+
20
+ var _utils = require("../libs/utils");
21
+
22
+ var _locale = _interopRequireDefault(require("../assets/locale"));
23
+
24
+ var _propTypes2 = require("../libs/prop-types");
25
+
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
+
28
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
29
+
30
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
31
+
32
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
33
+
34
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
35
+
36
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
37
+
38
+ const Filter = /*#__PURE__*/(0, _react.createContext)({});
39
+ const {
40
+ Provider,
41
+ Consumer
42
+ } = Filter;
43
+ exports.FilterConsumer = Consumer;
44
+
45
+ function FilterProvider(_ref) {
46
+ let {
47
+ onSelectBlocklet,
48
+ selectedBlocklets,
49
+ filters,
50
+ children,
51
+ baseUrl,
52
+ endpoint,
53
+ locale,
54
+ blockletRender,
55
+ onFilterChange
56
+ } = _ref;
57
+
58
+ const storeApi = _axios.default.create({
59
+ baseURL: endpoint
60
+ });
61
+
62
+ const {
63
+ data: allBlocklets,
64
+ error: fetchBlockletsError,
65
+ loading: fetchBlockletsLoading,
66
+ run: fetchBlocklets
67
+ } = (0, _ahooks.useRequest)(async () => {
68
+ const {
69
+ data: list
70
+ } = await storeApi.get('/api/blocklets.json');
71
+ return list;
72
+ }, {
73
+ initialData: [],
74
+ manual: true
75
+ });
76
+ const {
77
+ data: allCategories,
78
+ error: fetchCategoriesError,
79
+ loading: fetchCategoriesLoading,
80
+ run: fetchCategories
81
+ } = (0, _ahooks.useRequest)(async () => {
82
+ const {
83
+ data: list
84
+ } = await storeApi.get('/api/blocklets/categories');
85
+ return list;
86
+ }, {
87
+ initialData: [],
88
+ manual: true
89
+ });
90
+ const selectedCategory = filters.category;
91
+ const hasDeveloperFilter = !!filters.developer;
92
+ const categoryState = (0, _react.useMemo)(() => {
93
+ return !hasDeveloperFilter ? {
94
+ data: allCategories
95
+ } : (0, _utils.getCategories)(allBlocklets, filters.developer);
96
+ }, [hasDeveloperFilter, allCategories]);
97
+ const blockletList = (0, _react.useMemo)(() => {
98
+ var _filters$keyword;
99
+
100
+ const sortByName = x => {
101
+ var _x$title, _x$name;
102
+
103
+ return (x === null || x === void 0 ? void 0 : (_x$title = x.title) === null || _x$title === void 0 ? void 0 : _x$title.toLocaleLowerCase()) || (x === null || x === void 0 ? void 0 : (_x$name = x.name) === null || _x$name === void 0 ? void 0 : _x$name.toLocaleLowerCase());
104
+ }; // 按名称排序
105
+
106
+
107
+ const sortByPopularity = x => x.stats.downloads; // 按下载量排序
108
+
109
+
110
+ const sortByPublish = x => x.lastPublishedAt; // 按发布时间
111
+
112
+
113
+ const sortMap = {
114
+ nameAsc: sortByName,
115
+ nameDesc: sortByName,
116
+ popularity: sortByPopularity,
117
+ publishAt: sortByPublish
118
+ };
119
+ let result = allBlocklets || []; // 按照付费/免费筛选
120
+
121
+ result = (0, _utils.filterBlockletByPrice)(result, filters.price); // 按照分类筛选
122
+
123
+ result = result.filter(item => {
124
+ var _item$category;
125
+
126
+ return selectedCategory ? (item === null || item === void 0 ? void 0 : (_item$category = item.category) === null || _item$category === void 0 ? void 0 : _item$category.name) === selectedCategory : true;
127
+ }); // 按照作者筛选
128
+
129
+ result = result.filter(item => filters !== null && filters !== void 0 && filters.developer ? item.owner.did === filters.developer : true);
130
+ const lowerSearch = (filters === null || filters === void 0 ? void 0 : (_filters$keyword = filters.keyword) === null || _filters$keyword === void 0 ? void 0 : _filters$keyword.toLocaleLowerCase()) || ''; // 按照搜索筛选
131
+
132
+ result = result.filter(item => {
133
+ var _ref2, _item$description, _item$version;
134
+
135
+ return ((_ref2 = (item === null || item === void 0 ? void 0 : item.title) || (item === null || item === void 0 ? void 0 : item.name)) === null || _ref2 === void 0 ? void 0 : _ref2.toLocaleLowerCase().includes(lowerSearch)) || ((_item$description = item.description) === null || _item$description === void 0 ? void 0 : _item$description.toLocaleLowerCase().includes(lowerSearch)) || (item === null || item === void 0 ? void 0 : (_item$version = item.version) === null || _item$version === void 0 ? void 0 : _item$version.toLocaleLowerCase().includes(lowerSearch));
136
+ }); // 排序
137
+
138
+ return (0, _orderBy.default)(result, [sortMap[filters.sortBy]], [filters.sortDirection]);
139
+ }, [allBlocklets, filters]);
140
+ const categoryList = (0, _react.useMemo)(() => {
141
+ const list = categoryState.data || []; // 分类按照名称排序
142
+
143
+ return (0, _orderBy.default)(list, [i => i.name], ['asc']);
144
+ }, [categoryState.data]);
145
+
146
+ const translate = (key, data) => {
147
+ if (!_locale.default[locale] || !_locale.default[locale][key]) {
148
+ console.warn("Warning: no ".concat(key, " translation of ").concat(locale));
149
+ return key;
150
+ }
151
+
152
+ return (0, _utils.replaceTranslate)(_locale.default[locale][key], data);
153
+ };
154
+
155
+ const filterStore = {
156
+ errors: {
157
+ fetchBlockletsError,
158
+ fetchCategoriesError
159
+ },
160
+ loadings: {
161
+ fetchBlockletsLoading,
162
+ fetchCategoriesLoading
163
+ },
164
+ endpoint,
165
+ blockletList,
166
+ t: translate,
167
+ filters: _objectSpread({
168
+ sortBy: 'popularity',
169
+ sortDirection: 'desc'
170
+ }, filters),
171
+ selectedCategory,
172
+ categoryList,
173
+ baseUrl,
174
+ blockletRender,
175
+ locale,
176
+ selectedBlocklets,
177
+ onSelectBlocklet,
178
+ handleSort: sort => {
179
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
180
+ sortBy: sort,
181
+ sortDirection: sort === 'nameAsc' ? 'asc' : 'desc'
182
+ });
183
+
184
+ onFilterChange(changeData);
185
+ },
186
+ handleKeyword: keyWord => {
187
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
188
+ keyword: keyWord || undefined
189
+ });
190
+
191
+ onFilterChange(changeData);
192
+ },
193
+ handlePrice: price => {
194
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
195
+ price: price === filters.price ? undefined : price
196
+ });
197
+
198
+ onFilterChange(changeData);
199
+ },
200
+ handleCategory: category => {
201
+ if (category === 'all') {
202
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
203
+ category: undefined
204
+ });
205
+
206
+ onFilterChange(changeData);
207
+ } else {
208
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
209
+ category
210
+ });
211
+
212
+ onFilterChange(changeData);
213
+ }
214
+ },
215
+ handleDeveloper: developer => {
216
+ const changeData = _objectSpread(_objectSpread({}, filters), {}, {
217
+ developer: developer || undefined
218
+ });
219
+
220
+ onFilterChange(changeData);
221
+ },
222
+ getCategoryLocale: category => {
223
+ if (!category) return null;
224
+ let result = null;
225
+ const find = categoryState.data.find(item => item.name === category);
226
+
227
+ if (find) {
228
+ result = find.locales[locale];
229
+ }
230
+
231
+ return result;
232
+ },
233
+
234
+ get developerName() {
235
+ var _allBlocklets$find, _allBlocklets$find$ow;
236
+
237
+ return ((_allBlocklets$find = allBlocklets.find(i => i.owner.did === filters.developer)) === null || _allBlocklets$find === void 0 ? void 0 : (_allBlocklets$find$ow = _allBlocklets$find.owner) === null || _allBlocklets$find$ow === void 0 ? void 0 : _allBlocklets$find$ow.name) || '';
238
+ }
239
+
240
+ };
241
+ (0, _react.useEffect)(() => {
242
+ if (!hasDeveloperFilter) {
243
+ fetchCategories();
244
+ }
245
+ }, [hasDeveloperFilter]);
246
+ (0, _react.useEffect)(() => {
247
+ fetchBlocklets();
248
+ fetchCategories();
249
+ }, [endpoint]);
250
+ return /*#__PURE__*/_react.default.createElement(Provider, {
251
+ value: filterStore
252
+ }, children);
253
+ }
254
+
255
+ FilterProvider.propTypes = _objectSpread(_objectSpread({}, _propTypes2.propTypes), {}, {
256
+ children: _propTypes.default.any.isRequired
257
+ });
258
+ FilterProvider.defaultProps = _propTypes2.defaultProps;
259
+
260
+ function useFilterContext() {
261
+ const filterStore = (0, _react.useContext)(Filter);
262
+
263
+ if (!filterStore) {
264
+ return {};
265
+ }
266
+
267
+ return filterStore;
268
+ }
package/lib/index.js CHANGED
@@ -7,27 +7,17 @@ exports.default = BlockletList;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
10
- var _propTypes = _interopRequireDefault(require("prop-types"));
11
-
12
10
  var _base = _interopRequireDefault(require("./base"));
13
11
 
14
- var _store = require("./contexts/store");
12
+ var _filter = require("./contexts/filter");
13
+
14
+ var _propTypes = require("./libs/prop-types");
15
15
 
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
 
18
18
  function BlockletList(props) {
19
- return /*#__PURE__*/_react.default.createElement(_store.SearchProvider, props, /*#__PURE__*/_react.default.createElement(_base.default, null));
19
+ return /*#__PURE__*/_react.default.createElement(_filter.FilterProvider, props, /*#__PURE__*/_react.default.createElement(_base.default, null));
20
20
  }
21
21
 
22
- BlockletList.propTypes = {
23
- baseUrl: _propTypes.default.string,
24
- endpoint: _propTypes.default.string.isRequired,
25
- // 组件的类型: page 单独作为页面使用 持久化数据将存储在 url 和 localstorage,select 作为选择器组件使用 数据在存储在内存中
26
- type: _propTypes.default.oneOf(['select', 'page']).isRequired,
27
- locale: _propTypes.default.oneOf(['zh', 'en']),
28
- blockletRender: _propTypes.default.func.isRequired
29
- };
30
- BlockletList.defaultProps = {
31
- baseUrl: null,
32
- locale: 'zh'
33
- };
22
+ BlockletList.propTypes = _propTypes.propTypes;
23
+ BlockletList.defaultProps = _propTypes.defaultProps;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.propTypes = exports.defaultProps = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ const propTypes = {
13
+ filters: _propTypes.default.shape({
14
+ keyword: _propTypes.default.string,
15
+ sortBy: _propTypes.default.string,
16
+ sortDirection: _propTypes.default.string,
17
+ price: _propTypes.default.string,
18
+ category: _propTypes.default.string,
19
+ developer: _propTypes.default.string
20
+ }),
21
+ endpoint: _propTypes.default.string.isRequired,
22
+ blockletRender: _propTypes.default.func.isRequired,
23
+ onFilterChange: _propTypes.default.func,
24
+ baseUrl: _propTypes.default.string,
25
+ locale: _propTypes.default.oneOf(['zh', 'en'])
26
+ };
27
+ exports.propTypes = propTypes;
28
+ const defaultProps = {
29
+ baseUrl: null,
30
+ locale: 'zh',
31
+ filters: {},
32
+ onFilterChange: () => {}
33
+ };
34
+ exports.defaultProps = defaultProps;
@@ -7,7 +7,7 @@ exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = expo
7
7
 
8
8
  var _urlJoin = _interopRequireDefault(require("url-join"));
9
9
 
10
- var _cloneDeep = _interopRequireDefault(require("lodash-es/cloneDeep"));
10
+ var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
@@ -127,13 +127,13 @@ template.replace(/{(\w*)}/g, (m, key) => data.hasOwnProperty(key) ? data[key] :
127
127
  exports.replaceTranslate = replaceTranslate;
128
128
 
129
129
  const removeUndefined = obj => {
130
- const innerObj = (0, _cloneDeep.default)(obj);
131
- Object.keys(innerObj).forEach(key => {
132
- if (innerObj[key] === undefined) {
133
- delete innerObj[key];
130
+ const clone = (0, _cloneDeep.default)(obj);
131
+ Object.keys(clone).forEach(key => {
132
+ if (clone[key] === undefined) {
133
+ delete clone[key];
134
134
  }
135
135
  });
136
- return innerObj;
136
+ return clone;
137
137
  };
138
138
 
139
139
  exports.removeUndefined = removeUndefined;
package/package.json CHANGED
@@ -1,66 +1,62 @@
1
1
  {
2
- "name": "@blocklet/list",
3
- "version": "0.8.14",
4
- "description": "Common ux components of blocklet",
5
- "publishConfig": {
6
- "access": "public"
7
- },
8
- "author": "machao <machao@arcblock.io>",
9
- "homepage": "https://github.com/blocklet/blocklet-store#readme",
10
- "license": "ISC",
11
- "main": "lib/index.js",
12
- "files": [
13
- "lib",
14
- "src",
15
- "LICENSE",
16
- "package.json",
17
- "README.md"
18
- ],
19
- "repository": {
20
- "type": "git",
21
- "url": "git@github.com:blocklet/blocklet-store.git"
22
- },
23
- "scripts": {
24
- "lint": "eslint src",
25
- "build": "rm -rf lib && babel src --out-dir lib --copy-files",
26
- "watch": "babel src --out-dir lib -w --copy-files",
27
- "precommit": "CI=1 yarn test",
28
- "prepush": "CI=1 yarn test",
29
- "prepublish": "npm run build"
30
- },
31
- "bugs": {
32
- "url": "https://github.com/blocklet/blocklet-store/issues"
33
- },
34
- "peerDependencies": {
35
- "react": ">=16.12.0"
36
- },
37
- "dependencies": {
38
- "@arcblock/ux": "^2.1.3",
39
- "@emotion/react": "^11.9.0",
40
- "@emotion/styled": "^11.8.1",
41
- "@mui/icons-material": "^5.6.2",
42
- "@mui/material": "^5.7.0",
43
- "@mui/styles": "^5.7.0",
44
- "ahooks": "^2.10.12",
45
- "axios": "^0.27.2",
46
- "flat": "^5.0.2",
47
- "lodash": "^4.17.21",
48
- "lodash-es": "^4.17.21",
49
- "mdi-material-ui": "^7.3.0",
50
- "prop-types": "^15.7.2",
51
- "qs": "^6.10.2",
52
- "react-router-dom": "^5.3.0",
53
- "styled-components": "5.3.5",
54
- "url-join": "^4.0.1"
55
- },
56
- "devDependencies": {
57
- "@babel/cli": "^7.8.4",
58
- "@babel/core": "^7.8.4",
59
- "@babel/preset-env": "^7.8.4",
60
- "@babel/preset-react": "^7.8.3",
61
- "@emotion/babel-plugin": "^11.9.2",
62
- "babel-plugin-inline-react-svg": "^2.0.1",
63
- "babel-plugin-styled-components": "^1.10.7"
64
- },
65
- "gitHead": "c6475aec249f4ec909fe413d407f667d43bfcf0d"
2
+ "name": "@blocklet/list",
3
+ "version": "0.8.17",
4
+ "description": "Common ux components of blocklet",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "author": "machao <machao@arcblock.io>",
9
+ "homepage": "https://github.com/blocklet/blocklet-store#readme",
10
+ "license": "ISC",
11
+ "main": "lib/index.js",
12
+ "files": [
13
+ "lib",
14
+ "src",
15
+ "LICENSE",
16
+ "package.json",
17
+ "README.md"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git@github.com:blocklet/blocklet-store.git"
22
+ },
23
+ "scripts": {
24
+ "lint": "eslint src",
25
+ "build": "rm -rf lib && babel src --out-dir lib --copy-files",
26
+ "watch": "babel src --out-dir lib -w --copy-files",
27
+ "precommit": "CI=1 yarn test",
28
+ "prepush": "CI=1 yarn test",
29
+ "prepublish": "npm run build"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/blocklet/blocklet-store/issues"
33
+ },
34
+ "peerDependencies": {
35
+ "@mui/material": ">=5.6.4",
36
+ "@mui/styles": ">=5.6.2",
37
+ "react": ">=18.1.0"
38
+ },
39
+ "dependencies": {
40
+ "@arcblock/ux": "^2.1.4",
41
+ "@emotion/react": "^11.9.0",
42
+ "@emotion/styled": "^11.8.1",
43
+ "@mui/icons-material": "^5.6.2",
44
+ "ahooks": "^2.10.12",
45
+ "axios": "^0.27.2",
46
+ "flat": "^5.0.2",
47
+ "lodash": "^4.17.21",
48
+ "prop-types": "^15.7.2",
49
+ "styled-components": "5.3.5",
50
+ "url-join": "^4.0.1"
51
+ },
52
+ "devDependencies": {
53
+ "@babel/cli": "^7.8.4",
54
+ "@babel/core": "^7.8.4",
55
+ "@babel/preset-env": "^7.8.4",
56
+ "@babel/preset-react": "^7.8.3",
57
+ "@emotion/babel-plugin": "^11.9.2",
58
+ "babel-plugin-inline-react-svg": "^2.0.1",
59
+ "babel-plugin-styled-components": "^1.10.7"
60
+ },
61
+ "gitHead": "660a066ab7efb6b77e9a50f0f6e2a8928760409e"
66
62
  }
package/src/base.js CHANGED
@@ -1,21 +1,20 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
- import Sort from 'mdi-material-ui/Sort';
3
+ import SortIcon from '@mui/icons-material/Sort';
4
4
  import FilterListIcon from '@mui/icons-material/FilterList';
5
- import { Box, Hidden, SvgIcon } from '@mui/material';
5
+ import { Box, Hidden } from '@mui/material';
6
6
 
7
- import { useSearchContext } from './contexts/store';
7
+ import { useFilterContext } from './contexts/filter';
8
8
  import CustomSelect from './components/custom-select';
9
9
  import FilterAuthor from './components/filter-author';
10
- import { getSortOptions, getPrices } from './tools/utils';
10
+ import { getSortOptions, getPrices } from './libs/utils';
11
11
  import BlockletList from './components/list';
12
12
  import Aside from './components/aside';
13
13
  import Search from './components/search';
14
- import { CategorySelect } from './components/categories';
14
+ import CategorySelect from './components/category-select';
15
15
 
16
16
  const ListBase = () => {
17
- const searchStore = useSearchContext();
18
- const { sortParams, history, blockletList, queryParams, developerName, handleSort, t } = searchStore;
17
+ const { handleDeveloper, blockletList, filters, developerName, handleSort, t, handlePrice } = useFilterContext();
19
18
  return (
20
19
  <Box display="flex" alignItems="flex-start" height="100%">
21
20
  <Hidden mdDown>
@@ -24,11 +23,11 @@ const ListBase = () => {
24
23
  <StyledMin>
25
24
  <Box className="marketplace-header" display="flex" alignItems="center">
26
25
  <Hidden mdDown>
27
- {!!queryParams.get('developer') && (
26
+ {!!filters.developer && (
28
27
  <FilterAuthor
29
28
  user={developerName}
30
29
  deleteUserTag={() => {
31
- history.push('/');
30
+ handleDeveloper(null);
32
31
  }}
33
32
  />
34
33
  )}
@@ -43,10 +42,10 @@ const ListBase = () => {
43
42
  <CategorySelect />
44
43
  </Hidden>
45
44
  <CustomSelect
46
- value={sortParams.sort}
45
+ value={filters.sortBy}
47
46
  options={getSortOptions(t)}
48
- title={getSortOptions(t).find((f) => f.value === sortParams.sort)?.name || t('sort.sort')}
49
- icon={<SvgIcon component={Sort} />}
47
+ title={getSortOptions(t).find((f) => f.value === filters.sortBy)?.name || t('sort.sort')}
48
+ icon={<SortIcon />}
50
49
  onChange={(v) => {
51
50
  handleSort(v);
52
51
  }}
@@ -58,24 +57,24 @@ const ListBase = () => {
58
57
  display="flex"
59
58
  flexWrap="wrap"
60
59
  alignItems="center"
61
- justifyContent={queryParams.get('developer') ? 'space-between' : 'flex-end'}>
62
- {!!queryParams.get('developer') && (
60
+ justifyContent={filters.developer ? 'space-between' : 'flex-end'}>
61
+ {!!filters.developer && (
63
62
  <FilterAuthor
64
63
  user={developerName}
65
64
  deleteUserTag={() => {
66
- history.push('/');
65
+ handleDeveloper(null);
67
66
  }}
68
67
  style={{ marginBottom: '16px' }}
69
68
  />
70
69
  )}
71
70
  {/* 筛选付费/免费 */}
72
71
  <CustomSelect
73
- value={queryParams.get('price')}
72
+ value={filters.price}
74
73
  icon={<FilterListIcon />}
75
74
  options={getPrices(t)}
76
- title={getPrices(t).find((f) => f.value === queryParams.get('price'))?.name || t('common.price')}
75
+ title={getPrices(t).find((f) => f.value === filters.price)?.name || t('common.price')}
77
76
  onChange={(v) => {
78
- searchStore.handlePriceFilter(v);
77
+ handlePrice(v);
79
78
  }}
80
79
  style={{ marginBottom: '16px' }}
81
80
  />
@@ -2,14 +2,13 @@ import React from 'react';
2
2
  import { Box, List, Checkbox, FormControlLabel } from '@mui/material';
3
3
  import styled from 'styled-components';
4
4
 
5
- import { useSearchContext } from '../contexts/store';
6
- import { getPrices } from '../tools/utils';
7
- import Search from './search';
8
- import { CategoryLinkList } from './categories';
5
+ import { useFilterContext } from '../../contexts/filter';
6
+ import { getPrices } from '../../libs/utils';
7
+ import Search from '../search';
8
+ import CategoryLinkList from './category-link-list';
9
9
 
10
10
  const Aside = () => {
11
- const searchStore = useSearchContext();
12
- const { queryParams, handlePriceFilter, t } = searchStore;
11
+ const { filters, handlePrice, t } = useFilterContext();
13
12
  return (
14
13
  <StyledAside>
15
14
  <Search placeholder={t('common.searchStore')} />
@@ -21,10 +20,10 @@ const Aside = () => {
21
20
  control={
22
21
  <Checkbox
23
22
  onClick={() => {
24
- handlePriceFilter(item.value);
23
+ handlePrice(item.value);
25
24
  }}
26
25
  size="small"
27
- checked={item.value === queryParams.get('price')}
26
+ checked={item.value === filters.price}
28
27
  />
29
28
  }
30
29
  label={item.name}
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { ListItem, ListItemText, Link } from '@mui/material';
3
+ import joinUrl from 'url-join';
4
+
5
+ import { useFilterContext } from '../../contexts/filter';
6
+ import { urlStringify } from '../../libs/utils';
7
+
8
+ /**
9
+ * 宽屏幕下的分类列表
10
+ * @returns
11
+ */
12
+ const CategoryLinkList = () => {
13
+ const { categoryList, selectedCategory, filters, baseUrl, handleCategory, t, locale } = useFilterContext();
14
+
15
+ const handleClick = (e, name) => {
16
+ handleCategory(name);
17
+ e.preventDefault();
18
+ return false;
19
+ };
20
+ const content = (
21
+ <div style={{ marginRight: '16px' }}>
22
+ <ListItem selected={!selectedCategory} button onClick={(e) => handleClick(e, 'all')}>
23
+ <ListItemText primary={t('category.all')} />
24
+ </ListItem>
25
+ {categoryList.map((item) => (
26
+ <ListItem
27
+ key={item._id}
28
+ title={item.locales[locale]}
29
+ component={Link}
30
+ to={`${joinUrl(baseUrl, '/search')}?${urlStringify({
31
+ ...filters,
32
+ category: item.name,
33
+ })}`}
34
+ onClick={(e) => handleClick(e, item.name)}
35
+ button
36
+ selected={item.name === selectedCategory}>
37
+ <ListItemText primary={item.locales[locale]} />
38
+ </ListItem>
39
+ ))}
40
+ </div>
41
+ );
42
+
43
+ return (
44
+ <>
45
+ <ListItem>
46
+ <ListItemText className="category" primary={t('common.category')} />
47
+ </ListItem>
48
+ {content}
49
+ </>
50
+ );
51
+ };
52
+
53
+ export default CategoryLinkList;