Files
stash/stash-web/src/data/view.ts
T
CNWei 6dabeabaf2 refactor: 清理遗留设置模型与无用代码
- 删除 settings 的 sections 与 sidebar 六个旧排序/显隐字段,前后端类型与校验同步
- 删除旧分类模型 types、旧 /api/catalog 客户端、旧路由解析与 settings CRUD
- 删除未使用的 AppProject::initial
- 删除 27 条已无组件的 CSS 规则(159 行)
- 保持现有首页/接口页渲染,cargo test 52 passed
2026-11-03 19:49:04 +08:00

67 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 视图与地址的对应关系:地址栏是唯一的视图状态源。
*
* 控制台是单页应用,但「当前在哪一页」写在 URL 里,所以刷新、收藏、
* 前进后退都不会丢上下文。服务端对应的规则在 `src/server.rs`:
* `/c/**` 没有实体文件时回落到内嵌的 `index.html`,由前端按 pathname 重新出页面。
*
* 路由形状(各段都是业务键,也就是接口 JSON 里的 `id`):
*
* / 首页
* /c/<分区> 分类明细
* /c/<分区>/<分组> 只展示该分组
* /c/<分区>/i/<条目> 条目详情,返回 → 分类明细
* /c/<分区>/<分组>/i/<条目> 条目详情,返回 → 该分组
*
* 条目地址带上它自己所在的分组,URL 才是自解释的:刷新之后点「返回」
* 仍然落回条目所属的分组,而不是去猜一个返回目标。
*
* 这里只做「视图 → 地址」的纯转换,读写 history 的部分在 `AppNext.tsx`。
*/
export type DetailRoute = {
type: 'detail'
categoryId: string
/** 指定后明细页只展示该分组 */
groupId?: string
}
export type ItemRoute = {
type: 'item'
categoryId: string
itemId: string
/**
* 条目所在的分组(应用才有)。
*
* 它只描述「条目在哪」,不描述「从哪来」:返回目标由它推导,
* 这样同一个条目永远只有一个地址,刷新和分享都不会跑偏。
*/
groupId?: string
}
export type View =
| { type: 'home' }
| DetailRoute
| ItemRoute
/** 前端路由前缀;改动这里要同步 `src/server.rs` 的 `SPA_PREFIXES`。 */
const CATEGORY_SEGMENT = 'c'
/** 条目段标记:`/c/<分区>[/<分组>]/i/<条目>` */
const ITEM_MARK = 'i'
/** 把视图转成地址。 */
export function viewPath(view: View): string {
if (view.type === 'home') return '/'
const segments = [CATEGORY_SEGMENT, encodeSegment(view.categoryId)]
if (view.groupId !== undefined) segments.push(encodeSegment(view.groupId))
if (view.type === 'item') segments.push(ITEM_MARK, encodeSegment(view.itemId))
return `/${segments.join('/')}`
}
/** 单个路径段编码:id 里可能带斜杠、空格、中文 */
function encodeSegment(value: string): string {
return encodeURIComponent(value)
}