This commit is contained in:
728
2023-03-05 17:16:09 +08:00
parent 7d8d9567ba
commit ad2736c5b2
5 changed files with 142 additions and 8 deletions

View File

@ -2,7 +2,7 @@ import type { Id } from "../../src/eid/typ.ts"
import type { Pas, PasCode, PreUsr } from "../../src/pra/pos.ts"
import type { DocC, DocU } from "../../src/db.ts"
import type * as Q from "../../src/pra/que.ts"
import { nav, navhash, navpas } from "./nav.ts"
import { nav, navhash, navnid, navpas } from "./nav.ts"
import { bind, main, pas_a, pos, que } from "./template.ts"
import { is_actid, is_nbr, lim_re, req_re } from "../../src/eid/is.ts"
import { utc_medium } from "../../src/ont/utc.ts"
@ -17,6 +17,7 @@ export function pas(
navpas(null)
}
navnid()
main.innerHTML = ""
const t = bind("pas")
@ -82,6 +83,7 @@ export async function usr(
const [rej2, ref2] = [u.rej.length >= req_re, u.ref.length < req_re]
const froze = rej2 && !(nav.pas && (nav.pas.aut || is_sec(nav.pas)))
navnid()
main.innerHTML = ""
const t = bind("usr")
@ -132,13 +134,40 @@ export async function usr(
main.append(t.bind)
}
export function soc(
sid?: number
) {
export type Soc = Omit<NonNullable<Q.Soc>, "unam"> & {
unam: Map<Id["_id"], Id["nam"]>,
}
export async function soc(
sidadm?: number | string
) {
if (navhash(typeof sidadm === "number" ? `s${sidadm}` : `soc${sidadm ?? ""}`)) return
let ss: Q.Soc[]
if (typeof sidadm === "number") {
ss = [await que<Q.Soc>(`soc?sid=${sidadm}`)]
navnid()
} else {
const [a1, a2] = (sidadm ?? "").split("-")
if (a2) {
ss = await que<Q.Soc[]>(`soc?adm2=${a2}`)
navnid("soc", a1, a2)
} else if (a1) {
ss = await que<Q.Soc[]>(`soc?adm1=${a1}`)
navnid("soc", a1)
} else {
ss = await que<Q.Soc[]>(`soc`)
navnid("soc")
}
}
ss = ss.filter(s => s)
if (typeof sidadm === "number" && ss.length === 0) return idn(`s${sidadm}`, "社团")
main.innerHTML = JSON.stringify(ss)
}
export function agd(
aid?: number
aid?: number | string
) {
}
@ -154,6 +183,7 @@ function pre(
nam: "用户" | "社团" | "活动",
) {
if (!nav.pas) return
navnid()
main.innerHTML = ""
const t = bind("pre")
@ -197,6 +227,7 @@ function put(
id: Usr,
) {
if (!nav.pas) return
navnid()
main.innerHTML = ""
const t = bind("put")
@ -259,6 +290,7 @@ function put(
export function idn(
id: string, nam: string
) {
navnid()
main.innerHTML = ""
const t = bind("idn")

View File

@ -1,14 +1,18 @@
// deno-lint-ignore-file no-window-prefix
import type { Pas } from "../../src/pra/pas.ts"
import type { NId } from "../../src/pra/que.ts"
import { adm } from "../../src/ont/adm.ts"
import { pas, soc, usr, agd, wsl, lit, idn } from "./article.ts"
import { pas_a, pos } from "./template.ts"
import { adm1, adm2, pas_a, pos, que } from "./template.ts"
export const nav: {
pas: Pas | null,
hash: string,
nid: NId | null,
} = {
pas: null,
hash: "",
nid: null,
}
export async function navpas(
@ -24,6 +28,67 @@ export async function navpas(
}
}
function tag(
t: HTMLMenuElement,
h?: string,
n?: string,
) {
const l = t.appendChild(document.createElement("li"))
if (h) {
const a = l.appendChild(document.createElement("a"))
a.href = `#${h}`
a.addEventListener("click", () => {
for (const e of a.parentElement!.parentElement!.children) e.classList.remove("active")
a.parentElement!.classList.add("active")
// if (scroll) t.scrollIntoView({ behavior: "smooth" })
})
if (n) a.innerText = n
}
return l
}
function menu(
t: HTMLMenuElement,
[ph, pn]: [string, string],
hn: [string, string][],
) {
t.innerHTML = ""
tag(t)
tag(t, ph, pn).classList.add("active")
for (const [h, n] of hn) tag(t, h, n)
tag(t)
}
export async function navnid(
p?: "soc" | "agd",
a1?: string,
a2?: string,
) {
if (!p) {
adm1.parentElement!.classList.add("none")
adm2.parentElement!.classList.add("none")
return
}
if (!a1) {
nav.nid = await que<NId>("nid")
const admn = p === "soc" ? nav.nid!.adm1nsid : nav.nid!.adm1naid
menu(adm1, [p, "全部"], admn.map(([a, n]) => [`${p}${a}`, `${a} (${n})`]))
adm1.parentElement!.classList.remove("none")
adm2.parentElement!.classList.add("none")
} else if (!nav.nid) return
else if (!a2) {
const a2 = adm.get(a1)!
const admn = (p === "soc" ? nav.nid.adm2nsid : nav.nid.adm2naid)
.filter(an => a2.includes(an[0]))
menu(adm2, [`${p}${a1}`, "全部"], admn.map(([a, n]) => [`${p}${a1}-${a}`, `${a} (${n})`]))
adm1.parentElement!.classList.remove("none")
adm2.parentElement!.classList.remove("none")
} else {
adm1.parentElement!.classList.remove("none")
adm2.parentElement!.classList.remove("none")
}
}
export function navhash(
h: string
): boolean {
@ -37,8 +102,10 @@ window.addEventListener("hashchange", () => {
if (nav.hash === "pas") pas()
else if (/^\d+$/.test(nav.hash)) usr(parseInt(nav.hash))
else if (nav.hash === "soc") soc()
else if (nav.hash.startsWith("soc")) soc(nav.hash.substring(3))
else if (/^s\d+$/.test(nav.hash)) soc(parseInt(nav.hash.substring(1)))
else if (nav.hash === "" || nav.hash === "agd") agd()
else if (nav.hash.startsWith("agd")) agd(nav.hash.substring(3))
else if (/^a\d+$/.test(nav.hash)) agd(parseInt(nav.hash.substring(1)))
else if (nav.hash === "wsl") wsl()
else if (nav.hash === "lit") lit()

View File

@ -1,9 +1,11 @@
import type { Pos } from "../../src/pra/pos.ts"
export const utc_refresh = 500
export const utc_refresh = 750
export let utc_etag = Date.now()
export const main = document.getElementById("main")! as HTMLDivElement
export const pas_a = document.getElementById("pas_a")! as HTMLAnchorElement
export const adm1 = document.getElementById("adm1")! as HTMLMenuElement
export const adm2 = document.getElementById("adm2")! as HTMLMenuElement
export async function que<T>(
q: string

View File

@ -25,6 +25,15 @@
<li><a id="pas_a" href="#pas">用户登录</a></li>
</menu>
</nav>
<hr>
<nav class="adm none">
<menu id="adm1"></menu>
</nav>
<hr>
<nav class="adm none">
<menu id="adm2"></menu>
</nav>
<hr>
<div id="main"></div>
</body>
@ -34,7 +43,7 @@
) {
for (const e of t.parentElement.parentElement.children) e.classList.remove("active")
t.parentElement.classList.add("active")
if (scroll) t.scrollIntoView({ behavior: "smooth" })
// if (scroll) t.scrollIntoView({ behavior: "smooth" })
}
for (const n of document.getElementsByTagName("nav")) n.addEventListener("wheel", e => {
if (e.deltaX != 0) return

View File

@ -71,6 +71,12 @@ button:focus {
outline: none;
}
nav {
overflow: scroll;
scrollbar-width: none;
scroll-snap-type: x mandatory;
}
nav::-webkit-scrollbar {
display: none;
}
@ -538,6 +544,18 @@ nav.main li.active>a>em {
color: var(--red);
}
nav.adm a {
padding: 0px 12px;
border-radius: 16px;
border: 1px solid var(--darkgray);
color: var(--darkgray);
}
nav.adm li.active>a {
color: var(--lightgray);
background: var(--darkgray);
}
@media (hover: hover) {
nav.main a:hover {
color: var(--black);
@ -547,4 +565,10 @@ nav.main li.active>a>em {
nav.main a:hover>em {
color: var(--red);
}
nav.adm a:hover {
color: var(--lightgray);
background: var(--darkgray);
opacity: 0.65;
}
}