@blocklet/list 0.8.34 → 0.8.35
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 +2 -2
- package/lib/components/list/index.js +34 -11
- package/lib/contexts/filter.js +27 -1
- package/lib/libs/utils.js +8 -2
- package/package.json +4 -3
- package/src/base.js +2 -2
- package/src/components/list/index.js +36 -9
- package/src/contexts/filter.js +32 -4
- package/src/libs/utils.js +6 -1
package/lib/base.js
CHANGED
|
@@ -40,7 +40,7 @@ function ListBase() {
|
|
|
40
40
|
|
|
41
41
|
const {
|
|
42
42
|
handleDeveloper,
|
|
43
|
-
|
|
43
|
+
finalBlockletList,
|
|
44
44
|
filters,
|
|
45
45
|
developerName,
|
|
46
46
|
handleSort,
|
|
@@ -111,7 +111,7 @@ function ListBase() {
|
|
|
111
111
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactErrorBoundary.ErrorBoundary, {
|
|
112
112
|
FallbackComponent: _ErrorBoundary.ErrorFallback,
|
|
113
113
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_list.default, {
|
|
114
|
-
blocklets:
|
|
114
|
+
blocklets: finalBlockletList
|
|
115
115
|
})
|
|
116
116
|
})]
|
|
117
117
|
})]
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = BlockletList;
|
|
7
7
|
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
8
10
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
11
|
|
|
10
12
|
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
@@ -17,6 +19,8 @@ var _Grid = _interopRequireDefault(require("@mui/material/Grid"));
|
|
|
17
19
|
|
|
18
20
|
var _CircularProgress = _interopRequireDefault(require("@mui/material/CircularProgress"));
|
|
19
21
|
|
|
22
|
+
var _reactInfiniteScrollHook = _interopRequireDefault(require("react-infinite-scroll-hook"));
|
|
23
|
+
|
|
20
24
|
var _ErrorBoundary = require("@arcblock/ux/lib/ErrorBoundary");
|
|
21
25
|
|
|
22
26
|
var _empty = require("./empty");
|
|
@@ -50,13 +54,21 @@ function BlockletList(_ref) {
|
|
|
50
54
|
errors,
|
|
51
55
|
loadings,
|
|
52
56
|
selectedCategory,
|
|
53
|
-
|
|
57
|
+
finalBlockletList,
|
|
54
58
|
getCategoryLocale,
|
|
55
59
|
filters,
|
|
56
60
|
t,
|
|
61
|
+
hasNextPage,
|
|
62
|
+
loadMore,
|
|
57
63
|
endpoint
|
|
58
64
|
} = (0, _filter.useFilterContext)();
|
|
59
65
|
const showFilterTip = !!selectedCategory || !!filters.price;
|
|
66
|
+
const [sentryRef] = (0, _reactInfiniteScrollHook.default)({
|
|
67
|
+
loading: loadings.fetchBlockletsLoading,
|
|
68
|
+
hasNextPage,
|
|
69
|
+
onLoadMore: loadMore,
|
|
70
|
+
rootMargin: '0px 0px 400px 0px'
|
|
71
|
+
});
|
|
60
72
|
|
|
61
73
|
if (errors.fetchBlockletsError) {
|
|
62
74
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ErrorBoundary.ErrorFallback, {
|
|
@@ -73,7 +85,7 @@ function BlockletList(_ref) {
|
|
|
73
85
|
});
|
|
74
86
|
}
|
|
75
87
|
|
|
76
|
-
if (filters.keyword && showFilterTip &&
|
|
88
|
+
if (filters.keyword && showFilterTip && finalBlockletList.length === 0) {
|
|
77
89
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(CustomEmpty, {
|
|
78
90
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_empty.EmptyTitle, {
|
|
79
91
|
primaryStart: t('blocklet.noBlockletPart1'),
|
|
@@ -86,7 +98,7 @@ function BlockletList(_ref) {
|
|
|
86
98
|
});
|
|
87
99
|
}
|
|
88
100
|
|
|
89
|
-
if (filters.keyword &&
|
|
101
|
+
if (filters.keyword && finalBlockletList.length === 0) {
|
|
90
102
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(CustomEmpty, {
|
|
91
103
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_empty.EmptyTitle, {
|
|
92
104
|
primaryStart: t('blocklet.noBlockletPart1'),
|
|
@@ -98,7 +110,7 @@ function BlockletList(_ref) {
|
|
|
98
110
|
});
|
|
99
111
|
}
|
|
100
112
|
|
|
101
|
-
if (showFilterTip &&
|
|
113
|
+
if (showFilterTip && finalBlockletList.length === 0) {
|
|
102
114
|
const categoryLocale = getCategoryLocale(selectedCategory);
|
|
103
115
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(CustomEmpty, {
|
|
104
116
|
children: [categoryLocale ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_empty.EmptyTitle, {
|
|
@@ -111,16 +123,16 @@ function BlockletList(_ref) {
|
|
|
111
123
|
});
|
|
112
124
|
}
|
|
113
125
|
|
|
114
|
-
if (
|
|
126
|
+
if (finalBlockletList.length === 0) {
|
|
115
127
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(CustomEmpty, {
|
|
116
128
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_empty.NoResults, {})
|
|
117
129
|
});
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
132
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(StyledGrid, _objectSpread(_objectSpread({
|
|
121
133
|
container: true
|
|
122
134
|
}, rest), {}, {
|
|
123
|
-
children: blocklets.map(blocklet => /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledGridItem, {
|
|
135
|
+
children: [blocklets.map(blocklet => /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledGridItem, {
|
|
124
136
|
item: true,
|
|
125
137
|
lg: 4,
|
|
126
138
|
md: 6,
|
|
@@ -129,9 +141,20 @@ function BlockletList(_ref) {
|
|
|
129
141
|
"data-blocklet-did": blocklet.did,
|
|
130
142
|
children: blockletRender({
|
|
131
143
|
blocklet,
|
|
132
|
-
blocklets:
|
|
144
|
+
blocklets: finalBlockletList
|
|
145
|
+
})
|
|
146
|
+
}, blocklet.did)), hasNextPage && /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledGridItem, {
|
|
147
|
+
item: true,
|
|
148
|
+
md: 12,
|
|
149
|
+
sm: 12,
|
|
150
|
+
xs: 12,
|
|
151
|
+
ref: sentryRef,
|
|
152
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
|
|
153
|
+
display: "flex",
|
|
154
|
+
justifyContent: "center",
|
|
155
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CircularProgress.default, {})
|
|
133
156
|
})
|
|
134
|
-
}
|
|
157
|
+
})]
|
|
135
158
|
}));
|
|
136
159
|
}
|
|
137
160
|
|
|
@@ -143,10 +166,10 @@ const StyledGrid = (0, _styledComponents.default)(_Grid.default).withConfig({
|
|
|
143
166
|
displayName: "list__StyledGrid",
|
|
144
167
|
componentId: "sc-1guvpon-0"
|
|
145
168
|
})(["&.MuiGrid-root{width:auto;margin:0 -16px;}"]);
|
|
146
|
-
const StyledGridItem = (0, _styledComponents.default)(_Grid.default).withConfig({
|
|
169
|
+
const StyledGridItem = /*#__PURE__*/(0, _react.memo)((0, _styledComponents.default)(_Grid.default).withConfig({
|
|
147
170
|
displayName: "list__StyledGridItem",
|
|
148
171
|
componentId: "sc-1guvpon-1"
|
|
149
|
-
})(["@media (max-width:", "px){&.MuiGrid-item{padding-bottom:0px;}}@media (min-width:", "px){&.MuiGrid-item{margin-bottom:", ";}}"], props => props.theme.breakpoints.values.sm, props => props.theme.breakpoints.values.sm, props => props.theme.spacing(2));
|
|
172
|
+
})(["@media (max-width:", "px){&.MuiGrid-item{padding-bottom:0px;}}@media (min-width:", "px){&.MuiGrid-item{margin-bottom:", ";}}"], props => props.theme.breakpoints.values.sm, props => props.theme.breakpoints.values.sm, props => props.theme.spacing(2)));
|
|
150
173
|
const CustomEmpty = (0, _styledComponents.default)(_Empty.default).withConfig({
|
|
151
174
|
displayName: "list__CustomEmpty",
|
|
152
175
|
componentId: "sc-1guvpon-2"
|
package/lib/contexts/filter.js
CHANGED
|
@@ -95,6 +95,11 @@ function FilterProvider(_ref) {
|
|
|
95
95
|
initialData: [],
|
|
96
96
|
manual: true
|
|
97
97
|
});
|
|
98
|
+
const paginateState = (0, _ahooks.useReactive)({
|
|
99
|
+
currentPage: 1,
|
|
100
|
+
pageSize: (0, _utils.isMobileScreen)() ? 10 : 18,
|
|
101
|
+
defaultCurrentPage: 1
|
|
102
|
+
});
|
|
98
103
|
|
|
99
104
|
const finalFilters = _objectSpread({
|
|
100
105
|
sortBy: 'popularity',
|
|
@@ -153,6 +158,10 @@ function FilterProvider(_ref) {
|
|
|
153
158
|
|
|
154
159
|
return (0, _orderBy.default)(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
|
|
155
160
|
}, [allBlocklets, finalFilters]);
|
|
161
|
+
const finalBlockletList = (0, _react.useMemo)(() => {
|
|
162
|
+
// 前端分页 currentPage 当前页数 pageSize 每页条数
|
|
163
|
+
return blockletList.slice((paginateState.defaultCurrentPage - 1) * paginateState.pageSize, paginateState.currentPage * paginateState.pageSize);
|
|
164
|
+
}, [blockletList, paginateState]);
|
|
156
165
|
const categoryList = (0, _react.useMemo)(() => {
|
|
157
166
|
const list = categoryState.data || []; // 分类按照名称排序
|
|
158
167
|
|
|
@@ -180,7 +189,7 @@ function FilterProvider(_ref) {
|
|
|
180
189
|
fetchCategoriesLoading
|
|
181
190
|
},
|
|
182
191
|
endpoint,
|
|
183
|
-
|
|
192
|
+
finalBlockletList,
|
|
184
193
|
t: translate,
|
|
185
194
|
filters: finalFilters,
|
|
186
195
|
selectedCategory,
|
|
@@ -189,6 +198,7 @@ function FilterProvider(_ref) {
|
|
|
189
198
|
locale,
|
|
190
199
|
categoryOptions,
|
|
191
200
|
priceOptions,
|
|
201
|
+
hasNextPage: blockletList.length >= paginateState.pageSize * paginateState.currentPage,
|
|
192
202
|
handleSort: sort => {
|
|
193
203
|
const changeData = _objectSpread(_objectSpread({}, finalFilters), {}, {
|
|
194
204
|
sortBy: sort,
|
|
@@ -231,6 +241,18 @@ function FilterProvider(_ref) {
|
|
|
231
241
|
|
|
232
242
|
onFilterChange(changeData);
|
|
233
243
|
},
|
|
244
|
+
handlePage: page => {
|
|
245
|
+
const changeData = _objectSpread(_objectSpread({}, finalFilters), {}, {
|
|
246
|
+
currentPage: page
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
onFilterChange(changeData);
|
|
250
|
+
},
|
|
251
|
+
loadMore: () => {
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
paginateState.currentPage += 1;
|
|
254
|
+
}, 1000);
|
|
255
|
+
},
|
|
234
256
|
getCategoryLocale: category => {
|
|
235
257
|
if (!category) return null;
|
|
236
258
|
let result = null;
|
|
@@ -243,6 +265,10 @@ function FilterProvider(_ref) {
|
|
|
243
265
|
return result;
|
|
244
266
|
},
|
|
245
267
|
|
|
268
|
+
get allBlocklets() {
|
|
269
|
+
return allBlocklets || [];
|
|
270
|
+
},
|
|
271
|
+
|
|
246
272
|
get developerName() {
|
|
247
273
|
var _blocklets$find, _blocklets$find$owner;
|
|
248
274
|
|
package/lib/libs/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = exports.getStoreDetail = exports.getSortOptions = exports.getPrices = exports.getCategoryOptions = exports.getCategories = exports.formatLogoPath = exports.formatError = exports.filterBlockletByPrice = void 0;
|
|
6
|
+
exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = exports.isMobileScreen = exports.getStoreDetail = exports.getSortOptions = exports.getPrices = exports.getCategoryOptions = exports.getCategories = exports.formatLogoPath = exports.formatError = exports.filterBlockletByPrice = void 0;
|
|
7
7
|
|
|
8
8
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
9
9
|
|
|
@@ -159,4 +159,10 @@ const urlStringify = obj => {
|
|
|
159
159
|
return new URLSearchParams(removeUndefined(obj)).toString();
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
-
exports.urlStringify = urlStringify;
|
|
162
|
+
exports.urlStringify = urlStringify;
|
|
163
|
+
|
|
164
|
+
const isMobileScreen = () => {
|
|
165
|
+
return window.innerWidth <= 600;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
exports.isMobileScreen = isMobileScreen;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/list",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.35",
|
|
4
4
|
"description": "Common ux components of blocklet",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"react": ">=18.1.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@arcblock/ux": "^2.1.
|
|
41
|
+
"@arcblock/ux": "^2.1.21",
|
|
42
42
|
"@emotion/react": "^11.9.0",
|
|
43
43
|
"@emotion/styled": "^11.8.1",
|
|
44
44
|
"@mui/icons-material": "^5.6.2",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"lodash": "^4.17.21",
|
|
49
49
|
"prop-types": "^15.7.2",
|
|
50
50
|
"react-error-boundary": "^3.1.4",
|
|
51
|
+
"react-infinite-scroll-hook": "^4.0.3",
|
|
51
52
|
"styled-components": "5.3.5",
|
|
52
53
|
"url-join": "^4.0.1"
|
|
53
54
|
},
|
|
@@ -63,5 +64,5 @@
|
|
|
63
64
|
"eslint": "^8.16.0",
|
|
64
65
|
"prettier": "^2.6.2"
|
|
65
66
|
},
|
|
66
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "f6a52e3c84e6eb4cd5625f688a55d7da1b477740"
|
|
67
68
|
}
|
package/src/base.js
CHANGED
|
@@ -16,7 +16,7 @@ import Search from './components/search';
|
|
|
16
16
|
function ListBase() {
|
|
17
17
|
const {
|
|
18
18
|
handleDeveloper,
|
|
19
|
-
|
|
19
|
+
finalBlockletList,
|
|
20
20
|
filters,
|
|
21
21
|
developerName,
|
|
22
22
|
handleSort,
|
|
@@ -79,7 +79,7 @@ function ListBase() {
|
|
|
79
79
|
/>
|
|
80
80
|
</Box>
|
|
81
81
|
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
|
82
|
-
<BlockletList blocklets={
|
|
82
|
+
<BlockletList blocklets={finalBlockletList} />
|
|
83
83
|
</ErrorBoundary>
|
|
84
84
|
</StyledMin>
|
|
85
85
|
</Box>
|
|
@@ -1,20 +1,40 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
1
2
|
import PropTypes from 'prop-types';
|
|
2
3
|
import styled from 'styled-components';
|
|
3
4
|
import Empty from '@arcblock/ux/lib/Empty';
|
|
4
5
|
import Box from '@mui/material/Box';
|
|
5
6
|
import Grid from '@mui/material/Grid';
|
|
6
7
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
8
|
+
import useInfiniteScroll from 'react-infinite-scroll-hook';
|
|
7
9
|
import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
|
|
8
10
|
|
|
9
11
|
import { NoResults, EmptyTitle, NoResultsTips } from './empty';
|
|
10
12
|
import { useFilterContext } from '../../contexts/filter';
|
|
11
13
|
|
|
12
14
|
export default function BlockletList({ blocklets, ...rest }) {
|
|
13
|
-
const {
|
|
14
|
-
|
|
15
|
+
const {
|
|
16
|
+
blockletRender,
|
|
17
|
+
errors,
|
|
18
|
+
loadings,
|
|
19
|
+
selectedCategory,
|
|
20
|
+
finalBlockletList,
|
|
21
|
+
getCategoryLocale,
|
|
22
|
+
filters,
|
|
23
|
+
t,
|
|
24
|
+
hasNextPage,
|
|
25
|
+
loadMore,
|
|
26
|
+
endpoint,
|
|
27
|
+
} = useFilterContext();
|
|
15
28
|
|
|
16
29
|
const showFilterTip = !!selectedCategory || !!filters.price;
|
|
17
30
|
|
|
31
|
+
const [sentryRef] = useInfiniteScroll({
|
|
32
|
+
loading: loadings.fetchBlockletsLoading,
|
|
33
|
+
hasNextPage,
|
|
34
|
+
onLoadMore: loadMore,
|
|
35
|
+
rootMargin: '0px 0px 400px 0px',
|
|
36
|
+
});
|
|
37
|
+
|
|
18
38
|
if (errors.fetchBlockletsError) {
|
|
19
39
|
return (
|
|
20
40
|
<ErrorFallback
|
|
@@ -29,7 +49,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
29
49
|
</Box>
|
|
30
50
|
);
|
|
31
51
|
}
|
|
32
|
-
if (filters.keyword && showFilterTip &&
|
|
52
|
+
if (filters.keyword && showFilterTip && finalBlockletList.length === 0) {
|
|
33
53
|
return (
|
|
34
54
|
<CustomEmpty>
|
|
35
55
|
<EmptyTitle
|
|
@@ -41,7 +61,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
41
61
|
</CustomEmpty>
|
|
42
62
|
);
|
|
43
63
|
}
|
|
44
|
-
if (filters.keyword &&
|
|
64
|
+
if (filters.keyword && finalBlockletList.length === 0) {
|
|
45
65
|
return (
|
|
46
66
|
<CustomEmpty>
|
|
47
67
|
<EmptyTitle
|
|
@@ -53,7 +73,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
53
73
|
</CustomEmpty>
|
|
54
74
|
);
|
|
55
75
|
}
|
|
56
|
-
if (showFilterTip &&
|
|
76
|
+
if (showFilterTip && finalBlockletList.length === 0) {
|
|
57
77
|
const categoryLocale = getCategoryLocale(selectedCategory);
|
|
58
78
|
return (
|
|
59
79
|
<CustomEmpty>
|
|
@@ -70,7 +90,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
70
90
|
</CustomEmpty>
|
|
71
91
|
);
|
|
72
92
|
}
|
|
73
|
-
if (
|
|
93
|
+
if (finalBlockletList.length === 0) {
|
|
74
94
|
return (
|
|
75
95
|
<CustomEmpty>
|
|
76
96
|
<NoResults />
|
|
@@ -82,9 +102,16 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
82
102
|
<StyledGrid container {...rest}>
|
|
83
103
|
{blocklets.map((blocklet) => (
|
|
84
104
|
<StyledGridItem item lg={4} md={6} sm={6} xs={12} key={blocklet.did} data-blocklet-did={blocklet.did}>
|
|
85
|
-
{blockletRender({ blocklet, blocklets:
|
|
105
|
+
{blockletRender({ blocklet, blocklets: finalBlockletList })}
|
|
86
106
|
</StyledGridItem>
|
|
87
107
|
))}
|
|
108
|
+
{hasNextPage && (
|
|
109
|
+
<StyledGridItem item md={12} sm={12} xs={12} ref={sentryRef}>
|
|
110
|
+
<Box display="flex" justifyContent="center">
|
|
111
|
+
<CircularProgress />
|
|
112
|
+
</Box>
|
|
113
|
+
</StyledGridItem>
|
|
114
|
+
)}
|
|
88
115
|
</StyledGrid>
|
|
89
116
|
);
|
|
90
117
|
}
|
|
@@ -102,7 +129,7 @@ const StyledGrid = styled(Grid)`
|
|
|
102
129
|
}
|
|
103
130
|
`;
|
|
104
131
|
|
|
105
|
-
const StyledGridItem = styled(Grid)`
|
|
132
|
+
const StyledGridItem = memo(styled(Grid)`
|
|
106
133
|
@media (max-width: ${(props) => props.theme.breakpoints.values.sm}px) {
|
|
107
134
|
&.MuiGrid-item {
|
|
108
135
|
padding-bottom: 0px;
|
|
@@ -113,7 +140,7 @@ const StyledGridItem = styled(Grid)`
|
|
|
113
140
|
margin-bottom: ${(props) => props.theme.spacing(2)};
|
|
114
141
|
}
|
|
115
142
|
}
|
|
116
|
-
|
|
143
|
+
`);
|
|
117
144
|
const CustomEmpty = styled(Empty)`
|
|
118
145
|
text-align: center;
|
|
119
146
|
.primary {
|
package/src/contexts/filter.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { useContext, createContext, useMemo, useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { useRequest } from 'ahooks';
|
|
3
|
+
import { useRequest, useReactive } from 'ahooks';
|
|
4
4
|
import orderBy from 'lodash/orderBy';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import isArray from 'lodash/isArray';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
getCategories,
|
|
9
|
+
filterBlockletByPrice,
|
|
10
|
+
replaceTranslate,
|
|
11
|
+
getPrices,
|
|
12
|
+
getCategoryOptions,
|
|
13
|
+
isMobileScreen,
|
|
14
|
+
} from '../libs/utils';
|
|
9
15
|
import translations from '../assets/locale';
|
|
10
16
|
import { propTypes, defaultProps } from '../libs/prop-types';
|
|
11
17
|
|
|
@@ -48,6 +54,7 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
48
54
|
{ initialData: [], manual: true }
|
|
49
55
|
);
|
|
50
56
|
|
|
57
|
+
const paginateState = useReactive({ currentPage: 1, pageSize: isMobileScreen() ? 10 : 18, defaultCurrentPage: 1 });
|
|
51
58
|
const finalFilters = { sortBy: 'popularity', sortDirection: 'desc', ...filters };
|
|
52
59
|
const selectedCategory = finalFilters.category;
|
|
53
60
|
const hasDeveloperFilter = !!finalFilters.developer;
|
|
@@ -89,6 +96,14 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
89
96
|
return orderBy(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
|
|
90
97
|
}, [allBlocklets, finalFilters]);
|
|
91
98
|
|
|
99
|
+
const finalBlockletList = useMemo(() => {
|
|
100
|
+
// 前端分页 currentPage 当前页数 pageSize 每页条数
|
|
101
|
+
return blockletList.slice(
|
|
102
|
+
(paginateState.defaultCurrentPage - 1) * paginateState.pageSize,
|
|
103
|
+
paginateState.currentPage * paginateState.pageSize
|
|
104
|
+
);
|
|
105
|
+
}, [blockletList, paginateState]);
|
|
106
|
+
|
|
92
107
|
const categoryList = useMemo(() => {
|
|
93
108
|
const list = categoryState.data || [];
|
|
94
109
|
// 分类按照名称排序
|
|
@@ -109,7 +124,7 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
109
124
|
errors: { fetchBlockletsError, fetchCategoriesError },
|
|
110
125
|
loadings: { fetchBlockletsLoading, fetchCategoriesLoading },
|
|
111
126
|
endpoint,
|
|
112
|
-
|
|
127
|
+
finalBlockletList,
|
|
113
128
|
t: translate,
|
|
114
129
|
filters: finalFilters,
|
|
115
130
|
selectedCategory,
|
|
@@ -118,6 +133,7 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
118
133
|
locale,
|
|
119
134
|
categoryOptions,
|
|
120
135
|
priceOptions,
|
|
136
|
+
hasNextPage: blockletList.length >= paginateState.pageSize * paginateState.currentPage,
|
|
121
137
|
handleSort: (sort) => {
|
|
122
138
|
const changeData = {
|
|
123
139
|
...finalFilters,
|
|
@@ -149,6 +165,15 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
149
165
|
const changeData = { ...finalFilters, developer: developer || undefined };
|
|
150
166
|
onFilterChange(changeData);
|
|
151
167
|
},
|
|
168
|
+
handlePage: (page) => {
|
|
169
|
+
const changeData = { ...finalFilters, currentPage: page };
|
|
170
|
+
onFilterChange(changeData);
|
|
171
|
+
},
|
|
172
|
+
loadMore: () => {
|
|
173
|
+
setTimeout(() => {
|
|
174
|
+
paginateState.currentPage += 1;
|
|
175
|
+
}, 1000);
|
|
176
|
+
},
|
|
152
177
|
getCategoryLocale: (category) => {
|
|
153
178
|
if (!category) return null;
|
|
154
179
|
let result = null;
|
|
@@ -158,6 +183,9 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
158
183
|
}
|
|
159
184
|
return result;
|
|
160
185
|
},
|
|
186
|
+
get allBlocklets() {
|
|
187
|
+
return allBlocklets || [];
|
|
188
|
+
},
|
|
161
189
|
get developerName() {
|
|
162
190
|
const blocklets = allBlocklets || [];
|
|
163
191
|
return blocklets.find((blocklet) => blocklet.owner.did === finalFilters.developer)?.owner?.name || '';
|
package/src/libs/utils.js
CHANGED
|
@@ -5,10 +5,10 @@ const isFreeBlocklet = (meta) => {
|
|
|
5
5
|
if (!meta.payment) {
|
|
6
6
|
return true;
|
|
7
7
|
}
|
|
8
|
-
|
|
9
8
|
const priceList = (meta.payment.price || []).map((x) => x.value || 0);
|
|
10
9
|
return priceList.every((x) => x === 0);
|
|
11
10
|
};
|
|
11
|
+
|
|
12
12
|
const getSortOptions = (t) => {
|
|
13
13
|
return [
|
|
14
14
|
{
|
|
@@ -106,6 +106,10 @@ const urlStringify = (obj) => {
|
|
|
106
106
|
return new URLSearchParams(removeUndefined(obj)).toString();
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
+
const isMobileScreen = () => {
|
|
110
|
+
return window.innerWidth <= 600;
|
|
111
|
+
};
|
|
112
|
+
|
|
109
113
|
export {
|
|
110
114
|
getSortOptions,
|
|
111
115
|
getPrices,
|
|
@@ -118,4 +122,5 @@ export {
|
|
|
118
122
|
removeUndefined,
|
|
119
123
|
urlStringify,
|
|
120
124
|
getCategoryOptions,
|
|
125
|
+
isMobileScreen,
|
|
121
126
|
};
|