soulseek, extracted from the platform as a plugin
Seventh plugin out, and the first that was already dead. Soulseek had been switched off since 2026-08-13: hono.ts had the router import and its mount commented out, so createSidecarProxy never ran, registerProxiedPrefix was never called, the slskd:server announcement fired into a void, and officer-slskd was not in the ecosystem at all. The permission entry had been reduced to api: [], which is why assertPermissionTotality was satisfied and the server booted clean. The UI rendered perfectly and every request 404'd. So this is a resurrection as well as a move. The mount is now /api/soulseek, derived via mountPrefix from the appName — all 47 frontend call sites repointed from /slskd/. The credential key in service_connections stays 'slskd': it names the daemon, not the route. Those two strings differ on purpose and conflating them reads the wrong row. The connection stays in core service_connections, as transmission does, so 'slskd' remains in a platform union this plugin cannot extend. Recorded in PLUGIN.md. Unlike transmission this plugin does own a schema: favourites and the two halves of the cached browse tree, which slskd has no concept of. Those three tables had been dropped from the drizzle barrel, so bun db:push would have deleted them on any server holding data. 313 palette classes converted to the semantic tone set, including a shared PHASE_TONE the three transfer views previously each copied.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { Construction } from 'lucide-react';
|
||||
import { SOULSEEK_SECTIONS, useSoulseekSection, type SoulseekSectionId } from './shared';
|
||||
import { SearchView } from './SearchView';
|
||||
import { SoulseekTransfers } from './SoulseekTransfers';
|
||||
import { SoulseekUploads } from './SoulseekUploads';
|
||||
import { SoulseekRooms } from './SoulseekRooms';
|
||||
import { SoulseekDashboard } from './SoulseekDashboard';
|
||||
import { SoulseekChat } from './SoulseekChat';
|
||||
import { SoulseekUsers } from './SoulseekUsers';
|
||||
import { SoulseekSystem } from './SoulseekSystem';
|
||||
import { SoulseekConnection } from './SoulseekConnection';
|
||||
import { useServiceConnection } from 'officerdev';
|
||||
|
||||
// Right panel of the /soulseek workspace — renders the UI for the section the URL names. Content
|
||||
// zoom used to live here; it is now a framework-level per-panel control in PanelSlot.
|
||||
|
||||
const Placeholder = ({ id }: { id: SoulseekSectionId }) => {
|
||||
const label = SOULSEEK_SECTIONS.find((s) => s.id === id)?.label ?? id;
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-3 text-center">
|
||||
<div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-muted text-muted-foreground">
|
||||
<Construction className="h-6 w-6" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-base font-semibold">{label}</div>
|
||||
<div className="text-sm text-muted-foreground">Coming soon</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const sectionView = (section: SoulseekSectionId) => {
|
||||
switch (section) {
|
||||
case 'dashboard':
|
||||
return <SoulseekDashboard />;
|
||||
case 'search':
|
||||
return <SearchView />;
|
||||
case 'downloads':
|
||||
return <SoulseekTransfers />;
|
||||
case 'uploads':
|
||||
return <SoulseekUploads />;
|
||||
case 'rooms':
|
||||
return <SoulseekRooms />;
|
||||
case 'chat':
|
||||
return <SoulseekChat />;
|
||||
case 'users':
|
||||
return <SoulseekUsers />;
|
||||
case 'system':
|
||||
return <SoulseekSystem />;
|
||||
case 'connection':
|
||||
return <SoulseekConnection />;
|
||||
default:
|
||||
return <Placeholder id={section} />;
|
||||
}
|
||||
};
|
||||
|
||||
export const SoulseekView = () => {
|
||||
const section = useSoulseekSection();
|
||||
const { data: connection, isLoading } = useServiceConnection('soulseek');
|
||||
|
||||
// Nothing connected yet: the setup form takes over every section, because none of them can do anything
|
||||
// without a daemon.
|
||||
if (!isLoading && !connection?.configured) return <SoulseekConnection />;
|
||||
|
||||
return <div className="h-full w-full">{sectionView(section)}</div>;
|
||||
};
|
||||
Reference in New Issue
Block a user