feat(排名): 个性签名直接写在名单上,不用再指着小引号才看得到
- 桌面:写了签名的同学名字下面多一行,把签名写出来(一行二十来个字,长的指上去看全文);两栏按高度对半分 - 手机:签名从名字后面(只剩三五个字)挪到名字下面一行 - 自己还没写的,名单里自己那行有「写一句个性签名」,和「你」卡点开的是同一个框 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e946c99fb
commit
28a09831b5
4 files changed
+283
-177
No files matched your search
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import { MOOD_MAX } from "@oj2/contract"
|
||||
import { updateProfile } from "oj/api"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
|
||||
/**
|
||||
* 就地改个性签名:「你」卡上的签名、赛道里自己那行的「写一句个性签名」点开的是同一个框。
|
||||
* 触发按钮由调用方放进默认插槽。
|
||||
*/
|
||||
const props = defineProps<{ mood: string | null }>()
|
||||
const emit = defineEmits<{ saved: [mood: string | null] }>()
|
||||
|
||||
const message = useMessage()
|
||||
const userStore = useUserStore()
|
||||
const inputId = useId()
|
||||
|
||||
const editing = ref(false)
|
||||
const draft = ref("")
|
||||
const saving = ref(false)
|
||||
|
||||
watch(editing, (open) => {
|
||||
if (open) draft.value = props.mood ?? ""
|
||||
})
|
||||
|
||||
async function save() {
|
||||
const mood = draft.value.trim()
|
||||
if (mood.length > MOOD_MAX) {
|
||||
message.warning(`个性签名最多 ${MOOD_MAX} 个字`)
|
||||
return
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
await updateProfile({ mood })
|
||||
if (userStore.profile) userStore.profile.mood = mood || null
|
||||
emit("saved", mood || null)
|
||||
editing.value = false
|
||||
message.success(mood ? "签名改好了" : "签名清空了")
|
||||
} catch {
|
||||
message.error("没保存上,再试一次")
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-popover
|
||||
v-model:show="editing"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
:style="{ width: '300px' }"
|
||||
>
|
||||
<template #trigger>
|
||||
<slot />
|
||||
</template>
|
||||
<form class="mood-form" @submit.prevent="save">
|
||||
<label class="mood-label" :for="inputId">个性签名</label>
|
||||
<n-input
|
||||
v-model:value="draft"
|
||||
:input-props="{ id: inputId }"
|
||||
:maxlength="MOOD_MAX"
|
||||
show-count
|
||||
clearable
|
||||
placeholder="写点什么,让大家认识你"
|
||||
autofocus
|
||||
/>
|
||||
<div class="mood-actions">
|
||||
<n-button size="small" @click="editing = false">取消</n-button>
|
||||
<n-button size="small" type="primary" attr-type="submit" :loading="saving"> 保存 </n-button>
|
||||
</div>
|
||||
</form>
|
||||
</n-popover>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.mood-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.mood-label {
|
||||
font-size: var(--oj-fs-sec);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mood-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,10 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { MOOD_MAX, type RankRow } from "@oj2/contract"
|
||||
import type { RankRow } from "@oj2/contract"
|
||||
import { useThemeVars } from "naive-ui"
|
||||
import { updateProfile } from "oj/api"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
import UserName from "shared/components/UserName.vue"
|
||||
import { gapText, toPass } from "../utils"
|
||||
import MoodPopover from "./MoodPopover.vue"
|
||||
import RankAvatar from "./RankAvatar.vue"
|
||||
|
||||
export interface MiniRank {
|
||||
@@ -23,7 +22,7 @@ export interface MiniRank {
|
||||
* 用词只说位置(前一名 / 后一名 / 进步最大),不用「追」「对手」「冲」:用户指出
|
||||
* 「要追的」「追你」会被中学生读成追求谁,「冲得最猛」也容易误会。
|
||||
*
|
||||
* 个性签名(设计稿「签名 A」):自己的签名挂在大字下面,「改」就地改,不用跳去设置页;
|
||||
* 个性签名:自己的签名挂在大字下面,「改」就地改,不用跳去设置页;
|
||||
* 没写的给一句「写一句个性签名」。前一名、后一名的签名挂在他们名字下面。
|
||||
*/
|
||||
const props = defineProps<{
|
||||
@@ -45,36 +44,6 @@ const props = defineProps<{
|
||||
const emit = defineEmits<{ moodSaved: [mood: string | null] }>()
|
||||
|
||||
const theme = useThemeVars()
|
||||
const message = useMessage()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const editing = ref(false)
|
||||
const draft = ref("")
|
||||
const saving = ref(false)
|
||||
|
||||
watch(editing, (open) => {
|
||||
if (open) draft.value = props.me.mood ?? ""
|
||||
})
|
||||
|
||||
async function saveMood() {
|
||||
const mood = draft.value.trim()
|
||||
if (mood.length > MOOD_MAX) {
|
||||
message.warning(`个性签名最多 ${MOOD_MAX} 个字`)
|
||||
return
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
await updateProfile({ mood })
|
||||
if (userStore.profile) userStore.profile.mood = mood || null
|
||||
emit("moodSaved", mood || null)
|
||||
editing.value = false
|
||||
message.success(mood ? "签名改好了" : "签名清空了")
|
||||
} catch {
|
||||
message.error("没保存上,再试一次")
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const beyond = computed(() => !!props.cap && props.me.rank > props.cap)
|
||||
|
||||
@@ -126,37 +95,14 @@ function threatNote(me: RankRow, behind: RankRow) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<n-popover
|
||||
v-model:show="editing"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
:style="{ width: '300px' }"
|
||||
>
|
||||
<template #trigger>
|
||||
<button v-if="me.mood" class="mood" aria-label="改个性签名">
|
||||
<span class="quote-mark" aria-hidden="true">“</span>
|
||||
<n-ellipsis class="mood-text" :line-clamp="2" :tooltip="false">{{ me.mood }}</n-ellipsis>
|
||||
<span class="mood-edit">
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M4 20h4L19 9l-4-4L4 16z" />
|
||||
</svg>
|
||||
改
|
||||
</span>
|
||||
</button>
|
||||
<button v-else class="mood empty">
|
||||
<MoodPopover :mood="me.mood" @saved="emit('moodSaved', $event)">
|
||||
<button v-if="me.mood" class="mood" aria-label="改个性签名">
|
||||
<span class="quote-mark" aria-hidden="true">“</span>
|
||||
<n-ellipsis class="mood-text" :line-clamp="2" :tooltip="false">{{ me.mood }}</n-ellipsis>
|
||||
<span class="mood-edit">
|
||||
<svg
|
||||
width="13"
|
||||
height="13"
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
@@ -167,28 +113,26 @@ function threatNote(me: RankRow, behind: RankRow) {
|
||||
>
|
||||
<path d="M4 20h4L19 9l-4-4L4 16z" />
|
||||
</svg>
|
||||
写一句个性签名,上了领奖台全班都看得到
|
||||
</button>
|
||||
</template>
|
||||
<form class="mood-form" @submit.prevent="saveMood">
|
||||
<label class="mood-label" for="rank-mood-input">个性签名</label>
|
||||
<n-input
|
||||
v-model:value="draft"
|
||||
:input-props="{ id: 'rank-mood-input' }"
|
||||
:maxlength="MOOD_MAX"
|
||||
show-count
|
||||
clearable
|
||||
placeholder="写点什么,让大家认识你"
|
||||
autofocus
|
||||
/>
|
||||
<div class="mood-actions">
|
||||
<n-button size="small" @click="editing = false">取消</n-button>
|
||||
<n-button size="small" type="primary" attr-type="submit" :loading="saving">
|
||||
保存
|
||||
</n-button>
|
||||
</div>
|
||||
</form>
|
||||
</n-popover>
|
||||
改
|
||||
</span>
|
||||
</button>
|
||||
<button v-else class="mood empty">
|
||||
<svg
|
||||
width="13"
|
||||
height="13"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M4 20h4L19 9l-4-4L4 16z" />
|
||||
</svg>
|
||||
写一句个性签名,全班都看得到
|
||||
</button>
|
||||
</MoodPopover>
|
||||
<div v-if="headline" class="headline">
|
||||
<svg
|
||||
width="18"
|
||||
@@ -427,23 +371,6 @@ function threatNote(me: RankRow, behind: RankRow) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mood-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.mood-label {
|
||||
font-size: var(--oj-fs-sec);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mood-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.rival-name {
|
||||
flex-shrink: 0;
|
||||
max-width: 120px;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useThemeVars, type DropdownOption } from "naive-ui"
|
||||
import UserName from "shared/components/UserName.vue"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import { useRankPalette } from "../palette"
|
||||
import MoodPopover from "./MoodPopover.vue"
|
||||
import RankAvatar from "./RankAvatar.vue"
|
||||
|
||||
/**
|
||||
@@ -19,8 +20,10 @@ import RankAvatar from "./RankAvatar.vue"
|
||||
* 桌面的条只有百来像素(老师那边多一个「⋯」,七十来像素),压不下文字标签:「前一名」
|
||||
* 「后一名」靠条的颜色认(和右边「你」卡里两个标签同色),「进步最大」改成涨跌那一格的橙底徽章。手机每行有空,标签照旧。
|
||||
*
|
||||
* 个性签名(设计稿「签名 A」):桌面一行只有一百来像素的条,放不下一句话,所以有签名的
|
||||
* 名字后面挂一个引号,指上去看;手机每行本来就有空,签名直接写在名字后面。
|
||||
* 个性签名(设计稿「签名直接写在赛道上」T1):写了签名的人名字下面多一行,直接写出来,
|
||||
* 不再藏在引号后面指上去才看得到(用户:排名上看不出签名)。桌面这一行从名字底下一直伸到
|
||||
* 本栏末尾,能露二十多个字;手机挪到名字下面一行。你还没写的话,你那行(桌面)挂一个
|
||||
* 「写一句个性签名」,和「你」卡点开的是同一个框。
|
||||
*/
|
||||
const props = defineProps<{
|
||||
rows: RankRow[]
|
||||
@@ -48,6 +51,7 @@ const emit = defineEmits<{
|
||||
analysis: [username: string]
|
||||
hide: [row: RankRow]
|
||||
clearMood: [row: RankRow]
|
||||
moodSaved: [mood: string | null]
|
||||
}>()
|
||||
|
||||
const theme = useThemeVars()
|
||||
@@ -109,11 +113,31 @@ function expandGap() {
|
||||
if (!props.complete) emit("expand")
|
||||
}
|
||||
|
||||
/** 两栏:前一半、后一半。手机一栏 */
|
||||
/** 桌面每一项大约多高:带签名(或「写一句」)的行多一行,两栏按高度对半分,不按人数 */
|
||||
function heightOf(item: Item) {
|
||||
if (item.kind === "gap") return 48
|
||||
return hasSecondLine(item.row) ? 56 : 36
|
||||
}
|
||||
|
||||
function hasSecondLine(row: RankRow) {
|
||||
return !!row.mood || row.user.id === props.meId
|
||||
}
|
||||
|
||||
/** 两栏:前一半、后一半(按高度)。手机一栏 */
|
||||
const columns = computed(() => {
|
||||
if (!isDesktop.value) return [items.value]
|
||||
const half = Math.ceil(items.value.length / 2)
|
||||
return [items.value.slice(0, half), items.value.slice(half)]
|
||||
const total = items.value.reduce((sum, item) => sum + heightOf(item), 0)
|
||||
let acc = 0
|
||||
let cut = items.value.length
|
||||
for (const [index, item] of items.value.entries()) {
|
||||
const h = heightOf(item)
|
||||
if (acc + h / 2 > total / 2) {
|
||||
cut = index
|
||||
break
|
||||
}
|
||||
acc += h
|
||||
}
|
||||
return [items.value.slice(0, cut), items.value.slice(cut)]
|
||||
})
|
||||
|
||||
function barColor(row: RankRow) {
|
||||
@@ -175,7 +199,7 @@ function onMenu(key: string, row: RankRow) {
|
||||
<div
|
||||
v-else-if="!isDesktop"
|
||||
class="prow"
|
||||
:class="{ me: item.row.user.id === meId, zero: !item.row.solved }"
|
||||
:class="{ me: item.row.user.id === meId, zero: !item.row.solved, tall: !!item.row.mood }"
|
||||
>
|
||||
<span class="fill" :style="{ width: width(item.row), background: fillColor(item.row) }" />
|
||||
<span class="rank">{{ item.row.solved ? item.row.rank : "—" }}</span>
|
||||
@@ -185,13 +209,17 @@ function onMenu(key: string, row: RankRow) {
|
||||
:size="20"
|
||||
:me="item.row.user.id === meId"
|
||||
/>
|
||||
<button class="who" @click="emit('open', item.row.user.username)">
|
||||
<UserName :username="item.row.user.username" />
|
||||
</button>
|
||||
<span class="mood">{{ item.row.mood }}</span>
|
||||
<span v-if="item.row.user.id === chaseId" class="tag chase">前一名</span>
|
||||
<span v-else-if="item.row.user.id === threatId" class="tag threat">后一名</span>
|
||||
<span v-else-if="item.row.user.id === hotId" class="tag hot">进步最大</span>
|
||||
<div class="pmain">
|
||||
<div class="pname">
|
||||
<button class="who" @click="emit('open', item.row.user.username)">
|
||||
<UserName :username="item.row.user.username" />
|
||||
</button>
|
||||
<span v-if="item.row.user.id === chaseId" class="tag chase">前一名</span>
|
||||
<span v-else-if="item.row.user.id === threatId" class="tag threat">后一名</span>
|
||||
<span v-else-if="item.row.user.id === hotId" class="tag hot">进步最大</span>
|
||||
</div>
|
||||
<span v-if="item.row.mood" class="sig">“{{ item.row.mood }}”</span>
|
||||
</div>
|
||||
<span class="solved">{{ item.row.solved }}</span>
|
||||
<span class="change">
|
||||
<span v-if="(item.row.change ?? 0) > 0" class="up">↑{{ item.row.change }}</span>
|
||||
@@ -209,58 +237,73 @@ function onMenu(key: string, row: RankRow) {
|
||||
<button class="more" aria-label="更多">⋯</button>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
<div v-else class="lane" :class="{ me: item.row.user.id === meId, zero: !item.row.solved }">
|
||||
<span class="rank">{{ item.row.solved ? item.row.rank : "—" }}</span>
|
||||
<RankAvatar
|
||||
:username="item.row.user.username"
|
||||
:avatar="item.row.avatar"
|
||||
:size="20"
|
||||
:me="item.row.user.id === meId"
|
||||
/>
|
||||
<n-tooltip :disabled="!item.row.mood" :style="{ maxWidth: '300px' }">
|
||||
<template #trigger>
|
||||
<button class="who" @click="emit('open', item.row.user.username)">
|
||||
<UserName :username="item.row.user.username" />
|
||||
<div
|
||||
v-else
|
||||
class="entry"
|
||||
:class="{ me: item.row.user.id === meId, zero: !item.row.solved }"
|
||||
>
|
||||
<div class="lane">
|
||||
<span class="rank">{{ item.row.solved ? item.row.rank : "—" }}</span>
|
||||
<RankAvatar
|
||||
:username="item.row.user.username"
|
||||
:avatar="item.row.avatar"
|
||||
:size="20"
|
||||
:me="item.row.user.id === meId"
|
||||
/>
|
||||
<button class="who" @click="emit('open', item.row.user.username)">
|
||||
<UserName :username="item.row.user.username" />
|
||||
</button>
|
||||
<span class="bar-box" :style="{ background: palette.track }">
|
||||
<span
|
||||
class="bar"
|
||||
:style="{ width: width(item.row), background: barColor(item.row) }"
|
||||
/>
|
||||
</span>
|
||||
<span class="solved">{{ item.row.solved }}</span>
|
||||
<span class="change">
|
||||
<span v-if="item.row.user.id === hotId" class="up hot" title="进步最大"
|
||||
>↑{{ item.row.change }}</span
|
||||
>
|
||||
<span v-else-if="(item.row.change ?? 0) > 0" class="up">↑{{ item.row.change }}</span>
|
||||
<span v-else-if="(item.row.change ?? 0) < 0" class="down"
|
||||
>↓{{ -item.row.change! }}</span
|
||||
>
|
||||
<span v-else-if="item.row.change === 0" class="flat">—</span>
|
||||
</span>
|
||||
<n-dropdown
|
||||
v-if="teacher"
|
||||
trigger="click"
|
||||
:options="menuOf(item.row)"
|
||||
@select="(key: string) => onMenu(key, item.row)"
|
||||
>
|
||||
<button class="more" aria-label="更多">⋯</button>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
<div v-if="item.row.mood" class="sig line">
|
||||
<n-ellipsis :tooltip="{ contentStyle: { maxWidth: '300px' } }"
|
||||
>“{{ item.row.mood }}”</n-ellipsis
|
||||
>
|
||||
</div>
|
||||
<div v-else-if="item.row.user.id === meId" class="line">
|
||||
<MoodPopover :mood="null" @saved="emit('moodSaved', $event)">
|
||||
<button class="write">
|
||||
<svg
|
||||
v-if="item.row.mood"
|
||||
class="quote"
|
||||
width="11"
|
||||
height="11"
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
role="img"
|
||||
aria-label="有个性签名"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M4 18v-5c0-4 2-7 6-8l1 2c-2 1-3 2.5-3 4h3v7zm9 0v-5c0-4 2-7 6-8l1 2c-2 1-3 2.5-3 4h3v7z"
|
||||
/>
|
||||
<path d="M4 20h4L19 9l-4-4L4 16z" />
|
||||
</svg>
|
||||
写一句个性签名
|
||||
</button>
|
||||
</template>
|
||||
{{ item.row.mood }}
|
||||
</n-tooltip>
|
||||
<span class="bar-box" :style="{ background: palette.track }">
|
||||
<span class="bar" :style="{ width: width(item.row), background: barColor(item.row) }" />
|
||||
</span>
|
||||
<span class="solved">{{ item.row.solved }}</span>
|
||||
<span class="change">
|
||||
<span v-if="item.row.user.id === hotId" class="up hot" title="进步最大"
|
||||
>↑{{ item.row.change }}</span
|
||||
>
|
||||
<span v-else-if="(item.row.change ?? 0) > 0" class="up">↑{{ item.row.change }}</span>
|
||||
<span v-else-if="(item.row.change ?? 0) < 0" class="down"
|
||||
>↓{{ -item.row.change! }}</span
|
||||
>
|
||||
<span v-else-if="item.row.change === 0" class="flat">—</span>
|
||||
</span>
|
||||
<n-dropdown
|
||||
v-if="teacher"
|
||||
trigger="click"
|
||||
:options="menuOf(item.row)"
|
||||
@select="(key: string) => onMenu(key, item.row)"
|
||||
>
|
||||
<button class="more" aria-label="更多">⋯</button>
|
||||
</n-dropdown>
|
||||
</MoodPopover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -301,7 +344,8 @@ function onMenu(key: string, row: RankRow) {
|
||||
|
||||
.prow {
|
||||
position: relative;
|
||||
height: 38px;
|
||||
min-height: 38px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
@@ -331,22 +375,69 @@ function onMenu(key: string, row: RankRow) {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.prow .who {
|
||||
width: auto;
|
||||
max-width: 120px;
|
||||
.prow.tall {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
/* 手机:签名跟在名字后面,一行放不下就省略 */
|
||||
.mood {
|
||||
/* 手机:名字一行,签名在名字下面一行 */
|
||||
.pmain {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.pname {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.prow .who {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sig {
|
||||
display: block;
|
||||
font-size: var(--oj-fs-meta);
|
||||
color: v-bind("theme.textColor3");
|
||||
line-height: 18px;
|
||||
color: v-bind("theme.textColor2");
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 桌面:签名那一行从名字底下(名次 28 + 头像 20 + 两个 8 的间距)伸到本栏末尾 */
|
||||
.line {
|
||||
margin: -6px 0 4px 64px;
|
||||
}
|
||||
|
||||
.line :deep(.n-ellipsis) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.write {
|
||||
height: 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0 9px;
|
||||
border: 1px dashed rgba(24, 160, 88, 0.6);
|
||||
border-radius: 11px;
|
||||
background: v-bind("theme.cardColor");
|
||||
color: #18a058;
|
||||
font: inherit;
|
||||
font-size: var(--oj-fs-meta);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.write:hover {
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.prow .rank {
|
||||
width: 24px;
|
||||
}
|
||||
@@ -364,14 +455,14 @@ function onMenu(key: string, row: RankRow) {
|
||||
color: #0c7a43;
|
||||
}
|
||||
|
||||
.lane.me {
|
||||
.entry.me {
|
||||
margin: 0 -8px;
|
||||
padding: 0 8px;
|
||||
border-radius: 6px;
|
||||
background: rgba(24, 160, 88, 0.12);
|
||||
}
|
||||
|
||||
.lane.zero {
|
||||
.entry.zero {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
@@ -404,11 +495,6 @@ function onMenu(key: string, row: RankRow) {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.quote {
|
||||
flex-shrink: 0;
|
||||
color: v-bind("theme.textColor3");
|
||||
}
|
||||
|
||||
.bar-box {
|
||||
flex-grow: 1;
|
||||
height: 16px;
|
||||
|
||||
@@ -428,6 +428,7 @@ async function restore(userId: number) {
|
||||
@analysis="openAnalysis"
|
||||
@hide="hide"
|
||||
@clear-mood="confirmClearMood"
|
||||
@mood-saved="onMoodSaved"
|
||||
/>
|
||||
</template>
|
||||
<div v-else-if="!loading" class="empty">排名没取到,刷新一下试试</div>
|
||||
|
||||
Reference in new issue
Block a user