fix(自学): 手机上代码折行看着像另起了一行,改回整行横着滑
正文的代码块、填空、排序、找错四处都不折行了,和桌面一样。排序和找错是整组一起滑, 每行卡片一样宽(= 最长那行)。题目页编辑器的折行不动。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
18b11e3730
commit
395be1a19b
5 files changed
+65
-96
No files matched your search
@@ -10,8 +10,6 @@ import { explainRuntimeError } from "oj/problem/utils/runtimeError"
|
||||
import { useAuthModalStore } from "shared/store/authModal"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
import { mainWrapExtensions, wrapMain } from "../wrapMain"
|
||||
import { hangWrapExtensions } from "shared/extensions/hangIndent"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
|
||||
const CodeEditor = defineAsyncComponent(() => import("shared/components/CodeEditor.vue"))
|
||||
|
||||
@@ -37,12 +35,8 @@ const message = useMessage()
|
||||
const { copy } = useClipboard({ legacy: true })
|
||||
|
||||
const original = computed(() => (props.wrapMain ? wrapMain(props.code) : props.code))
|
||||
const { isDesktop } = useBreakpoints()
|
||||
// 手机上折行(见 hangIndent.ts);桌面正文 720 宽,长行少,照旧横着滚
|
||||
const extensions = computed(() => [
|
||||
...(props.wrapMain ? mainWrapExtensions : []),
|
||||
...(isDesktop.value ? [] : hangWrapExtensions),
|
||||
])
|
||||
// 手机上也不折行,长行横着滚:折下来的那截看着像另起了一行代码
|
||||
const extensions = computed(() => (props.wrapMain ? mainWrapExtensions : []))
|
||||
const value = ref(original.value)
|
||||
const input = ref("")
|
||||
const running = ref(false)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import ExerciseResult from "./ExerciseResult.vue"
|
||||
import type { Exercise, ExerciseDebugData } from "utils/types"
|
||||
import { highlightLines } from "shared/highlight"
|
||||
import { hangStyle } from "shared/extensions/hangIndent"
|
||||
|
||||
const props = defineProps<{ exercise: Exercise; lang?: string }>()
|
||||
const emit = defineEmits<{
|
||||
@@ -92,19 +91,19 @@ function reset() {
|
||||
点击你认为有错误的代码行(可多选)。
|
||||
</p>
|
||||
|
||||
<n-space vertical :size="6">
|
||||
<!-- 不折行:长行整组一起横着滚,每行一样宽(= 最长那行),和正文的代码块一样 -->
|
||||
<div style="overflow-x: auto">
|
||||
<div
|
||||
v-for="(line, idx) in data.lines"
|
||||
:key="idx"
|
||||
:style="lineStyle(idx)"
|
||||
@click="toggle(idx)"
|
||||
style="display: flex; flex-direction: column; gap: 6px; width: max-content; min-width: 100%"
|
||||
>
|
||||
<span style="color: #bbb; width: 22px; text-align: right; flex-shrink: 0">
|
||||
{{ idx + 1 }}
|
||||
</span>
|
||||
<span v-html="lineHtml[idx]" :style="{ minWidth: 0, ...hangStyle(line) }" />
|
||||
<div v-for="(_, idx) in data.lines" :key="idx" :style="lineStyle(idx)" @click="toggle(idx)">
|
||||
<span style="color: #bbb; width: 22px; text-align: right; flex-shrink: 0">
|
||||
{{ idx + 1 }}
|
||||
</span>
|
||||
<span v-html="lineHtml[idx]" style="white-space: pre" />
|
||||
</div>
|
||||
</div>
|
||||
</n-space>
|
||||
</div>
|
||||
|
||||
<ExerciseResult
|
||||
v-if="submitted"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import ExerciseResult from "./ExerciseResult.vue"
|
||||
import type { Exercise, ExerciseFillData } from "utils/types"
|
||||
import { highlightWithHoles } from "shared/highlight"
|
||||
import { hangStyle } from "shared/extensions/hangIndent"
|
||||
|
||||
const props = defineProps<{ exercise: Exercise; lang?: string }>()
|
||||
const emit = defineEmits<{
|
||||
@@ -39,28 +38,21 @@ const segments = computed<Segment[]>(() => {
|
||||
})
|
||||
|
||||
/**
|
||||
* 按行切开,每行自己折行、悬挂缩进(见 hangIndent.ts)。原来整段 pre-wrap,
|
||||
* 手机上行尾的注释折下来顶格,看着像另起了一行代码。
|
||||
* 按行切开,一行一个块;不折行,长行整块横着滚(和正文的代码块一样)。
|
||||
* 高亮的 HTML 在换行处是断开的(见 shared/highlight.ts 的 walk),按 "\n" 切不会切坏标签。
|
||||
*/
|
||||
const lines = computed(() => {
|
||||
const rows: { indent: string; parts: Segment[] }[] = [{ indent: "", parts: [] }]
|
||||
const rows: { parts: Segment[] }[] = [{ parts: [] }]
|
||||
for (const seg of segments.value) {
|
||||
if (seg.type === "blank") {
|
||||
rows[rows.length - 1].parts.push(seg)
|
||||
continue
|
||||
}
|
||||
seg.html.split("\n").forEach((html, i) => {
|
||||
if (i > 0) rows.push({ indent: "", parts: [] })
|
||||
if (i > 0) rows.push({ parts: [] })
|
||||
if (html) rows[rows.length - 1].parts.push({ type: "code", html })
|
||||
})
|
||||
}
|
||||
for (const row of rows) {
|
||||
const first = row.parts[0]
|
||||
if (first?.type === "code") {
|
||||
row.indent = first.html.replace(/<[^>]*>/g, "").match(/^[ \t]*/)![0]
|
||||
}
|
||||
}
|
||||
return rows
|
||||
})
|
||||
|
||||
@@ -114,13 +106,10 @@ function inputWidth(idx: number): string {
|
||||
border: '1px solid var(--learn-line)',
|
||||
borderRadius: '6px',
|
||||
padding: '10px 12px',
|
||||
overflowX: 'auto',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="(row, r) in lines"
|
||||
:key="r"
|
||||
:style="{ minHeight: '1.9em', ...hangStyle(row.indent) }"
|
||||
>
|
||||
<div v-for="(row, r) in lines" :key="r" style="min-height: 1.9em; white-space: pre">
|
||||
<template v-for="(seg, i) in row.parts" :key="i"
|
||||
><span v-if="seg.type === 'code'" v-html="seg.html" /><input
|
||||
v-else
|
||||
@@ -136,7 +125,6 @@ function inputWidth(idx: number): string {
|
||||
fontSize: '16px',
|
||||
lineHeight: '1.4',
|
||||
padding: '2px 6px',
|
||||
textIndent: 0,
|
||||
borderRadius: '4px',
|
||||
border: `1.5px solid ${
|
||||
allCorrect
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { Exercise, ExerciseSortData } from "utils/types"
|
||||
import { shuffle } from "../composables/useShuffle"
|
||||
import { highlightLines } from "shared/highlight"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import { hangStyle } from "shared/extensions/hangIndent"
|
||||
|
||||
const props = defineProps<{ exercise: Exercise; lang?: string }>()
|
||||
const emit = defineEmits<{
|
||||
@@ -100,51 +99,53 @@ const lineHtml = computed<string[]>(() => highlightLines(data.value.lines, props
|
||||
先点一行,再点它该去的位置。
|
||||
</p>
|
||||
|
||||
<n-space vertical :size="6">
|
||||
<!-- 不折行:长行整组一起横着滚,每行一样宽(= 最长那行),和正文的代码块一样 -->
|
||||
<div style="overflow-x: auto">
|
||||
<div
|
||||
v-for="(line, idx) in lines"
|
||||
:key="line.originalIdx"
|
||||
draggable="true"
|
||||
:style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '8px 12px',
|
||||
borderRadius: '6px',
|
||||
border:
|
||||
pickedIdx === idx
|
||||
? '2px solid #2080f0'
|
||||
: `1.5px ${submitted ? 'solid' : 'dashed'} ${
|
||||
lineStatus(idx) === 'correct'
|
||||
? '#18a058'
|
||||
: lineStatus(idx) === 'wrong'
|
||||
? '#d03050'
|
||||
: 'var(--learn-control-line)'
|
||||
}`,
|
||||
background:
|
||||
pickedIdx === idx
|
||||
? 'rgba(32,128,240,0.08)'
|
||||
: lineStatus(idx) === 'correct'
|
||||
? 'rgba(24,160,88,0.08)'
|
||||
: lineStatus(idx) === 'wrong'
|
||||
? 'rgba(208,48,80,0.07)'
|
||||
: 'transparent',
|
||||
cursor: 'grab',
|
||||
fontFamily: 'var(--learn-code-font)',
|
||||
userSelect: 'none',
|
||||
}"
|
||||
@dragstart="onDragStart(idx)"
|
||||
@dragover.prevent
|
||||
@drop="onDrop(idx)"
|
||||
@click="onLineClick(idx)"
|
||||
style="display: flex; flex-direction: column; gap: 6px; width: max-content; min-width: 100%"
|
||||
>
|
||||
<span style="color: #bbb; cursor: grab">⠿</span>
|
||||
<span
|
||||
v-html="lineHtml[line.originalIdx]"
|
||||
:style="{ minWidth: 0, ...hangStyle(line.text) }"
|
||||
/>
|
||||
<div
|
||||
v-for="(line, idx) in lines"
|
||||
:key="line.originalIdx"
|
||||
draggable="true"
|
||||
:style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '8px 12px',
|
||||
borderRadius: '6px',
|
||||
border:
|
||||
pickedIdx === idx
|
||||
? '2px solid #2080f0'
|
||||
: `1.5px ${submitted ? 'solid' : 'dashed'} ${
|
||||
lineStatus(idx) === 'correct'
|
||||
? '#18a058'
|
||||
: lineStatus(idx) === 'wrong'
|
||||
? '#d03050'
|
||||
: 'var(--learn-control-line)'
|
||||
}`,
|
||||
background:
|
||||
pickedIdx === idx
|
||||
? 'rgba(32,128,240,0.08)'
|
||||
: lineStatus(idx) === 'correct'
|
||||
? 'rgba(24,160,88,0.08)'
|
||||
: lineStatus(idx) === 'wrong'
|
||||
? 'rgba(208,48,80,0.07)'
|
||||
: 'transparent',
|
||||
cursor: 'grab',
|
||||
fontFamily: 'var(--learn-code-font)',
|
||||
userSelect: 'none',
|
||||
}"
|
||||
@dragstart="onDragStart(idx)"
|
||||
@dragover.prevent
|
||||
@drop="onDrop(idx)"
|
||||
@click="onLineClick(idx)"
|
||||
>
|
||||
<span style="color: #bbb; cursor: grab">⠿</span>
|
||||
<span v-html="lineHtml[line.originalIdx]" style="white-space: pre" />
|
||||
</div>
|
||||
</div>
|
||||
</n-space>
|
||||
</div>
|
||||
|
||||
<ExerciseResult
|
||||
v-if="submitted"
|
||||
|
||||
Reference in new issue
Block a user