Land on a page of the space after deleting the room you are in

This commit is contained in:
Coracle-Bot 2026-09-10 23:14:52 +00:00
parent e6ce3e5ec8
commit 259091ba64
4 changed files with 55 additions and 4 deletions

View file

@ -305,6 +305,18 @@ Acceptance:
and removes it from the sidebar.
- bob sees neither "Edit Room" nor "Delete Room" in the room's detail menu.
### US-121 — Land somewhere after deleting the room you are in
As admin, I want deleting the room I am reading to put me on a page of the
space, so that I am not stranded on a screen with nothing on it.
Acceptance:
- Confirming the deletion leaves admin on a page below the space root, with the
space's remaining rooms listed beside it.
- Entering the space again from the rail lands on a page, rather than returning
to the room that was deleted or to the empty root.
### US-021 — Request access to a private room and get approved
As carol, I want to ask to join a closed room and be let in, so that I can read

View file

@ -300,6 +300,36 @@ test("US-020 create, edit, and delete a room", async ({seed, as}) => {
await expect(bob.getByRole("button", {name: "Delete Room"})).toHaveCount(0)
})
test("US-121 land somewhere after deleting the room you are in", async ({seed, as}) => {
const scenario = await seed(({relay, user}) => {
const space = relay("space")
space.room("general", {name: "General"})
space.room("wardroom", {name: "Wardroom"})
space.join(user.admin, "general")
space.join(user.admin, "wardroom")
})
const {url} = scenario.space("space")
const admin = await as(users.admin, roomPath(url, "wardroom"))
await openRoomDetail(admin)
await openRoomDetailMenu(admin)
await admin.getByRole("button", {name: "Delete Room"}).click()
await admin.getByRole("button", {name: "Confirm"}).click()
// The space root renders nothing on a wide screen; it hands off to whichever page of the space
// was open last, and the room that was just deleted is the page it remembers.
await expect(admin).toHaveURL(pathPattern(spacePath(url) + "/"))
await expect(roomLink(admin, "General")).toBeVisible()
// Entering the space from the rail reads the same memory, so it has to land somewhere too.
await admin.locator('.primary-nav [data-tip^="space"]').click()
await expect(admin).toHaveURL(pathPattern(spacePath(url) + "/"))
await expect(roomLink(admin, "General")).toBeVisible()
})
test("US-021 request access to a private room and get approved", async ({seed, as}) => {
const scenario = await seed(({relay, user, at}) => {
const space = relay("space")

View file

@ -14,7 +14,7 @@
import {app, roomLists, rooms} from "@app/core"
import {joinRoom, leaveRoom} from "@app/access"
import {deriveUserIsRoomAdmin, deriveUserRoomMembershipStatus} from "@app/rooms"
import {makeSpacePath} from "@app/routes"
import {forgetSpacePage, makeSpacePath} from "@app/routes"
import {navigate, pushModal} from "@app/modal"
import {pushToast} from "@app/toast"
@ -62,6 +62,8 @@
pushToast({theme: "error", message})
} else {
await $roomLists.removeRoom(h, url).then(publish)
forgetSpacePage(url)
navigate(makeSpacePath(url))
}
},

View file

@ -40,8 +40,13 @@ export const lastSpaceUrl = writable<string | undefined>(undefined)
export const setupHistory = () =>
page.subscribe($page => {
if ($page.params.relay) {
lastPageBySpaceUrl.set($page.params.relay, $page.url.pathname)
lastSpaceUrl.set(decodeRelay($page.params.relay))
const url = decodeRelay($page.params.relay)
if ($page.url.pathname !== makeSpacePath(url)) {
lastPageBySpaceUrl.set(url, $page.url.pathname)
}
lastSpaceUrl.set(url)
}
if ($page.params.chat) {
@ -88,8 +93,10 @@ export const makeSpacePath = (url: string, ...extra: (string | undefined)[]) =>
return path
}
export const forgetSpacePage = (url: string) => lastPageBySpaceUrl.delete(url)
export const makeSpaceEntryPath = (url: string) => {
const prevPath = lastPageBySpaceUrl.get(encodeRelay(url))
const prevPath = lastPageBySpaceUrl.get(url)
if (prevPath) {
return prevPath