fix(手机): 收起键盘后「提交」按钮不回来;比赛领奖台第一名被挤出屏幕;iPhone 点输入框整页放大
- 题目页:安卓按返回键收键盘时编辑器不失焦,符号键一直贴底、「运行例子 / 提交」不回来。 改成看键盘真弹着没有(可视视口变矮),不只看焦点 - 比赛排名:结束后的领奖台三块共 646px,手机上第一名被切掉、第三名看不见;改成平分一行 - iPhone:点 14/15px 的输入框和代码编辑器,Safari 会整页放大且不缩回;只给 iOS 加 maximum-scale=1 - 登录:手机上选完班不再自动聚焦搜索框(键盘弹出来盖住半张名单) - 题单:窄屏上题目拆成两张没标题的卡片,像分了两组;放不下两栏时合成一张 - 「中等」在题目页是蓝色、在题目列表是橙色,统一成橙色 - 零碎:自学四列表格在 360 宽上收窄格子;统计「错得最多的题」表头不再挤成竖排; 「第 N 名」「14 道」不再把最后一个字甩到下一行 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
90ce1ab0f5
commit
a5d5c39411
12 files changed
+177
-28
No files matched your search
@@ -5,7 +5,7 @@ import { useCodeStore } from "oj/store/code"
|
||||
import { useProblemStore } from "oj/store/problem"
|
||||
import { useSubmissionStore } from "oj/store/submission"
|
||||
import SubmitCode from "./SubmitCode.vue"
|
||||
import { editorFocused } from "../utils/symbolKeys"
|
||||
import { typing } from "../utils/symbolKeys"
|
||||
|
||||
const SubmitFlowchart = defineAsyncComponent(() => import("./SubmitFlowchart.vue"))
|
||||
|
||||
@@ -30,8 +30,9 @@ const canRunSamples = computed(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 写代码时(键盘弹着)让位给符号键:两条都贴底会叠在一起,安卓上还会被键盘顶上来 -->
|
||||
<div v-show="!editorFocused" class="mobile-actions">
|
||||
<!-- 写代码时(键盘弹着)让位给符号键:两条都贴底会叠在一起,安卓上还会被键盘顶上来。
|
||||
按返回键收了键盘、编辑器还有焦点时要回来,所以看 typing 不看焦点 -->
|
||||
<div v-show="!typing" class="mobile-actions">
|
||||
<n-button
|
||||
v-if="canRunSamples"
|
||||
size="large"
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { useThemeVars } from "naive-ui"
|
||||
import { useCodeStore } from "oj/store/code"
|
||||
import { editorFocused, SYMBOL_KEYS, typeSymbol } from "../utils/symbolKeys"
|
||||
import {
|
||||
editorFocused,
|
||||
measureKeyboard,
|
||||
SYMBOL_KEYS,
|
||||
typeSymbol,
|
||||
typing,
|
||||
} from "../utils/symbolKeys"
|
||||
|
||||
/**
|
||||
* 手机上贴着键盘顶的一排符号键,编辑器有焦点(键盘弹着)时才出来。
|
||||
@@ -29,9 +35,19 @@ function place() {
|
||||
top.value = viewport ? viewport.offsetTop + viewport.height - BAR_HEIGHT : null
|
||||
}
|
||||
|
||||
useEventListener(() => window.visualViewport, "resize", place)
|
||||
// 键盘弹起之前就得量出「没键盘时多高」,所以挂上就量
|
||||
onMounted(measureKeyboard)
|
||||
useEventListener("resize", measureKeyboard)
|
||||
useEventListener(
|
||||
() => window.visualViewport,
|
||||
"resize",
|
||||
() => {
|
||||
measureKeyboard()
|
||||
place()
|
||||
},
|
||||
)
|
||||
useEventListener(() => window.visualViewport, "scroll", place)
|
||||
watch(editorFocused, (focused) => focused && place(), { immediate: true })
|
||||
watch(typing, (on) => on && place(), { immediate: true })
|
||||
// 键盘弹着时点了别处换题、离开页面,编辑器直接卸载,不一定等得到失焦
|
||||
onBeforeUnmount(() => {
|
||||
editorFocused.value = false
|
||||
@@ -40,7 +56,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="editorFocused && keys.length"
|
||||
v-if="typing && keys.length"
|
||||
class="symbol-keys"
|
||||
:style="top === null ? { bottom: '0px' } : { top: `${top}px` }"
|
||||
role="toolbar"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { insertBracket } from "@codemirror/autocomplete"
|
||||
import { EditorView } from "@codemirror/view"
|
||||
import { ref } from "vue"
|
||||
import { computed, ref } from "vue"
|
||||
import { currentEditorView } from "./errorMark"
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@ import { currentEditorView } from "./errorMark"
|
||||
* 一行 print(int(input())) 来回切七八次。
|
||||
*/
|
||||
|
||||
/** 题目页主编辑器有没有焦点 —— 有焦点就是键盘弹着,这时才摆符号键 */
|
||||
/** 题目页主编辑器有没有焦点 */
|
||||
export const editorFocused = ref(false)
|
||||
|
||||
export const editorFocusTracker = EditorView.focusChangeEffect.of((_state, focusing) => {
|
||||
@@ -16,6 +16,35 @@ export const editorFocusTracker = EditorView.focusChangeEffect.of((_state, focus
|
||||
return null
|
||||
})
|
||||
|
||||
/**
|
||||
* 软键盘是不是弹着。光看焦点不够:安卓按返回键收键盘,编辑器**不失焦**,
|
||||
* 符号键就一直贴在屏幕底下,「运行例子 / 提交」也不回来,学生找不到地方交。
|
||||
*
|
||||
* 键盘弹起时可视视口变矮(iOS 和 Chrome 108+ 布局视口不变;更老的安卓连
|
||||
* innerHeight 一起变矮),所以和这个宽度下见过的最高值比。宽度变了(转屏)重新量。
|
||||
* 乘 scale 是为了双指放大时别误判成键盘弹着。
|
||||
*/
|
||||
const keyboardUp = ref(false)
|
||||
let baseline = 0
|
||||
let baselineWidth = 0
|
||||
|
||||
export function measureKeyboard() {
|
||||
const viewport = window.visualViewport
|
||||
if (!viewport) return
|
||||
if (window.innerWidth !== baselineWidth) {
|
||||
baselineWidth = window.innerWidth
|
||||
baseline = 0
|
||||
}
|
||||
const visible = viewport.height * viewport.scale
|
||||
baseline = Math.max(baseline, window.innerHeight, visible)
|
||||
keyboardUp.value = visible < baseline - 120
|
||||
}
|
||||
|
||||
/** 正在打字:编辑器有焦点、键盘也弹着。这时才摆符号键,底栏让位 */
|
||||
export const typing = computed(
|
||||
() => editorFocused.value && (!window.visualViewport || keyboardUp.value),
|
||||
)
|
||||
|
||||
export interface SymbolKey {
|
||||
label: string
|
||||
/** 插进去的字;不写就是 label */
|
||||
|
||||
Reference in new issue
Block a user