@blocklet/list 0.8.10 → 0.8.13
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.
- package/lib/base.js +5 -5
- package/lib/components/aside.js +1 -1
- package/lib/components/categories.js +8 -10
- package/lib/components/list.js +9 -6
- package/lib/components/search.js +9 -3
- package/lib/contexts/store.js +33 -30
- package/lib/tools/utils.js +27 -3
- package/package.json +3 -3
- package/src/base.js +5 -5
- package/src/components/aside.js +1 -1
- package/src/components/categories.js +26 -8
- package/src/components/list.js +6 -6
- package/src/components/search.js +7 -3
- package/src/contexts/store.js +43 -27
- package/src/tools/utils.js +22 -2
package/lib/base.js
CHANGED
|
@@ -58,7 +58,7 @@ const ListBase = () => {
|
|
|
58
58
|
alignItems: "center"
|
|
59
59
|
}, /*#__PURE__*/_react.default.createElement(_material.Hidden, {
|
|
60
60
|
mdDown: true
|
|
61
|
-
}, !!queryParams.developer && /*#__PURE__*/_react.default.createElement(_filterAuthor.default, {
|
|
61
|
+
}, !!queryParams.get('developer') && /*#__PURE__*/_react.default.createElement(_filterAuthor.default, {
|
|
62
62
|
user: developerName,
|
|
63
63
|
deleteUserTag: () => {
|
|
64
64
|
history.push('/');
|
|
@@ -93,8 +93,8 @@ const ListBase = () => {
|
|
|
93
93
|
display: "flex",
|
|
94
94
|
flexWrap: "wrap",
|
|
95
95
|
alignItems: "center",
|
|
96
|
-
justifyContent: queryParams.developer ? 'space-between' : 'flex-end'
|
|
97
|
-
}, !!queryParams.developer && /*#__PURE__*/_react.default.createElement(_filterAuthor.default, {
|
|
96
|
+
justifyContent: queryParams.get('developer') ? 'space-between' : 'flex-end'
|
|
97
|
+
}, !!queryParams.get('developer') && /*#__PURE__*/_react.default.createElement(_filterAuthor.default, {
|
|
98
98
|
user: developerName,
|
|
99
99
|
deleteUserTag: () => {
|
|
100
100
|
history.push('/');
|
|
@@ -103,10 +103,10 @@ const ListBase = () => {
|
|
|
103
103
|
marginBottom: '16px'
|
|
104
104
|
}
|
|
105
105
|
}), /*#__PURE__*/_react.default.createElement(_customSelect.default, {
|
|
106
|
-
value: queryParams.price,
|
|
106
|
+
value: queryParams.get('price'),
|
|
107
107
|
icon: /*#__PURE__*/_react.default.createElement(_FilterList.default, null),
|
|
108
108
|
options: (0, _utils.getPrices)(t),
|
|
109
|
-
title: ((_getPrices$find = (0, _utils.getPrices)(t).find(f => f.value === queryParams.price)) === null || _getPrices$find === void 0 ? void 0 : _getPrices$find.name) || t('common.price'),
|
|
109
|
+
title: ((_getPrices$find = (0, _utils.getPrices)(t).find(f => f.value === queryParams.get('price'))) === null || _getPrices$find === void 0 ? void 0 : _getPrices$find.name) || t('common.price'),
|
|
110
110
|
onChange: v => {
|
|
111
111
|
searchStore.handlePriceFilter(v);
|
|
112
112
|
},
|
package/lib/components/aside.js
CHANGED
|
@@ -40,7 +40,7 @@ const Aside = () => {
|
|
|
40
40
|
handlePriceFilter(item.value);
|
|
41
41
|
},
|
|
42
42
|
size: "small",
|
|
43
|
-
checked: item.value === queryParams.price
|
|
43
|
+
checked: item.value === queryParams.get('price')
|
|
44
44
|
}),
|
|
45
45
|
label: item.name
|
|
46
46
|
}))), /*#__PURE__*/_react.default.createElement(_material.List, {
|
|
@@ -11,14 +11,14 @@ var _reactRouterDom = require("react-router-dom");
|
|
|
11
11
|
|
|
12
12
|
var _material = require("@mui/material");
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
var _qs = _interopRequireDefault(require("qs"));
|
|
14
|
+
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
17
15
|
|
|
18
16
|
var _store = require("../contexts/store");
|
|
19
17
|
|
|
20
18
|
var _customSelect = _interopRequireDefault(require("./custom-select"));
|
|
21
19
|
|
|
20
|
+
var _utils = require("../tools/utils");
|
|
21
|
+
|
|
22
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
23
|
|
|
24
24
|
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; }
|
|
@@ -72,10 +72,6 @@ const CategorySelect = () => {
|
|
|
72
72
|
exports.CategorySelect = CategorySelect;
|
|
73
73
|
|
|
74
74
|
const CategoryLinkList = () => {
|
|
75
|
-
const {
|
|
76
|
-
t,
|
|
77
|
-
locale
|
|
78
|
-
} = (0, _context.useLocaleContext)();
|
|
79
75
|
const searchStore = (0, _store.useSearchContext)();
|
|
80
76
|
const {
|
|
81
77
|
queryParams,
|
|
@@ -84,7 +80,9 @@ const CategoryLinkList = () => {
|
|
|
84
80
|
selectedCategory,
|
|
85
81
|
isPageMode,
|
|
86
82
|
handleCategorySelect,
|
|
87
|
-
baseUrl
|
|
83
|
+
baseUrl,
|
|
84
|
+
locale,
|
|
85
|
+
t
|
|
88
86
|
} = searchStore;
|
|
89
87
|
let content = null;
|
|
90
88
|
|
|
@@ -97,7 +95,7 @@ const CategoryLinkList = () => {
|
|
|
97
95
|
selected: !selectedCategory,
|
|
98
96
|
button: true,
|
|
99
97
|
component: _reactRouterDom.Link,
|
|
100
|
-
to: !isSearchPage ? baseUrl : "".concat(baseUrl, "
|
|
98
|
+
to: !isSearchPage ? baseUrl : "".concat((0, _urlJoin.default)(baseUrl, '/search'), "?").concat((0, _utils.urlStringify)(_objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
101
99
|
category: undefined
|
|
102
100
|
})))
|
|
103
101
|
}, /*#__PURE__*/_react.default.createElement(_material.ListItemText, {
|
|
@@ -108,7 +106,7 @@ const CategoryLinkList = () => {
|
|
|
108
106
|
button: true,
|
|
109
107
|
selected: item.name === selectedCategory,
|
|
110
108
|
component: _reactRouterDom.Link,
|
|
111
|
-
to: !isSearchPage ? "".concat(baseUrl,
|
|
109
|
+
to: !isSearchPage ? "".concat((0, _urlJoin.default)(baseUrl, '/category', item.name)) : "".concat((0, _urlJoin.default)(baseUrl, '/search'), "?").concat((0, _utils.urlStringify)(_objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
112
110
|
category: item.name
|
|
113
111
|
})))
|
|
114
112
|
}, /*#__PURE__*/_react.default.createElement(_material.ListItemText, {
|
package/lib/components/list.js
CHANGED
|
@@ -51,7 +51,7 @@ function BlockletList(_ref) {
|
|
|
51
51
|
queryParams,
|
|
52
52
|
t
|
|
53
53
|
} = (0, _store.useSearchContext)();
|
|
54
|
-
const showFilterTip = !!selectedCategory || !!queryParams.price;
|
|
54
|
+
const showFilterTip = !!selectedCategory || !!queryParams.get('price');
|
|
55
55
|
|
|
56
56
|
if (errors.fetchBlockletsError) {
|
|
57
57
|
return /*#__PURE__*/_react.default.createElement(_Alert.default, {
|
|
@@ -68,22 +68,22 @@ function BlockletList(_ref) {
|
|
|
68
68
|
}, /*#__PURE__*/_react.default.createElement(_CircularProgress.default, null));
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
if (queryParams.search && showFilterTip && blockletList.length === 0) {
|
|
71
|
+
if (queryParams.get('search') && showFilterTip && blockletList.length === 0) {
|
|
72
72
|
return /*#__PURE__*/_react.default.createElement(CustomEmpty, null, /*#__PURE__*/_react.default.createElement(_empty.EmptyTitle, {
|
|
73
73
|
primaryStart: t('blocklet.noBlockletPart1'),
|
|
74
74
|
primaryEnd: t('blocklet.noBlockletPart2'),
|
|
75
|
-
search: queryParams.search
|
|
75
|
+
search: queryParams.get('search')
|
|
76
76
|
}), /*#__PURE__*/_react.default.createElement(_empty.NoResultsTips, {
|
|
77
77
|
keywordTip: true,
|
|
78
78
|
filterTip: true
|
|
79
79
|
}));
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
if (queryParams.search && blockletList.length === 0) {
|
|
82
|
+
if (queryParams.get('search') && blockletList.length === 0) {
|
|
83
83
|
return /*#__PURE__*/_react.default.createElement(CustomEmpty, null, /*#__PURE__*/_react.default.createElement(_empty.EmptyTitle, {
|
|
84
84
|
primaryStart: t('blocklet.noBlockletPart1'),
|
|
85
85
|
primaryEnd: t('blocklet.noBlockletPart2'),
|
|
86
|
-
search: queryParams.search
|
|
86
|
+
search: queryParams.get('search')
|
|
87
87
|
}), /*#__PURE__*/_react.default.createElement(_empty.NoResultsTips, {
|
|
88
88
|
keywordTip: true
|
|
89
89
|
}));
|
|
@@ -115,7 +115,10 @@ function BlockletList(_ref) {
|
|
|
115
115
|
xs: 12,
|
|
116
116
|
key: blocklet.did,
|
|
117
117
|
"data-blocklet-did": blocklet.did
|
|
118
|
-
}, blockletRender(
|
|
118
|
+
}, blockletRender({
|
|
119
|
+
blocklet,
|
|
120
|
+
blocklets: blockletList
|
|
121
|
+
}))));
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
BlockletList.propTypes = {
|
package/lib/components/search.js
CHANGED
|
@@ -42,7 +42,7 @@ const Search = _ref => {
|
|
|
42
42
|
queryParams,
|
|
43
43
|
handleSearchKeyword
|
|
44
44
|
} = searchStore;
|
|
45
|
-
const [searchStr, setSearchStr] = (0, _react.useState)(queryParams.search || '');
|
|
45
|
+
const [searchStr, setSearchStr] = (0, _react.useState)(queryParams.get('search') || '');
|
|
46
46
|
const {
|
|
47
47
|
run: handleSearch
|
|
48
48
|
} = (0, _ahooks.useDebounceFn)(handleSearchKeyword, {
|
|
@@ -63,6 +63,9 @@ const Search = _ref => {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
return /*#__PURE__*/_react.default.createElement(StyledSearch, Object.assign({
|
|
66
|
+
inputProps: {
|
|
67
|
+
'data-cy': 'search-blocklet'
|
|
68
|
+
},
|
|
66
69
|
startAdornment: /*#__PURE__*/_react.default.createElement(_material.InputAdornment, {
|
|
67
70
|
position: "start"
|
|
68
71
|
}, /*#__PURE__*/_react.default.createElement(StyledMagnify, null)),
|
|
@@ -70,10 +73,13 @@ const Search = _ref => {
|
|
|
70
73
|
placeholder: placeholder,
|
|
71
74
|
value: searchStr,
|
|
72
75
|
title: placeholder,
|
|
76
|
+
"data-cy": "search",
|
|
73
77
|
endAdornment: searchStr && /*#__PURE__*/_react.default.createElement(_material.InputAdornment, {
|
|
74
|
-
onClick: handleClose,
|
|
75
78
|
position: "end"
|
|
76
|
-
}, /*#__PURE__*/_react.default.createElement(StyledClose,
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement(StyledClose, {
|
|
80
|
+
"data-cy": "search-delete",
|
|
81
|
+
onClick: handleClose
|
|
82
|
+
}))
|
|
77
83
|
}, rest));
|
|
78
84
|
};
|
|
79
85
|
|
package/lib/contexts/store.js
CHANGED
|
@@ -11,8 +11,6 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
11
11
|
|
|
12
12
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
13
13
|
|
|
14
|
-
var _qs = _interopRequireDefault(require("qs"));
|
|
15
|
-
|
|
16
14
|
var _reactRouterDom = require("react-router-dom");
|
|
17
15
|
|
|
18
16
|
var _ahooks = require("ahooks");
|
|
@@ -59,7 +57,9 @@ function SearchProvider(_ref) {
|
|
|
59
57
|
locale,
|
|
60
58
|
blockletRender
|
|
61
59
|
} = _ref;
|
|
62
|
-
const
|
|
60
|
+
const {
|
|
61
|
+
location
|
|
62
|
+
} = window;
|
|
63
63
|
const history = (0, _reactRouterDom.useHistory)();
|
|
64
64
|
const pathParams = (0, _reactRouterDom.useParams)();
|
|
65
65
|
const isPageMode = type === 'page';
|
|
@@ -71,14 +71,16 @@ function SearchProvider(_ref) {
|
|
|
71
71
|
const {
|
|
72
72
|
data: allBlocklets,
|
|
73
73
|
error: fetchBlockletsError,
|
|
74
|
-
loading: fetchBlockletsLoading
|
|
74
|
+
loading: fetchBlockletsLoading,
|
|
75
|
+
run: fetchBlocklets
|
|
75
76
|
} = (0, _ahooks.useRequest)(async () => {
|
|
76
77
|
const {
|
|
77
78
|
data: list
|
|
78
79
|
} = await axiosInstance.get((0, _urlJoin.default)(endpoint, '/api/blocklets.json'));
|
|
79
80
|
return list;
|
|
80
81
|
}, {
|
|
81
|
-
initialData: []
|
|
82
|
+
initialData: [],
|
|
83
|
+
manual: true
|
|
82
84
|
});
|
|
83
85
|
const {
|
|
84
86
|
data: allCategories,
|
|
@@ -99,9 +101,7 @@ function SearchProvider(_ref) {
|
|
|
99
101
|
sortDirection: 'desc'
|
|
100
102
|
});
|
|
101
103
|
const queryParams = (0, _react.useMemo)(() => {
|
|
102
|
-
return isPageMode ?
|
|
103
|
-
ignoreQueryPrefix: true
|
|
104
|
-
}) : memoryParams;
|
|
104
|
+
return isPageMode ? new URLSearchParams(location.search) : new Map(Object.entries(memoryParams));
|
|
105
105
|
}, [memoryParams, location.search]);
|
|
106
106
|
let sortParams; // 当作页面使用时 sort 数据比较特殊, 默认取 localStorge 中的值,如果 url query 中有sort值则优先使用
|
|
107
107
|
|
|
@@ -111,8 +111,8 @@ function SearchProvider(_ref) {
|
|
|
111
111
|
direction: 'desc'
|
|
112
112
|
}, baseUrl);
|
|
113
113
|
const urlSortParams = {
|
|
114
|
-
sort: queryParams.sortBy,
|
|
115
|
-
direction: queryParams.sortDirection
|
|
114
|
+
sort: queryParams.get('sortBy'),
|
|
115
|
+
direction: queryParams.get('sortDirection')
|
|
116
116
|
};
|
|
117
117
|
sortParams = urlSortParams.sort && urlSortParams.direction ? urlSortParams : localSortParams;
|
|
118
118
|
} else {
|
|
@@ -124,22 +124,22 @@ function SearchProvider(_ref) {
|
|
|
124
124
|
}, [memoryParams]);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
const isSearchPage = location.pathname === '/search';
|
|
127
|
+
const isSearchPage = location.pathname === (0, _urlJoin.default)(baseUrl, '/search');
|
|
128
128
|
const selectedCategory = (0, _react.useMemo)(() => {
|
|
129
129
|
let result = null;
|
|
130
130
|
|
|
131
131
|
if (isPageMode) {
|
|
132
|
-
result = !isSearchPage ? pathParams.category : queryParams.category;
|
|
132
|
+
result = !isSearchPage ? pathParams.category : queryParams.get('category');
|
|
133
133
|
} else {
|
|
134
|
-
result = queryParams.category;
|
|
134
|
+
result = queryParams.get('category');
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
return result;
|
|
138
138
|
}, [isPageMode, pathParams, queryParams]);
|
|
139
|
-
const hasDeveloperFilter = !!queryParams.developer;
|
|
139
|
+
const hasDeveloperFilter = !!queryParams.get('developer');
|
|
140
140
|
const categoryState = !hasDeveloperFilter ? {
|
|
141
141
|
data: allCategories
|
|
142
|
-
} : (0, _utils.getCategories)(allBlocklets, queryParams.developer);
|
|
142
|
+
} : (0, _utils.getCategories)(allBlocklets, queryParams.get('developer'));
|
|
143
143
|
const blockletList = (0, _react.useMemo)(() => {
|
|
144
144
|
var _queryParams$search;
|
|
145
145
|
|
|
@@ -164,7 +164,7 @@ function SearchProvider(_ref) {
|
|
|
164
164
|
};
|
|
165
165
|
let result = allBlocklets || []; // 按照付费/免费筛选
|
|
166
166
|
|
|
167
|
-
result = (0, _utils.filterBlockletByPrice)(result, queryParams.price); // 按照分类筛选
|
|
167
|
+
result = (0, _utils.filterBlockletByPrice)(result, queryParams.get('price')); // 按照分类筛选
|
|
168
168
|
|
|
169
169
|
result = result.filter(item => {
|
|
170
170
|
var _item$category;
|
|
@@ -172,7 +172,7 @@ function SearchProvider(_ref) {
|
|
|
172
172
|
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;
|
|
173
173
|
}); // 按照作者筛选
|
|
174
174
|
|
|
175
|
-
result = result.filter(item => queryParams !== null && queryParams !== void 0 && queryParams.developer ? item.owner.did === queryParams.developer : true);
|
|
175
|
+
result = result.filter(item => queryParams !== null && queryParams !== void 0 && queryParams.developer ? item.owner.did === queryParams.get('developer') : true);
|
|
176
176
|
const lowerSearch = (queryParams === null || queryParams === void 0 ? void 0 : (_queryParams$search = queryParams.search) === null || _queryParams$search === void 0 ? void 0 : _queryParams$search.toLocaleLowerCase()) || ''; // 按照搜索筛选
|
|
177
177
|
|
|
178
178
|
result = result.filter(item => {
|
|
@@ -195,7 +195,7 @@ function SearchProvider(_ref) {
|
|
|
195
195
|
return key;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
return (0, _utils.
|
|
198
|
+
return (0, _utils.replaceTranslate)(_locale.default[locale][key], data);
|
|
199
199
|
};
|
|
200
200
|
|
|
201
201
|
const searchStore = {
|
|
@@ -221,7 +221,7 @@ function SearchProvider(_ref) {
|
|
|
221
221
|
blockletRender,
|
|
222
222
|
locale,
|
|
223
223
|
handleSort: value => {
|
|
224
|
-
const changData = _objectSpread(_objectSpread({}, queryParams), {}, {
|
|
224
|
+
const changData = _objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
225
225
|
sortBy: value,
|
|
226
226
|
sortDirection: value === 'nameAsc' ? 'asc' : 'desc'
|
|
227
227
|
});
|
|
@@ -229,29 +229,29 @@ function SearchProvider(_ref) {
|
|
|
229
229
|
if (isPageMode) {
|
|
230
230
|
sortParams.sort = changData.sortBy;
|
|
231
231
|
sortParams.direction = changData.sortDirection;
|
|
232
|
-
history.push("".concat(baseUrl, "
|
|
232
|
+
history.push("".concat((0, _urlJoin.default)(baseUrl, 'search'), "?").concat((0, _utils.urlStringify)(changData)));
|
|
233
233
|
} else {
|
|
234
234
|
setMemoryParams(changData);
|
|
235
235
|
}
|
|
236
236
|
},
|
|
237
237
|
handleSearchKeyword: value => {
|
|
238
|
-
const changData = _objectSpread(_objectSpread({}, queryParams), {}, {
|
|
238
|
+
const changData = _objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
239
239
|
search: value || undefined
|
|
240
240
|
});
|
|
241
241
|
|
|
242
242
|
if (isPageMode) {
|
|
243
|
-
history.push("".concat(baseUrl, "
|
|
243
|
+
history.push("".concat((0, _urlJoin.default)(baseUrl, 'search'), "?").concat((0, _utils.urlStringify)(changData)));
|
|
244
244
|
} else {
|
|
245
245
|
setMemoryParams(changData);
|
|
246
246
|
}
|
|
247
247
|
},
|
|
248
248
|
handlePriceFilter: value => {
|
|
249
|
-
const changData = _objectSpread(_objectSpread({}, queryParams), {}, {
|
|
250
|
-
price: value === queryParams.price ? undefined : value
|
|
249
|
+
const changData = _objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
250
|
+
price: value === queryParams.get('price') ? undefined : value
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
if (isPageMode) {
|
|
254
|
-
history.push("".concat(baseUrl, "
|
|
254
|
+
history.push("".concat((0, _urlJoin.default)(baseUrl, 'search'), "?").concat((0, _utils.urlStringify)(changData)));
|
|
255
255
|
} else {
|
|
256
256
|
setMemoryParams(changData);
|
|
257
257
|
}
|
|
@@ -269,22 +269,22 @@ function SearchProvider(_ref) {
|
|
|
269
269
|
},
|
|
270
270
|
handleCategorySelect: value => {
|
|
271
271
|
if (value === 'all') {
|
|
272
|
-
const changData = _objectSpread(_objectSpread({}, queryParams), {}, {
|
|
272
|
+
const changData = _objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
273
273
|
category: undefined
|
|
274
274
|
});
|
|
275
275
|
|
|
276
276
|
if (isPageMode) {
|
|
277
|
-
history.push(!isSearchPage ? baseUrl : "".concat(baseUrl, "
|
|
277
|
+
history.push(!isSearchPage ? baseUrl : "".concat((0, _urlJoin.default)(baseUrl, 'search'), "?").concat((0, _utils.urlStringify)(changData)));
|
|
278
278
|
} else {
|
|
279
279
|
setMemoryParams(changData);
|
|
280
280
|
}
|
|
281
281
|
} else {
|
|
282
|
-
const changData = _objectSpread(_objectSpread({}, queryParams), {}, {
|
|
282
|
+
const changData = _objectSpread(_objectSpread({}, Object.fromEntries(queryParams.entries())), {}, {
|
|
283
283
|
category: value
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
if (isPageMode) {
|
|
287
|
-
history.push(!isSearchPage ? "".concat(baseUrl,
|
|
287
|
+
history.push(!isSearchPage ? "".concat((0, _urlJoin.default)(baseUrl, 'category', value)) : "".concat((0, _urlJoin.default)(baseUrl, 'search'), "?").concat((0, _utils.urlStringify)(changData)));
|
|
288
288
|
} else {
|
|
289
289
|
setMemoryParams(changData);
|
|
290
290
|
}
|
|
@@ -294,7 +294,7 @@ function SearchProvider(_ref) {
|
|
|
294
294
|
get developerName() {
|
|
295
295
|
var _allBlocklets$find, _allBlocklets$find$ow;
|
|
296
296
|
|
|
297
|
-
return ((_allBlocklets$find = allBlocklets.find(i => i.owner.did === queryParams.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) || '';
|
|
297
|
+
return ((_allBlocklets$find = allBlocklets.find(i => i.owner.did === queryParams.get('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) || '';
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
};
|
|
@@ -303,6 +303,9 @@ function SearchProvider(_ref) {
|
|
|
303
303
|
fetchCategories();
|
|
304
304
|
}
|
|
305
305
|
}, [!hasDeveloperFilter]);
|
|
306
|
+
(0, _react.useEffect)(() => {
|
|
307
|
+
fetchBlocklets();
|
|
308
|
+
}, [endpoint]);
|
|
306
309
|
return /*#__PURE__*/_react.default.createElement(Provider, {
|
|
307
310
|
value: searchStore
|
|
308
311
|
}, children);
|
package/lib/tools/utils.js
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = exports.getStoreDetail = exports.getSortOptions = exports.getPrices = exports.getCategories = exports.formatLogoPath = exports.formatError = exports.filterBlockletByPrice = void 0;
|
|
7
7
|
|
|
8
8
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
9
9
|
|
|
10
|
+
var _cloneDeep = _interopRequireDefault(require("lodash-es/cloneDeep"));
|
|
11
|
+
|
|
10
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
13
|
|
|
12
14
|
const isFreeBlocklet = meta => {
|
|
@@ -119,7 +121,29 @@ const formatLogoPath = function formatLogoPath(did, asset) {
|
|
|
119
121
|
|
|
120
122
|
exports.formatLogoPath = formatLogoPath;
|
|
121
123
|
|
|
122
|
-
const
|
|
124
|
+
const replaceTranslate = (template, data) => // eslint-disable-next-line no-prototype-builtins
|
|
123
125
|
template.replace(/{(\w*)}/g, (m, key) => data.hasOwnProperty(key) ? data[key] : '');
|
|
124
126
|
|
|
125
|
-
exports.
|
|
127
|
+
exports.replaceTranslate = replaceTranslate;
|
|
128
|
+
|
|
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];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
return innerObj;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
exports.removeUndefined = removeUndefined;
|
|
140
|
+
|
|
141
|
+
const urlStringify = obj => {
|
|
142
|
+
if (!obj) {
|
|
143
|
+
throw new Error('obj is required in urlStringify ');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return new URLSearchParams(removeUndefined(obj)).toString();
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
exports.urlStringify = urlStringify;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/list",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.13",
|
|
4
4
|
"description": "Common ux components of blocklet",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react": ">=16.12.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@arcblock/ux": "^2.1.
|
|
38
|
+
"@arcblock/ux": "^2.1.3",
|
|
39
39
|
"@emotion/react": "^11.9.0",
|
|
40
40
|
"@emotion/styled": "^11.8.1",
|
|
41
41
|
"@mui/icons-material": "^5.6.2",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"babel-plugin-inline-react-svg": "^2.0.1",
|
|
63
63
|
"babel-plugin-styled-components": "^1.10.7"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "966ec885a8c7a68eb84be25bd138be696f3b09f4"
|
|
66
66
|
}
|
package/src/base.js
CHANGED
|
@@ -24,7 +24,7 @@ const ListBase = () => {
|
|
|
24
24
|
<StyledMin>
|
|
25
25
|
<Box className="marketplace-header" display="flex" alignItems="center">
|
|
26
26
|
<Hidden mdDown>
|
|
27
|
-
{!!queryParams.developer && (
|
|
27
|
+
{!!queryParams.get('developer') && (
|
|
28
28
|
<FilterAuthor
|
|
29
29
|
user={developerName}
|
|
30
30
|
deleteUserTag={() => {
|
|
@@ -58,8 +58,8 @@ const ListBase = () => {
|
|
|
58
58
|
display="flex"
|
|
59
59
|
flexWrap="wrap"
|
|
60
60
|
alignItems="center"
|
|
61
|
-
justifyContent={queryParams.developer ? 'space-between' : 'flex-end'}>
|
|
62
|
-
{!!queryParams.developer && (
|
|
61
|
+
justifyContent={queryParams.get('developer') ? 'space-between' : 'flex-end'}>
|
|
62
|
+
{!!queryParams.get('developer') && (
|
|
63
63
|
<FilterAuthor
|
|
64
64
|
user={developerName}
|
|
65
65
|
deleteUserTag={() => {
|
|
@@ -70,10 +70,10 @@ const ListBase = () => {
|
|
|
70
70
|
)}
|
|
71
71
|
{/* 筛选付费/免费 */}
|
|
72
72
|
<CustomSelect
|
|
73
|
-
value={queryParams.price}
|
|
73
|
+
value={queryParams.get('price')}
|
|
74
74
|
icon={<FilterListIcon />}
|
|
75
75
|
options={getPrices(t)}
|
|
76
|
-
title={getPrices(t).find((f) => f.value === queryParams.price)?.name || t('common.price')}
|
|
76
|
+
title={getPrices(t).find((f) => f.value === queryParams.get('price'))?.name || t('common.price')}
|
|
77
77
|
onChange={(v) => {
|
|
78
78
|
searchStore.handlePriceFilter(v);
|
|
79
79
|
}}
|
package/src/components/aside.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import { MenuItem, ListItem, ListItemText } from '@mui/material';
|
|
4
|
-
import
|
|
5
|
-
import qs from 'qs';
|
|
4
|
+
import joinUrl from 'url-join';
|
|
6
5
|
|
|
7
6
|
import { useSearchContext } from '../contexts/store';
|
|
8
7
|
import CustomSelect from './custom-select';
|
|
8
|
+
import { urlStringify } from '../tools/utils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* 小屏幕下的分类选择器
|
|
@@ -47,10 +47,18 @@ const CategorySelect = () => {
|
|
|
47
47
|
* @returns
|
|
48
48
|
*/
|
|
49
49
|
const CategoryLinkList = () => {
|
|
50
|
-
const { t, locale } = useLocaleContext();
|
|
51
50
|
const searchStore = useSearchContext();
|
|
52
|
-
const {
|
|
53
|
-
|
|
51
|
+
const {
|
|
52
|
+
queryParams,
|
|
53
|
+
categoryList,
|
|
54
|
+
isSearchPage,
|
|
55
|
+
selectedCategory,
|
|
56
|
+
isPageMode,
|
|
57
|
+
handleCategorySelect,
|
|
58
|
+
baseUrl,
|
|
59
|
+
locale,
|
|
60
|
+
t,
|
|
61
|
+
} = searchStore;
|
|
54
62
|
|
|
55
63
|
let content = null;
|
|
56
64
|
if (isPageMode) {
|
|
@@ -60,7 +68,14 @@ const CategoryLinkList = () => {
|
|
|
60
68
|
selected={!selectedCategory}
|
|
61
69
|
button
|
|
62
70
|
component={Link}
|
|
63
|
-
to={
|
|
71
|
+
to={
|
|
72
|
+
!isSearchPage
|
|
73
|
+
? baseUrl
|
|
74
|
+
: `${joinUrl(baseUrl, '/search')}?${urlStringify({
|
|
75
|
+
...Object.fromEntries(queryParams.entries()),
|
|
76
|
+
category: undefined,
|
|
77
|
+
})}`
|
|
78
|
+
}>
|
|
64
79
|
<ListItemText primary={t('category.all')} />
|
|
65
80
|
</ListItem>
|
|
66
81
|
{categoryList.map((item) => (
|
|
@@ -72,8 +87,11 @@ const CategoryLinkList = () => {
|
|
|
72
87
|
component={Link}
|
|
73
88
|
to={
|
|
74
89
|
!isSearchPage
|
|
75
|
-
? `${baseUrl
|
|
76
|
-
: `${baseUrl}
|
|
90
|
+
? `${joinUrl(baseUrl, '/category', item.name)}`
|
|
91
|
+
: `${joinUrl(baseUrl, '/search')}?${urlStringify({
|
|
92
|
+
...Object.fromEntries(queryParams.entries()),
|
|
93
|
+
category: item.name,
|
|
94
|
+
})}`
|
|
77
95
|
}>
|
|
78
96
|
<ListItemText primary={item.locales[locale]} />
|
|
79
97
|
</ListItem>
|
package/src/components/list.js
CHANGED
|
@@ -15,7 +15,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
15
15
|
const { blockletRender, errors, loadings, selectedCategory, blockletList, getCategoryLocale, queryParams, t } =
|
|
16
16
|
useSearchContext();
|
|
17
17
|
|
|
18
|
-
const showFilterTip = !!selectedCategory || !!queryParams.price;
|
|
18
|
+
const showFilterTip = !!selectedCategory || !!queryParams.get('price');
|
|
19
19
|
|
|
20
20
|
if (errors.fetchBlockletsError) {
|
|
21
21
|
return (
|
|
@@ -31,25 +31,25 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
31
31
|
</Box>
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
|
-
if (queryParams.search && showFilterTip && blockletList.length === 0) {
|
|
34
|
+
if (queryParams.get('search') && showFilterTip && blockletList.length === 0) {
|
|
35
35
|
return (
|
|
36
36
|
<CustomEmpty>
|
|
37
37
|
<EmptyTitle
|
|
38
38
|
primaryStart={t('blocklet.noBlockletPart1')}
|
|
39
39
|
primaryEnd={t('blocklet.noBlockletPart2')}
|
|
40
|
-
search={queryParams.search}
|
|
40
|
+
search={queryParams.get('search')}
|
|
41
41
|
/>
|
|
42
42
|
<NoResultsTips keywordTip filterTip />
|
|
43
43
|
</CustomEmpty>
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
|
-
if (queryParams.search && blockletList.length === 0) {
|
|
46
|
+
if (queryParams.get('search') && blockletList.length === 0) {
|
|
47
47
|
return (
|
|
48
48
|
<CustomEmpty>
|
|
49
49
|
<EmptyTitle
|
|
50
50
|
primaryStart={t('blocklet.noBlockletPart1')}
|
|
51
51
|
primaryEnd={t('blocklet.noBlockletPart2')}
|
|
52
|
-
search={queryParams.search}
|
|
52
|
+
search={queryParams.get('search')}
|
|
53
53
|
/>
|
|
54
54
|
<NoResultsTips keywordTip />
|
|
55
55
|
</CustomEmpty>
|
|
@@ -84,7 +84,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
84
84
|
<Grid container spacing={4} {...rest}>
|
|
85
85
|
{blocklets.map((blocklet) => (
|
|
86
86
|
<StyledGrid item lg={4} md={6} sm={6} xs={12} key={blocklet.did} data-blocklet-did={blocklet.did}>
|
|
87
|
-
{blockletRender(blocklet)}
|
|
87
|
+
{blockletRender({ blocklet, blocklets: blockletList })}
|
|
88
88
|
</StyledGrid>
|
|
89
89
|
))}
|
|
90
90
|
</Grid>
|
package/src/components/search.js
CHANGED
|
@@ -10,7 +10,7 @@ import { useSearchContext } from '../contexts/store';
|
|
|
10
10
|
const Search = ({ placeholder, ...rest }) => {
|
|
11
11
|
const searchStore = useSearchContext();
|
|
12
12
|
const { queryParams, handleSearchKeyword } = searchStore;
|
|
13
|
-
const [searchStr, setSearchStr] = useState(queryParams.search || '');
|
|
13
|
+
const [searchStr, setSearchStr] = useState(queryParams.get('search') || '');
|
|
14
14
|
|
|
15
15
|
const { run: handleSearch } = useDebounceFn(handleSearchKeyword, { wait: 300 });
|
|
16
16
|
const handleChange = (event) => {
|
|
@@ -24,6 +24,9 @@ const Search = ({ placeholder, ...rest }) => {
|
|
|
24
24
|
};
|
|
25
25
|
return (
|
|
26
26
|
<StyledSearch
|
|
27
|
+
inputProps={{
|
|
28
|
+
'data-cy': 'search-blocklet',
|
|
29
|
+
}}
|
|
27
30
|
startAdornment={
|
|
28
31
|
<InputAdornment position="start">
|
|
29
32
|
<StyledMagnify />
|
|
@@ -33,10 +36,11 @@ const Search = ({ placeholder, ...rest }) => {
|
|
|
33
36
|
placeholder={placeholder}
|
|
34
37
|
value={searchStr}
|
|
35
38
|
title={placeholder}
|
|
39
|
+
data-cy="search"
|
|
36
40
|
endAdornment={
|
|
37
41
|
searchStr && (
|
|
38
|
-
<InputAdornment
|
|
39
|
-
<StyledClose />
|
|
42
|
+
<InputAdornment position="end">
|
|
43
|
+
<StyledClose data-cy="search-delete" onClick={handleClose} />
|
|
40
44
|
</InputAdornment>
|
|
41
45
|
)
|
|
42
46
|
}
|
package/src/contexts/store.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import React, { useContext, createContext, useMemo, useEffect, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import
|
|
4
|
-
import { useParams, useLocation, useHistory } from 'react-router-dom';
|
|
3
|
+
import { useParams, useHistory } from 'react-router-dom';
|
|
5
4
|
import { useRequest } from 'ahooks';
|
|
6
5
|
import orderBy from 'lodash-es/orderBy';
|
|
7
6
|
import axios from 'axios';
|
|
8
7
|
import joinUrl from 'url-join';
|
|
9
8
|
|
|
10
9
|
import usePageState from '../hooks/page-state';
|
|
11
|
-
import { getCategories, filterBlockletByPrice,
|
|
10
|
+
import { getCategories, filterBlockletByPrice, replaceTranslate, urlStringify } from '../tools/utils';
|
|
12
11
|
import translations from '../assets/locale';
|
|
13
12
|
|
|
14
13
|
const axiosInstance = axios.create();
|
|
@@ -16,7 +15,7 @@ const Search = createContext({});
|
|
|
16
15
|
const { Provider, Consumer } = Search;
|
|
17
16
|
|
|
18
17
|
function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRender }) {
|
|
19
|
-
const location =
|
|
18
|
+
const { location } = window;
|
|
20
19
|
const history = useHistory();
|
|
21
20
|
const pathParams = useParams();
|
|
22
21
|
const isPageMode = type === 'page';
|
|
@@ -27,12 +26,13 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
27
26
|
data: allBlocklets,
|
|
28
27
|
error: fetchBlockletsError,
|
|
29
28
|
loading: fetchBlockletsLoading,
|
|
29
|
+
run: fetchBlocklets,
|
|
30
30
|
} = useRequest(
|
|
31
31
|
async () => {
|
|
32
32
|
const { data: list } = await axiosInstance.get(joinUrl(endpoint, '/api/blocklets.json'));
|
|
33
33
|
return list;
|
|
34
34
|
},
|
|
35
|
-
{ initialData: [] }
|
|
35
|
+
{ initialData: [], manual: true }
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
const {
|
|
@@ -54,7 +54,7 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
const queryParams = useMemo(() => {
|
|
57
|
-
return isPageMode ?
|
|
57
|
+
return isPageMode ? new URLSearchParams(location.search) : new Map(Object.entries(memoryParams));
|
|
58
58
|
}, [memoryParams, location.search]);
|
|
59
59
|
|
|
60
60
|
let sortParams;
|
|
@@ -68,8 +68,8 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
68
68
|
baseUrl
|
|
69
69
|
);
|
|
70
70
|
const urlSortParams = {
|
|
71
|
-
sort: queryParams.sortBy,
|
|
72
|
-
direction: queryParams.sortDirection,
|
|
71
|
+
sort: queryParams.get('sortBy'),
|
|
72
|
+
direction: queryParams.get('sortDirection'),
|
|
73
73
|
};
|
|
74
74
|
sortParams = urlSortParams.sort && urlSortParams.direction ? urlSortParams : localSortParams;
|
|
75
75
|
} else {
|
|
@@ -81,21 +81,21 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
81
81
|
}, [memoryParams]);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
const isSearchPage = location.pathname === '/search';
|
|
84
|
+
const isSearchPage = location.pathname === joinUrl(baseUrl, '/search');
|
|
85
85
|
const selectedCategory = useMemo(() => {
|
|
86
86
|
let result = null;
|
|
87
87
|
if (isPageMode) {
|
|
88
|
-
result = !isSearchPage ? pathParams.category : queryParams.category;
|
|
88
|
+
result = !isSearchPage ? pathParams.category : queryParams.get('category');
|
|
89
89
|
} else {
|
|
90
|
-
result = queryParams.category;
|
|
90
|
+
result = queryParams.get('category');
|
|
91
91
|
}
|
|
92
92
|
return result;
|
|
93
93
|
}, [isPageMode, pathParams, queryParams]);
|
|
94
94
|
|
|
95
|
-
const hasDeveloperFilter = !!queryParams.developer;
|
|
95
|
+
const hasDeveloperFilter = !!queryParams.get('developer');
|
|
96
96
|
const categoryState = !hasDeveloperFilter
|
|
97
97
|
? { data: allCategories }
|
|
98
|
-
: getCategories(allBlocklets, queryParams.developer);
|
|
98
|
+
: getCategories(allBlocklets, queryParams.get('developer'));
|
|
99
99
|
|
|
100
100
|
const blockletList = useMemo(() => {
|
|
101
101
|
const sortByName = (x) => x?.title?.toLocaleLowerCase() || x?.name?.toLocaleLowerCase(); // 按名称排序
|
|
@@ -110,11 +110,11 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
110
110
|
|
|
111
111
|
let result = allBlocklets || [];
|
|
112
112
|
// 按照付费/免费筛选
|
|
113
|
-
result = filterBlockletByPrice(result, queryParams.price);
|
|
113
|
+
result = filterBlockletByPrice(result, queryParams.get('price'));
|
|
114
114
|
// 按照分类筛选
|
|
115
115
|
result = result.filter((item) => (selectedCategory ? item?.category?.name === selectedCategory : true));
|
|
116
116
|
// 按照作者筛选
|
|
117
|
-
result = result.filter((item) => (queryParams?.developer ? item.owner.did === queryParams.developer : true));
|
|
117
|
+
result = result.filter((item) => (queryParams?.developer ? item.owner.did === queryParams.get('developer') : true));
|
|
118
118
|
const lowerSearch = queryParams?.search?.toLocaleLowerCase() || '';
|
|
119
119
|
// 按照搜索筛选
|
|
120
120
|
result = result.filter((item) => {
|
|
@@ -140,7 +140,7 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
140
140
|
return key;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
return
|
|
143
|
+
return replaceTranslate(translations[locale][key], data);
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
const searchStore = {
|
|
@@ -160,27 +160,34 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
160
160
|
blockletRender,
|
|
161
161
|
locale,
|
|
162
162
|
handleSort: (value) => {
|
|
163
|
-
const changData = {
|
|
163
|
+
const changData = {
|
|
164
|
+
...Object.fromEntries(queryParams.entries()),
|
|
165
|
+
sortBy: value,
|
|
166
|
+
sortDirection: value === 'nameAsc' ? 'asc' : 'desc',
|
|
167
|
+
};
|
|
164
168
|
if (isPageMode) {
|
|
165
169
|
sortParams.sort = changData.sortBy;
|
|
166
170
|
sortParams.direction = changData.sortDirection;
|
|
167
|
-
history.push(`${baseUrl}
|
|
171
|
+
history.push(`${joinUrl(baseUrl, 'search')}?${urlStringify(changData)}`);
|
|
168
172
|
} else {
|
|
169
173
|
setMemoryParams(changData);
|
|
170
174
|
}
|
|
171
175
|
},
|
|
172
176
|
handleSearchKeyword: (value) => {
|
|
173
|
-
const changData = { ...queryParams, search: value || undefined };
|
|
177
|
+
const changData = { ...Object.fromEntries(queryParams.entries()), search: value || undefined };
|
|
174
178
|
if (isPageMode) {
|
|
175
|
-
history.push(`${baseUrl}
|
|
179
|
+
history.push(`${joinUrl(baseUrl, 'search')}?${urlStringify(changData)}`);
|
|
176
180
|
} else {
|
|
177
181
|
setMemoryParams(changData);
|
|
178
182
|
}
|
|
179
183
|
},
|
|
180
184
|
handlePriceFilter: (value) => {
|
|
181
|
-
const changData = {
|
|
185
|
+
const changData = {
|
|
186
|
+
...Object.fromEntries(queryParams.entries()),
|
|
187
|
+
price: value === queryParams.get('price') ? undefined : value,
|
|
188
|
+
};
|
|
182
189
|
if (isPageMode) {
|
|
183
|
-
history.push(`${baseUrl}
|
|
190
|
+
history.push(`${joinUrl(baseUrl, 'search')}?${urlStringify(changData)}`);
|
|
184
191
|
} else {
|
|
185
192
|
setMemoryParams(changData);
|
|
186
193
|
}
|
|
@@ -196,23 +203,27 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
196
203
|
},
|
|
197
204
|
handleCategorySelect: (value) => {
|
|
198
205
|
if (value === 'all') {
|
|
199
|
-
const changData = { ...queryParams, category: undefined };
|
|
206
|
+
const changData = { ...Object.fromEntries(queryParams.entries()), category: undefined };
|
|
200
207
|
if (isPageMode) {
|
|
201
|
-
history.push(!isSearchPage ? baseUrl : `${baseUrl}
|
|
208
|
+
history.push(!isSearchPage ? baseUrl : `${joinUrl(baseUrl, 'search')}?${urlStringify(changData)}`);
|
|
202
209
|
} else {
|
|
203
210
|
setMemoryParams(changData);
|
|
204
211
|
}
|
|
205
212
|
} else {
|
|
206
|
-
const changData = { ...queryParams, category: value };
|
|
213
|
+
const changData = { ...Object.fromEntries(queryParams.entries()), category: value };
|
|
207
214
|
if (isPageMode) {
|
|
208
|
-
history.push(
|
|
215
|
+
history.push(
|
|
216
|
+
!isSearchPage
|
|
217
|
+
? `${joinUrl(baseUrl, 'category', value)}`
|
|
218
|
+
: `${joinUrl(baseUrl, 'search')}?${urlStringify(changData)}`
|
|
219
|
+
);
|
|
209
220
|
} else {
|
|
210
221
|
setMemoryParams(changData);
|
|
211
222
|
}
|
|
212
223
|
}
|
|
213
224
|
},
|
|
214
225
|
get developerName() {
|
|
215
|
-
return allBlocklets.find((i) => i.owner.did === queryParams.developer)?.owner?.name || '';
|
|
226
|
+
return allBlocklets.find((i) => i.owner.did === queryParams.get('developer'))?.owner?.name || '';
|
|
216
227
|
},
|
|
217
228
|
};
|
|
218
229
|
|
|
@@ -221,6 +232,11 @@ function SearchProvider({ children, baseUrl, type, endpoint, locale, blockletRen
|
|
|
221
232
|
fetchCategories();
|
|
222
233
|
}
|
|
223
234
|
}, [!hasDeveloperFilter]);
|
|
235
|
+
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
fetchBlocklets();
|
|
238
|
+
}, [endpoint]);
|
|
239
|
+
|
|
224
240
|
return <Provider value={searchStore}>{children}</Provider>;
|
|
225
241
|
}
|
|
226
242
|
|
package/src/tools/utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import joinURL from 'url-join';
|
|
2
|
+
import cloneDeep from 'lodash-es/cloneDeep';
|
|
2
3
|
|
|
3
4
|
const isFreeBlocklet = (meta) => {
|
|
4
5
|
if (!meta.payment) {
|
|
@@ -81,10 +82,27 @@ const formatLogoPath = (did, asset, target = 'assets') => {
|
|
|
81
82
|
}
|
|
82
83
|
return `${target}/${did}/${asset}`;
|
|
83
84
|
};
|
|
84
|
-
const
|
|
85
|
+
const replaceTranslate = (template, data) =>
|
|
85
86
|
// eslint-disable-next-line no-prototype-builtins
|
|
86
87
|
template.replace(/{(\w*)}/g, (m, key) => (data.hasOwnProperty(key) ? data[key] : ''));
|
|
87
88
|
|
|
89
|
+
const removeUndefined = (obj) => {
|
|
90
|
+
const innerObj = cloneDeep(obj);
|
|
91
|
+
Object.keys(innerObj).forEach((key) => {
|
|
92
|
+
if (innerObj[key] === undefined) {
|
|
93
|
+
delete innerObj[key];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return innerObj;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const urlStringify = (obj) => {
|
|
100
|
+
if (!obj) {
|
|
101
|
+
throw new Error('obj is required in urlStringify ');
|
|
102
|
+
}
|
|
103
|
+
return new URLSearchParams(removeUndefined(obj)).toString();
|
|
104
|
+
};
|
|
105
|
+
|
|
88
106
|
export {
|
|
89
107
|
getSortOptions,
|
|
90
108
|
getPrices,
|
|
@@ -92,6 +110,8 @@ export {
|
|
|
92
110
|
filterBlockletByPrice,
|
|
93
111
|
getStoreDetail,
|
|
94
112
|
formatLogoPath,
|
|
95
|
-
|
|
113
|
+
replaceTranslate,
|
|
96
114
|
formatError,
|
|
115
|
+
removeUndefined,
|
|
116
|
+
urlStringify,
|
|
97
117
|
};
|