diff --git a/e2e/USER_STORIES.md b/e2e/USER_STORIES.md index afd7567c..6c6fb44e 100644 --- a/e2e/USER_STORIES.md +++ b/e2e/USER_STORIES.md @@ -153,8 +153,8 @@ Acceptance: - Typing a term filters both sections live, matching name, url, or description. - Clicking a joined space opens it; clicking one she hasn't joined opens a join prompt instead. -- Dragging a joined space above another reorders the list immediately, and the - order survives a reload. +- Dragging a joined space above another, on the page or in the sidebar rail, + reorders the list immediately, and the order survives a reload. ### US-010 — Join a space from an invite link diff --git a/e2e/specs/spaces.spec.ts b/e2e/specs/spaces.spec.ts index 4f133cb4..aecac9e9 100644 --- a/e2e/specs/spaces.spec.ts +++ b/e2e/specs/spaces.spec.ts @@ -83,6 +83,24 @@ test("US-009 browse, search, and reorder your spaces", async ({seed, as}) => { // starts the drag and moves it, but never delivers the drop the reorder is committed in, so the // row would snap back to where it came from. const dataTransfer = await page.evaluateHandle(() => new DataTransfer()) + + // The sidebar rail is the same list and reorders the same way. It shows icons and no text, so + // its rows are named by position and the list on the page is where the result is read. + const rail = page.locator(".primary-nav [draggable=true]") + + await rail.nth(0).dispatchEvent("dragstart", {dataTransfer}) + await rail.nth(1).dispatchEvent("drop", {dataTransfer}) + + await expect(joined.first()).toContainText(other.url) + + await rail.nth(1).dispatchEvent("dragstart", {dataTransfer}) + await rail.nth(0).dispatchEvent("drop", {dataTransfer}) + + await expect(joined.first()).toContainText(space.url) + + // Dragging in the page's own list moves the same room list. It goes last because it shows the new + // order the moment it is dropped, ahead of the room list it publishes, so a drag in the rail + // straight afterwards would be working from the order it replaced. const source = joined.filter({hasText: other.url}) const target = joined.filter({hasText: space.url}) diff --git a/src/app/components/PrimaryNavSpaces.svelte b/src/app/components/PrimaryNavSpaces.svelte index dfb97313..4daa17e8 100644 --- a/src/app/components/PrimaryNavSpaces.svelte +++ b/src/app/components/PrimaryNavSpaces.svelte @@ -5,9 +5,10 @@ import Divider from "@lib/components/Divider.svelte" import Tippy from "@lib/components/Tippy.svelte" import PrimaryNavItem from "@lib/components/PrimaryNavItem.svelte" + import DragList from "@lib/components/DragList.svelte" import PrimaryNavItemSpace from "@app/components/PrimaryNavItemSpace.svelte" import PrimaryNavSpacesOverflow from "@app/components/PrimaryNavSpacesOverflow.svelte" - import {userSpaceUrls} from "@app/rooms" + import {reorderSpaceUrls, userSpaceUrls} from "@app/rooms" import {PLATFORM_RELAYS, PLATFORM_LOGO} from "@app/env" import {notifications} from "@app/notifications" import {makeSpacePath} from "@app/routes" @@ -48,9 +49,14 @@ - {#each primarySpaceUrls as url (url)} - - {/each} + + {#snippet item(url)} + + {/snippet} + {#snippet allSpaces(title: string)} $userRoomList?.urls() ?? []) +// Spaces get reordered from lists that show only some of them, so the urls given here go back +// in the slots the ones they replace occupied. +export const reorderSpaceUrls = (urls: string[]) => { + let index = 0 + + const nextUrls = get(userSpaceUrls).map(url => (urls.includes(url) ? urls[index++] : url)) + + return roomLists.get().setRelays(nextUrls).then(publish) +} + // Rooms in the space the user has joined, limited to those the relay still advertises. export const deriveUserRooms = (url: string) => derived( diff --git a/src/lib/components/DragList.svelte b/src/lib/components/DragList.svelte new file mode 100644 index 00000000..40550fa7 --- /dev/null +++ b/src/lib/components/DragList.svelte @@ -0,0 +1,118 @@ + + +
+ {#each order as value (value)} +
onDragStart(e, value)} + ondragover={onDragOver} + ondragenter={e => onDragEnter(e, value)} + ondrop={e => onDrop(e, value)} + ondragend={onDragEnd}> + {@render item(value)} +
+ {/each} +
diff --git a/src/routes/spaces/+page.svelte b/src/routes/spaces/+page.svelte index f4b25706..f3c06502 100644 --- a/src/routes/spaces/+page.svelte +++ b/src/routes/spaces/+page.svelte @@ -1,13 +1,11 @@