Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: various improvements

Hugo 2de0cc34 ad9a45c2

+11 -10
+1 -4
packages/app/e2e/tests/self-hosted/feature-requests.spec.ts
··· 21 21 await expect(page.getByRole("link", { name: /Windows phone support/ })).not.toBeVisible(); 22 22 }); 23 23 24 - test("renders vote counts and comment counts", async ({ page }) => { 24 + test("renders vote counts", async ({ page }) => { 25 25 await page.goto("/infuse"); 26 26 27 27 // Wait for the list to render 28 28 await expect(page.getByRole("link", { name: /Add dark mode support/ })).toBeVisible(); 29 - 30 - // fr-001 has 2 comments 31 - await expect(page.getByText("2 comments")).toBeVisible(); 32 29 33 30 // Vote counts are rendered (△ + number) — check that the triangle markers exist 34 31 const voteElements = page.getByText(/△\d/);
+9 -5
packages/app/src/pages/sphere-labels.tsx
··· 51 51 const editColor = useSignal(""); 52 52 const saving = useSignal(false); 53 53 const listError = useSignal(""); 54 + const optimisticLabels = useSignal<LabelData[] | null>(null); 54 55 55 56 const handleCreate = async (e: Event) => { 56 57 e.preventDefault(); ··· 110 111 }; 111 112 112 113 const handleMove = async (index: number, direction: -1 | 1) => { 113 - if (!data) return; 114 + const labels = optimisticLabels.value ?? data?.labels; 115 + if (!labels) return; 114 116 const newIndex = index + direction; 115 - if (newIndex < 0 || newIndex >= data.labels.length) return; 116 - const reordered = [...data.labels]; 117 + if (newIndex < 0 || newIndex >= labels.length) return; 118 + const reordered = [...labels]; 117 119 const [item] = reordered.splice(index, 1); 118 120 reordered.splice(newIndex, 0, item); 121 + optimisticLabels.value = reordered; 119 122 try { 120 123 await reorderSphereLabels( 121 124 handle, ··· 123 126 ); 124 127 refetch(); 125 128 } catch (err) { 129 + optimisticLabels.value = null; 126 130 listError.value = err instanceof Error ? err.message : "Failed to reorder labels."; 127 131 } 128 132 }; ··· 208 212 <p class={ui.emptyState}>No labels yet.</p> 209 213 ) : ( 210 214 <div class={ui.stackSm}> 211 - {data.labels.map((label, index) => ( 215 + {(optimisticLabels.value ?? data.labels).map((label, index) => ( 212 216 <div key={label.id} class={ui.card}> 213 217 {editingId.value === label.id ? ( 214 218 <div class={ui.formStack}> ··· 264 268 </button> 265 269 <button 266 270 class={cpUi.arrowBtn} 267 - disabled={index === data!.labels.length - 1} 271 + disabled={index === (optimisticLabels.value ?? data.labels).length - 1} 268 272 onClick={() => handleMove(index, 1)} 269 273 title="Move down" 270 274 >
+1 -1
packages/feature-requests/src/ui/ui.css.ts
··· 70 70 export const detailCardWrapper = style({ 71 71 border: `1px solid ${vars.color.border}`, 72 72 borderRadius: vars.radius.lg, 73 - boxShadow: `0 1px 3px ${vars.color.shadow}, 0 1px 2px ${vars.color.shadow}`, 73 + boxShadow: `0 1px 3px ${vars.color.shadow}`, 74 74 overflow: "hidden", 75 75 }); 76 76