Files
OJ2/apps/web/src/main.ts
T
xuyueandClaude Opus 5.5 a5d5c39411 fix(手机): 收起键盘后「提交」按钮不回来;比赛领奖台第一名被挤出屏幕;iPhone 点输入框整页放大
- 题目页:安卓按返回键收键盘时编辑器不失焦,符号键一直贴底、「运行例子 / 提交」不回来。
  改成看键盘真弹着没有(可视视口变矮),不只看焦点
- 比赛排名:结束后的领奖台三块共 646px,手机上第一名被切掉、第三名看不见;改成平分一行
- iPhone:点 14/15px 的输入框和代码编辑器,Safari 会整页放大且不缩回;只给 iOS 加 maximum-scale=1
- 登录:手机上选完班不再自动聚焦搜索框(键盘弹出来盖住半张名单)
- 题单:窄屏上题目拆成两张没标题的卡片,像分了两组;放不下两栏时合成一张
- 「中等」在题目页是蓝色、在题目列表是橙色,统一成橙色
- 零碎:自学四列表格在 360 宽上收窄格子;统计「错得最多的题」表头不再挤成竖排;
  「第 N 名」「14 道」不再把最后一个字甩到下一行

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:36:33 +08:00

98 lines
2.8 KiB
TypeScript

import { addAPIProvider } from "@iconify/vue"
import { createPinia } from "pinia"
import { createRouter, createWebHistory } from "vue-router"
import { STORAGE_KEY } from "utils/constants"
import storage from "utils/storage"
import App from "./App.vue"
import { admins, ojs } from "./routes"
/**
* iPhone 上点进字号小于 16px 的输入框(Naive 的输入框是 14px、代码编辑器 15px),
* Safari 会自动把整页放大,而且退出输入也不缩回去,得学生自己双指缩。
* maximum-scale=1 能关掉这个自动放大;iOS 10 起照样允许双指缩放,所以只给 iOS 加 ——
* 安卓上这么写会真的禁掉双指放大,看题面图片、代码就没法放大了。
*/
const isIOS =
/iPhone|iPad|iPod/.test(navigator.userAgent) ||
(navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)
if (isIOS) {
const viewport = document.querySelector('meta[name="viewport"]')
viewport?.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1")
}
const router = createRouter({
history: createWebHistory(),
routes: [ojs, admins],
})
const pinia = createPinia()
// 创建 app 并安装插件
const app = createApp(App)
app.use(pinia)
app.use(router)
// 现在可以安全地使用 Store
import { useAuthModalStore } from "./shared/store/authModal"
import { useUserStore } from "./shared/store/user"
const authStore = useAuthModalStore()
// vue-router 5.4 起 next() 回调已弃用,改成返回值:返回 "/" 就是跳回首页,什么都不返回就是放行
router.beforeEach(async (to) => {
// 检查是否需要认证
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!storage.get(STORAGE_KEY.AUTHED)) {
authStore.openLoginModal()
return "/"
}
}
// 检查权限
if (
to.matched.some(
(record) =>
record.meta.requiresSuperAdmin ||
record.meta.requiresTeacherAdmin ||
record.meta.requiresProblemPermission,
)
) {
if (!storage.get(STORAGE_KEY.AUTHED)) {
authStore.openLoginModal()
return "/"
}
const userStore = useUserStore()
if (!userStore.user) {
try {
await userStore.getMyProfile()
} catch {
return "/"
}
}
if (to.matched.some((record) => record.meta.requiresSuperAdmin)) {
if (!userStore.isSuperAdmin) {
return "/"
}
} else if (to.matched.some((record) => record.meta.requiresTeacherAdmin)) {
if (!userStore.isTeacherOrAbove) {
return "/"
}
} else if (to.matched.some((record) => record.meta.requiresProblemPermission)) {
if (!userStore.hasProblemPermission) {
return "/"
}
}
}
})
app.mount("#app")
if (import.meta.env.PUBLIC_ICONIFY_URL) {
addAPIProvider("", {
resources: [import.meta.env.PUBLIC_ICONIFY_URL],
})
}