feat(SPA): media page T0
This commit is contained in:
1 parent
0d99544579
commit
67d456baf6
32 files changed
+4874
-40
No files matched your search
@@ -0,0 +1,69 @@
|
||||
import type { LocationQuery } from 'vue-router'
|
||||
|
||||
export type MediaFilter = 'all' | 'unused'
|
||||
export type MediaSort = 'newest' | 'oldest' | 'name' | 'largest'
|
||||
export type MediaView = 'grid' | 'list'
|
||||
|
||||
export interface MediaControls {
|
||||
q: string
|
||||
filter: MediaFilter
|
||||
sort: MediaSort
|
||||
view: MediaView
|
||||
}
|
||||
|
||||
export const MEDIA_PAGE_LIMIT = 100
|
||||
|
||||
export const DEFAULT_CONTROLS: MediaControls = {
|
||||
q: '',
|
||||
filter: 'all',
|
||||
sort: 'newest',
|
||||
view: 'grid',
|
||||
}
|
||||
|
||||
const FILTERS: MediaFilter[] = ['all', 'unused']
|
||||
const SORTS: MediaSort[] = ['newest', 'oldest', 'name', 'largest']
|
||||
const VIEWS: MediaView[] = ['grid', 'list']
|
||||
|
||||
function firstValue(value: LocationQuery[string] | undefined) {
|
||||
return (Array.isArray(value) ? value[0] : value) ?? ''
|
||||
}
|
||||
|
||||
function pick<T extends string>(allowed: T[], value: string, fallback: T) {
|
||||
return (allowed as string[]).includes(value) ? (value as T) : fallback
|
||||
}
|
||||
|
||||
export function parseMediaControls(query: LocationQuery): MediaControls {
|
||||
return {
|
||||
q: firstValue(query.q).trim(),
|
||||
filter: pick(FILTERS, firstValue(query.filter), DEFAULT_CONTROLS.filter),
|
||||
sort: pick(SORTS, firstValue(query.sort), DEFAULT_CONTROLS.sort),
|
||||
view: pick(VIEWS, firstValue(query.view), DEFAULT_CONTROLS.view),
|
||||
}
|
||||
}
|
||||
|
||||
export function toRouteQuery(controls: MediaControls) {
|
||||
const query: Record<string, string> = {}
|
||||
if (controls.q) {
|
||||
query.q = controls.q
|
||||
}
|
||||
if (controls.filter !== DEFAULT_CONTROLS.filter) {
|
||||
query.filter = controls.filter
|
||||
}
|
||||
if (controls.sort !== DEFAULT_CONTROLS.sort) {
|
||||
query.sort = controls.sort
|
||||
}
|
||||
if (controls.view !== DEFAULT_CONTROLS.view) {
|
||||
query.view = controls.view
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
export function toRequestQuery(controls: MediaControls) {
|
||||
const parts = [
|
||||
...(controls.q ? [`q=${encodeURIComponent(controls.q)}`] : []),
|
||||
`filter=${controls.filter}`,
|
||||
`sort=${controls.sort}`,
|
||||
`limit=${MEDIA_PAGE_LIMIT}`,
|
||||
]
|
||||
return parts.join('&')
|
||||
}
|
||||
Reference in new issue
Block a user