import type { Package } from '@onelauncher/client/bindings'; import UFuzzy from '@leeoniya/ufuzzy'; import { FilterFunnel01Icon, RefreshCw01Icon, SearchMdIcon, Trash03Icon } from '@untitled-theme/icons-solid'; import { bridge } from '~imports'; import Button from '~ui/components/base/Button'; import TextField from '~ui/components/base/TextField'; import ScrollableContainer from '~ui/components/ScrollableContainer'; import Sidebar from '~ui/components/Sidebar'; import useBrowser from '~ui/hooks/useBrowser'; import useClusterContext from '~ui/hooks/useCluster'; import useCommand from '~ui/hooks/useCommand'; import useProcessor from '~ui/hooks/useProcessor'; import { type Accessor, createEffect, createSignal, For, Match, Show, Switch } from 'solid-js'; // TODO: This needs a rewrite. function ClusterMods() { const [cluster] = useClusterContext(); const { isRunning } = useProcessor(cluster()!); const [mods, { refetch: refetchMods }] = useCommand(cluster, () => bridge.commands.getClusterPackages(cluster()?.path || '', 'mod')); // Mods to display, should be a clone of the mods array but sorted const [displayedMods, setDisplayedMods] = createSignal([]); // true - `A to Z` & false - `Z to A` const [sortingAtoZ, setSortingAtoZ] = createSignal(true); function getModName(mod: Package) { if (mod.meta.type === 'unknown') return mod.file_name; return mod.meta.title || mod.file_name; } const uf = new UFuzzy(); const [modsSearchable] = createSignal(() => mods()?.map(getModName) || []); function search(value: string) { if (value === '' || value === undefined) { resetMods(); return; } const result = uf.search(modsSearchable()(), value); const filtered: Package[] = []; result[0]?.forEach((index) => { const mod = mods()?.[index]; if (mod) filtered.push(mod); }); setDisplayedMods(sortListByName(filtered)); } function sortListByName(list: Package[]): Package[] { if (sortingAtoZ()) return list.sort((a, b) => getModName(a).localeCompare(getModName(b))); else return list.sort((a, b) => getModName(b).localeCompare(getModName(a))); } function toggleNameSort() { setSortingAtoZ(!sortingAtoZ()); setDisplayedMods(sortListByName([...displayedMods()])); } function resetMods() { setDisplayedMods(sortListByName([...(mods() || [])])); } createEffect(() => { resetMods(); }); return (

Mods

0}> {mod => ( )}

No mods were found

); } export default ClusterMods; interface ModEntryProps { pkg: Package; refetch: () => void; isRunning: Accessor; }; function ModEntry(props: ModEntryProps) { const [cluster] = useClusterContext(); const browser = useBrowser(); const name = () => { if (props.pkg.meta.type === 'unknown') return props.pkg.file_name; return props.pkg.meta.title || props.pkg.file_name; }; const version = () => { let formatted = 'Unknown'; if (props.pkg.meta.type === 'managed') formatted = props.pkg.meta.version_formatted; return formatted; }; const tags = () => { type TagStatus = 'normal' | 'warning' | 'danger'; const tags: [string, TagStatus][] = []; const meta = props.pkg.meta; if (meta.type === 'managed') { tags[0] = [meta.provider, 'normal']; const supportedVersions = meta.mc_versions || []; if (supportedVersions.length === 0) tags.push(['Unknown Version', 'warning']); else if (!supportedVersions.includes(cluster()!.meta.mc_version)) tags.push(['Incompatible', 'danger']); } else { tags[0] = ['Unknown', 'normal']; } return tags; }; const icon = () => { if (props.pkg.meta.type === 'managed') return props.pkg.meta.icon_url; return undefined; }; function onClick(e: MouseEvent) { const meta = props.pkg.meta; if (meta.type === 'managed') { e.preventDefault(); e.stopPropagation(); browser.displayPackage(meta.package_id, meta.provider); } } async function deletePackage(e: MouseEvent) { e.preventDefault(); e.stopPropagation(); const path = cluster()?.path; if (path) { await bridge.commands.removeClusterPackage(path, props.pkg.file_name, 'mod'); await bridge.commands.syncClusterPackages(path); props.refetch(); } } return (
} fallback={
} when={icon()} />

{name()}

{([tag, status]) => ( {tag} )}
{version()} {/* TODO: Add version checker */} {/* */} {/* 1.0.1 */} {/* */}
{/* */}
); }