Skip to content

Commit e229902

Browse files
authored
refactor: plugins page (#1428)
* refactor: plugins page - fixed layout issue - enable/disable state update issue - dont show switch on updates page * minor ui improvements and refactor filter things * fix * Update style.scss
1 parent 7495c7b commit e229902

File tree

5 files changed

+419
-149
lines changed

5 files changed

+419
-149
lines changed

src/pages/plugins/item.js

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default function Item({
2626
installed,
2727
enabled,
2828
onToggleEnabled,
29+
updates,
2930
}) {
3031
const authorName = (() => {
3132
const displayName =
@@ -98,12 +99,10 @@ export default function Item({
9899
{price !== null && price !== undefined && price !== 0 ? (
99100
<span className="plugin-price">{price}</span>
100101
) : null}
101-
{/* Enable/Disable Toggle */}
102-
{installed && (
102+
{installed && !updates ? (
103103
<span
104104
className="plugin-toggle-switch"
105105
data-enabled={enabled}
106-
// style={{ marginLeft: 12, display: 'flex', alignItems: 'center', gap: 4, cursor: 'pointer', zIndex: 100 }}
107106
onclick={e => {
108107
e.stopPropagation();
109108
onToggleEnabled?.(id, enabled);
@@ -112,33 +111,11 @@ export default function Item({
112111
<span
113112
className="plugin-toggle-track"
114113
data-enabled={enabled}
115-
// style={{
116-
// width: 36,
117-
// height: 20,
118-
// borderRadius: 12,
119-
// background: enabled ? '#4ade80' : '#d1d5db',
120-
// position: 'relative',
121-
// transition: 'background 0.2s',
122-
// display: 'inline-block',
123-
// }}
124114
>
125-
<span
126-
className="plugin-toggle-thumb"
127-
// style={{
128-
// position: 'absolute',
129-
// left: enabled ? 18 : 2,
130-
// top: 2,
131-
// width: 16,
132-
// height: 16,
133-
// borderRadius: '50%',
134-
// background: '#fff',
135-
// boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
136-
// transition: 'left 0.2s',
137-
// }}
138-
/>
115+
<span className="plugin-toggle-thumb" />
139116
</span>
140117
</span>
141-
)}
118+
) : null}
142119
</div>
143120
</div>
144121
</div>

src/pages/plugins/plugins.js

Lines changed: 126 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export default function PluginsInclude(updates) {
5050
let isLoading = false;
5151
let hasMore = true;
5252
let isSearching = false;
53+
let currentFilter = null;
5354
const LIMIT = 50;
5455

5556
Contextmenu({
@@ -81,26 +82,32 @@ export default function PluginsInclude(updates) {
8182
downloads: strings.most_downloaded,
8283
};
8384
const filterName = filterNames[item];
85+
currentFilter = item;
86+
currentPage = 1;
87+
hasMore = true;
88+
isLoading = false;
89+
plugins.all = []; // Reset the all plugins array
8490
render("all");
85-
getFilteredPlugins(item).then((plugins) => {
86-
$list.all.replaceChildren();
87-
$list.all.append(
88-
<div className="filter-message">
89-
Filter for <strong>{filterName}</strong>
90-
<span
91-
className="icon clearclose"
92-
data-action="clear-filter"
93-
onclick={() => {
94-
$list.all.replaceChildren();
95-
getAllPlugins();
96-
}}
97-
></span>
98-
</div>,
99-
);
100-
plugins.forEach((plugin) => {
101-
$list.all.append(<Item {...plugin} />);
102-
});
103-
});
91+
$list.all.replaceChildren();
92+
$list.all.append(
93+
<div className="filter-message">
94+
Filtered by <strong>{filterName}</strong>
95+
<span
96+
className="icon clearclose"
97+
data-action="clear-filter"
98+
onclick={() => {
99+
currentFilter = null;
100+
currentPage = 1;
101+
hasMore = true;
102+
isLoading = false;
103+
plugins.all = []; // Reset the all plugins array
104+
$list.all.replaceChildren();
105+
getAllPlugins();
106+
}}
107+
></span>
108+
</div>,
109+
);
110+
getFilteredPlugins(item);
104111
},
105112
});
106113

@@ -153,8 +160,12 @@ export default function PluginsInclude(updates) {
153160
if (isLoading || !hasMore || isSearching) return;
154161

155162
const { scrollTop, scrollHeight, clientHeight } = e.target;
156-
if (scrollTop + clientHeight >= scrollHeight - 100) {
157-
await getAllPlugins();
163+
if (scrollTop + clientHeight >= scrollHeight - 50) {
164+
if (currentFilter) {
165+
await getFilteredPlugins(currentFilter);
166+
} else {
167+
await getAllPlugins();
168+
}
158169
}
159170
})
160171

@@ -237,6 +248,7 @@ export default function PluginsInclude(updates) {
237248
currentPage = 1;
238249
hasMore = true;
239250
isLoading = false;
251+
plugins.all = []; // Reset the all plugins array
240252
$list.all.replaceChildren();
241253
getAllPlugins();
242254
}
@@ -274,21 +286,56 @@ export default function PluginsInclude(updates) {
274286
}
275287

276288
async function getFilteredPlugins(filterName) {
289+
if (isLoading || !hasMore) return;
290+
277291
try {
292+
isLoading = true;
293+
$list.all.setAttribute("empty-msg", strings["loading..."]);
294+
278295
let response;
279296
if (filterName === "top_rated") {
280-
response = await fetch(`${constants.API_BASE}/plugins?explore=random`);
297+
response = await fetch(`${constants.API_BASE}/plugins?explore=random&page=${currentPage}&limit=${LIMIT}`);
281298
} else {
282299
response = await fetch(
283-
`${constants.API_BASE}/plugin?orderBy=${filterName}`,
300+
`${constants.API_BASE}/plugin?orderBy=${filterName}&page=${currentPage}&limit=${LIMIT}`,
284301
);
285302
}
286-
return await response.json();
303+
const fetchedPlugins = await response.json();
304+
305+
if (fetchedPlugins.length < LIMIT) {
306+
hasMore = false;
307+
}
308+
309+
const installed = await fsOperation(PLUGIN_DIR).lsDir();
310+
const disabledMap = settings.value.pluginsDisabled || {};
311+
312+
installed.forEach(({ url }) => {
313+
const plugin = fetchedPlugins.find(({ id }) => id === Url.basename(url));
314+
if (plugin) {
315+
plugin.installed = true;
316+
plugin.enabled = disabledMap[plugin.id] !== true;
317+
plugin.onToggleEnabled = onToggleEnabled;
318+
plugin.localPlugin = getLocalRes(plugin.id, "plugin.json");
319+
}
320+
});
321+
322+
// Add plugins to the all plugins array
323+
plugins.all.push(...fetchedPlugins);
324+
325+
const fragment = document.createDocumentFragment();
326+
fetchedPlugins.forEach((plugin) => {
327+
fragment.append(<Item {...plugin} updates={updates} />);
328+
});
329+
$list.all.append(fragment);
330+
331+
currentPage++;
332+
$list.all.setAttribute("empty-msg", strings["no plugins found"]);
287333
} catch (error) {
288334
$list.all.setAttribute("empty-msg", strings["error"]);
289335
window.log("error", "Failed to filter plugins:");
290336
window.log("error", error);
291-
return [];
337+
} finally {
338+
isLoading = false;
292339
}
293340
}
294341

@@ -308,17 +355,26 @@ export default function PluginsInclude(updates) {
308355
}
309356

310357
const installed = await fsOperation(PLUGIN_DIR).lsDir();
358+
const disabledMap = settings.value.pluginsDisabled || {};
359+
311360
installed.forEach(({ url }) => {
312361
const plugin = newPlugins.find(({ id }) => id === Url.basename(url));
313362
if (plugin) {
314363
plugin.installed = true;
364+
plugin.enabled = disabledMap[plugin.id] !== true;
365+
plugin.onToggleEnabled = onToggleEnabled;
315366
plugin.localPlugin = getLocalRes(plugin.id, "plugin.json");
316367
}
317368
});
318369

370+
// Add plugins to the all plugins array
371+
plugins.all.push(...newPlugins);
372+
373+
const fragment = document.createDocumentFragment();
319374
newPlugins.forEach((plugin) => {
320-
$list.all.append(<Item {...plugin} />);
375+
fragment.append(<Item {...plugin} updates={updates} />);
321376
});
377+
$list.all.append(fragment);
322378

323379
currentPage++;
324380
$list.all.setAttribute("empty-msg", strings["no plugins found"]);
@@ -347,7 +403,7 @@ export default function PluginsInclude(updates) {
347403
plugin.onToggleEnabled = onToggleEnabled;
348404
plugins.installed.push(plugin);
349405
if ($list.installed.get(`[data-id=\"${id}\"]`)) return;
350-
$list.installed.append(<Item {...plugin} />);
406+
$list.installed.append(<Item {...plugin} updates={updates} />);
351407
}),
352408
);
353409
$list.installed.setAttribute("empty-msg", strings["no plugins found"]);
@@ -356,14 +412,22 @@ export default function PluginsInclude(updates) {
356412
async function getOwned() {
357413
$list.owned.setAttribute("empty-msg", strings["loading..."]);
358414
const purchases = await helpers.promisify(iap.getPurchases);
415+
const disabledMap = settings.value.pluginsDisabled || {};
416+
359417
purchases.forEach(async ({ productIds }) => {
360418
const [sku] = productIds;
361419
const url = Url.join(constants.API_BASE, "plugin/owned", sku);
362420
const plugin = await fsOperation(url).readFile("json");
363421
const isInstalled = plugins.installed.find(({ id }) => id === plugin.id);
364422
plugin.installed = !!isInstalled;
423+
424+
if (plugin.installed) {
425+
plugin.enabled = disabledMap[plugin.id] !== true;
426+
plugin.onToggleEnabled = onToggleEnabled;
427+
}
428+
365429
plugins.owned.push(plugin);
366-
$list.owned.append(<Item {...plugin} />);
430+
$list.owned.append(<Item {...plugin} updates={updates} />);
367431
});
368432
$list.owned.setAttribute("empty-msg", strings["no plugins found"]);
369433
}
@@ -392,7 +456,7 @@ export default function PluginsInclude(updates) {
392456

393457
const existingItem = $list.installed.get(`[data-id="${plugin.id}"]`);
394458
if (!existingItem) {
395-
$list.installed.append(<Item {...plugin} />);
459+
$list.installed.append(<Item {...plugin} updates={updates} />);
396460
}
397461

398462
}
@@ -456,17 +520,39 @@ export default function PluginsInclude(updates) {
456520
window.toast(strings["plugin_enabled"] || "Plugin enabled");
457521
}
458522

459-
// Update the plugin object's state
460-
const plugin = plugins.installed.find(p => p.id === id);
461-
if (plugin) {
462-
plugin.enabled = !enabled;
463-
464-
// Re-render the specific item
465-
const $existingItem = $list.installed.get(`[data-id="${id}"]`);
466-
if ($existingItem) {
467-
const $newItem = <Item {...plugin} />;
468-
$existingItem.replaceWith($newItem);
469-
}
523+
// Update the plugin object's state in all plugin arrays
524+
const installedPlugin = plugins.installed.find(p => p.id === id);
525+
if (installedPlugin) {
526+
installedPlugin.enabled = !enabled;
527+
}
528+
529+
const allPlugin = plugins.all.find(p => p.id === id);
530+
if (allPlugin) {
531+
allPlugin.enabled = !enabled;
532+
}
533+
534+
const ownedPlugin = plugins.owned.find(p => p.id === id);
535+
if (ownedPlugin) {
536+
ownedPlugin.enabled = !enabled;
537+
}
538+
539+
// Re-render the specific item in all tabs
540+
const $installedItem = $list.installed.get(`[data-id="${id}"]`);
541+
if ($installedItem && installedPlugin) {
542+
const $newItem = <Item {...installedPlugin} updates={updates} />;
543+
$installedItem.replaceWith($newItem);
544+
}
545+
546+
const $allItem = $list.all.get(`[data-id="${id}"]`);
547+
if ($allItem && allPlugin) {
548+
const $newItem = <Item {...allPlugin} updates={updates} />;
549+
$allItem.replaceWith($newItem);
550+
}
551+
552+
const $ownedItem = $list.owned.get(`[data-id="${id}"]`);
553+
if ($ownedItem && ownedPlugin) {
554+
const $newItem = <Item {...ownedPlugin} updates={updates} />;
555+
$ownedItem.replaceWith($newItem);
470556
}
471557
}
472558
}

0 commit comments

Comments
 (0)