mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-04-23 22:09:51 +08:00
💄 调整UI
This commit is contained in:
@@ -2,14 +2,14 @@
|
||||
<div
|
||||
v-if="card"
|
||||
:id="`post-card-${card.postId}`"
|
||||
class="tpc-card"
|
||||
:class="{ 'select-mode': props.selectMode }"
|
||||
class="tpc-card"
|
||||
@click="trySelect()"
|
||||
>
|
||||
<div class="tpc-top">
|
||||
<div class="tpc-cover" @click="toPost()">
|
||||
<TMiImg :src="card.cover" alt="cover" :ori="true" v-if="card.cover !== ''" />
|
||||
<img src="/source/UI/defaultCover.webp" alt="cover" v-else />
|
||||
<TMiImg v-if="card.cover !== ''" :ori="true" :src="card.cover" alt="cover" />
|
||||
<img v-else alt="cover" src="/source/UI/defaultCover.webp" />
|
||||
<div v-if="card.status" class="tpc-act">
|
||||
<div class="tpc-status">{{ card.status?.label }}</div>
|
||||
<div class="tpc-time">
|
||||
@@ -19,20 +19,20 @@
|
||||
</div>
|
||||
<div
|
||||
v-else-if="props.modelValue.post.images.length > 1"
|
||||
class="tpc-image-cnt"
|
||||
:title="`图片数:${props.modelValue.post.images.length}`"
|
||||
class="tpc-image-cnt"
|
||||
>
|
||||
<v-icon size="10">mdi-folder-multiple-image</v-icon>
|
||||
<span>{{ props.modelValue.post.images.length }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tpc-title" :title="card.title" @click="shareCard()">{{ card.title }}</div>
|
||||
<div :title="card.title" class="tpc-title" @click="shareCard()">{{ card.title }}</div>
|
||||
</div>
|
||||
<div class="tpc-mid" v-if="card.user !== null">
|
||||
<div v-if="card.user !== null" class="tpc-mid">
|
||||
<TpAvatar
|
||||
:data="card.user"
|
||||
position="left"
|
||||
:style="{ cursor: props.userClick ? 'pointer' : 'default' }"
|
||||
position="left"
|
||||
@click="onUserClick()"
|
||||
/>
|
||||
</div>
|
||||
@@ -45,41 +45,41 @@
|
||||
<TpcTag
|
||||
v-for="topic in card.topics"
|
||||
:key="topic.id"
|
||||
@click="toTopic(topic)"
|
||||
:tag="topic.name"
|
||||
@click="toTopic(topic)"
|
||||
/>
|
||||
</div>
|
||||
<div class="tpc-data" v-if="card.data !== null">
|
||||
<div class="tpc-info-item" :title="`浏览数:${card.data.view}`">
|
||||
<div v-if="card.data !== null" class="tpc-data">
|
||||
<div :title="`浏览数:${card.data.view}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-eye</v-icon>
|
||||
<span>{{ card.data.view }}</span>
|
||||
</div>
|
||||
<div class="tpc-info-item" :title="`收藏数:${card.data.mark}`">
|
||||
<div :title="`收藏数:${card.data.mark}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-star</v-icon>
|
||||
<span>{{ card.data.mark }}</span>
|
||||
</div>
|
||||
<div class="tpc-info-item" :title="`回复数:${card.data.reply}`">
|
||||
<div :title="`回复数:${card.data.reply}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-comment</v-icon>
|
||||
<span>{{ card.data.reply }}</span>
|
||||
</div>
|
||||
<div class="tpc-info-item" :title="`点赞数:${card.data.like}`">
|
||||
<div :title="`点赞数:${card.data.like}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-thumb-up</v-icon>
|
||||
<span>{{ card.data.like }}</span>
|
||||
</div>
|
||||
<div class="tpc-info-item" :title="`转发数:${card.data.forward}`">
|
||||
<div :title="`转发数:${card.data.forward}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-share-variant</v-icon>
|
||||
<span>{{ card.data.forward }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tpc-data">
|
||||
<div class="tpc-info-item" :title="`创建时间: ${card.meta.create_time}`">
|
||||
<div :title="`创建时间: ${card.meta.create_time}`" class="tpc-info-item">
|
||||
<v-icon size="12">mdi-calendar-clock</v-icon>
|
||||
<span>{{ card.meta.create_time }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="card.meta.update_time"
|
||||
class="tpc-info-item"
|
||||
:title="`更新时间: ${card.meta.update_time}`"
|
||||
class="tpc-info-item"
|
||||
>
|
||||
<v-icon size="12">mdi-calendar-edit</v-icon>
|
||||
<span>{{ card.meta.update_time }}</span>
|
||||
@@ -87,30 +87,30 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tpc-forum"
|
||||
v-if="card.forum !== null && card.forum.name !== ''"
|
||||
:style="{
|
||||
background: str2Color(`${card.forum.id}${card.forum.name}`, -60),
|
||||
}"
|
||||
v-if="card.forum !== null && card.forum.name !== ''"
|
||||
:title="`频道: ${card.forum.name}`"
|
||||
class="tpc-forum"
|
||||
@click="toForum(card.forum)"
|
||||
>
|
||||
<img v-if="card.forum.icon !== ''" :src="card.forum.icon" :alt="card.forum.name" />
|
||||
<img v-if="card.forum.icon !== ''" :alt="card.forum.name" :src="card.forum.icon" />
|
||||
<span>{{ card.forum.name }}</span>
|
||||
</div>
|
||||
<v-checkbox-btn
|
||||
v-model="isSelected"
|
||||
v-if="props.selectMode"
|
||||
v-model="isSelected"
|
||||
class="tpc-select"
|
||||
@click.stop="trySelect()"
|
||||
data-html2canvas-ignore
|
||||
@click.stop="trySelect()"
|
||||
/>
|
||||
<div
|
||||
class="tpc-info-id"
|
||||
v-else
|
||||
:style="{
|
||||
background: str2Color(`${props.modelValue.post.post_id}`, 0),
|
||||
}"
|
||||
v-else
|
||||
class="tpc-info-id"
|
||||
>
|
||||
<span>{{ props.modelValue.post.post_id }}</span>
|
||||
<template v-if="isDevEnv">
|
||||
@@ -125,9 +125,10 @@ import showSnackbar from "@comp/func/snackbar.js";
|
||||
import TpAvatar from "@comp/viewPost/tp-avatar.vue";
|
||||
import TpcTag from "@comp/viewPost/tpc-tag.vue";
|
||||
import { emit } from "@tauri-apps/api/event";
|
||||
import { str2Color } from "@utils/colorFunc.js";
|
||||
import { generateShareImg } from "@utils/TGShare.js";
|
||||
import { createPost } from "@utils/TGWindow.js";
|
||||
import { str2Color, timestampToDate } from "@utils/toolFunc.js";
|
||||
import { timestampToDate } from "@utils/toolFunc.js";
|
||||
import { computed, onMounted, ref, shallowRef, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
{{ parseTitle(model.subtitle) }}
|
||||
</div>
|
||||
<div
|
||||
:style="{ background: str2Color(`${model.tagIcon}${model.tagLabel}`, 40) }"
|
||||
:title="`标签:${model.tagLabel}`"
|
||||
class="anno-label"
|
||||
:style="{ background: str2Color(`${model.tagIcon}${model.tagLabel}`, 40) }"
|
||||
>
|
||||
<TMiImg :src="model.tagIcon" alt="tag" :ori="true" />
|
||||
<TMiImg :ori="true" :src="model.tagIcon" alt="tag" />
|
||||
<span>{{ model.tagLabel }}</span>
|
||||
</div>
|
||||
<div class="anno-id" :style="{ background: str2Color(`${model.id}`, 0) }">
|
||||
<div :style="{ background: str2Color(`${model.id}`, 0) }" class="anno-id">
|
||||
ID:{{ model.id }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -31,10 +31,11 @@ import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { AnnoTypeEnum } from "@enum/anno.js";
|
||||
import useAppStore from "@store/app.js";
|
||||
import { str2Color } from "@utils/colorFunc.js";
|
||||
import TGLogger from "@utils/TGLogger.js";
|
||||
import { generateShareImg } from "@utils/TGShare.js";
|
||||
import { createTGWindow } from "@utils/TGWindow.js";
|
||||
import { decodeRegExp, str2Color } from "@utils/toolFunc.js";
|
||||
import { decodeRegExp } from "@utils/toolFunc.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
<template>
|
||||
<div :title="props.info.name" class="pb-mi-box" @click="toMaterial()">
|
||||
<div class="pb-mi-left">
|
||||
<img :src="`/icon/bg/${props.info.star}-Star.webp`" alt="bg" class="pb-mi-bg" />
|
||||
<img :src="`/icon/material/${props.info.id}.webp`" alt="icon" class="pb-mi-icon" />
|
||||
<img :src="`/icon/bg/${props.info.star}-Star.webp`" alt="bg" class="bg" />
|
||||
<img :src="`/icon/material/${props.info.id}.webp`" alt="icon" class="icon" />
|
||||
</div>
|
||||
<div class="pb-mi-right">{{ props.info.name }}</div>
|
||||
<div class="pb-mi-id">{{ props.info.id }}</div>
|
||||
<div class="pb-mi-id">{{ props.info.type }}·{{ props.info.id }}</div>
|
||||
<div class="pb-mi-cnt">{{ item.count }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, watch } from "vue";
|
||||
import { getOdStarColor } from "@utils/colorFunc.js";
|
||||
import { computed, shallowRef, watch } from "vue";
|
||||
|
||||
import type { MaterialInfo } from "@/pages/common/PageBagMaterial.vue";
|
||||
|
||||
@@ -44,6 +45,8 @@ watch(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const idColor = computed<string>(() => getOdStarColor(props.info.star));
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@styles/github.styles.scss" as github-styles;
|
||||
@@ -51,39 +54,37 @@ watch(
|
||||
.pb-mi-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 45px;
|
||||
overflow: hidden;
|
||||
height: 48px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-right: 5px;
|
||||
padding-right: 8px;
|
||||
border: 1px solid var(--common-shadow-1);
|
||||
border-radius: 5px;
|
||||
border-radius: 4px;
|
||||
background: var(--box-bg-1);
|
||||
column-gap: 5px;
|
||||
column-gap: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pb-mi-left {
|
||||
position: relative;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
aspect-ratio: 1;
|
||||
|
||||
.pb-mi-bg,
|
||||
.pb-mi-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
.bg,
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.pb-mi-right {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-width: calc(100% - 50px);
|
||||
max-width: 100%;
|
||||
color: var(--box-text-2);
|
||||
font-size: 14px;
|
||||
text-overflow: ellipsis;
|
||||
@@ -93,26 +94,30 @@ watch(
|
||||
|
||||
.pb-mi-id {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
right: 2px;
|
||||
bottom: 0;
|
||||
color: v-bind(idColor); /* stylelint-disable-line value-keyword-case */
|
||||
font-size: 8px;
|
||||
opacity: 0.6;
|
||||
font-style: italic;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.pb-mi-cnt {
|
||||
@include github-styles.github-tag-dark-gen(#82aaff);
|
||||
@include github-styles.github-tag-dark-gen(#009688);
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
padding-right: 4px;
|
||||
padding-left: 12px;
|
||||
border-top: unset;
|
||||
border-left: unset;
|
||||
border-bottom-left-radius: 20px;
|
||||
border-top-right-radius: 4px;
|
||||
border-right: unset;
|
||||
border-bottom-left-radius: 12px;
|
||||
font-family: var(--font-title);
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<span class="cnt">{{ record.count }}</span>
|
||||
<span class="type">{{ record.manual ? "手动更新" : "自动导入" }}</span>
|
||||
</div>
|
||||
<div v-if="dbInfo.records.length === 0">暂无记录</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,72 +1,144 @@
|
||||
<!-- 角色/武器WIKI侧边栏项 -->
|
||||
<template>
|
||||
<div class="twc-li-box">
|
||||
<div :class="{ selected: props.curItem.id === props.data.id }" class="twc-li-box">
|
||||
<div class="twc-li-left">
|
||||
<!-- TODO: 角色添加元素&武器类型,武器添加类型 -->
|
||||
<img class="twc-li-bg" :src="`/icon/bg/${props.data.star}-Star.webp`" alt="bg" />
|
||||
<img class="twc-li-icon" :src="`/WIKI/${props.mode}/${props.data.id}.webp`" alt="icon" />
|
||||
<img :src="`/icon/bg/${props.data.star}-Star.webp`" alt="bg" class="bg" />
|
||||
<img :src="`/WIKI/${props.mode}/${props.data.id}.webp`" alt="icon" class="icon" />
|
||||
</div>
|
||||
<div :title="props.data.name" class="twc-li-right">{{ props.data.name }}</div>
|
||||
<div
|
||||
:title="`${props.mode === 'weapon' ? '武器' : '角色'}ID:${props.data.id}`"
|
||||
class="twc-li-id"
|
||||
>
|
||||
{{ props.data.id }}
|
||||
</div>
|
||||
<div class="twc-li-icons">
|
||||
<template v-if="props.mode === 'character'">
|
||||
<img
|
||||
:src="`/icon/element/${props.data.element}元素.webp`"
|
||||
:title="`${props.data.element}元素`"
|
||||
alt="element"
|
||||
class="element"
|
||||
/>
|
||||
</template>
|
||||
<img
|
||||
:src="`/icon/weapon/${props.data.weapon}.webp`"
|
||||
:title="props.data.weapon"
|
||||
alt="weapon"
|
||||
class="weapon"
|
||||
/>
|
||||
</div>
|
||||
<div class="twc-li-right" :title="props.data.name">{{ props.data.name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
type TwcListItemProps =
|
||||
| {
|
||||
mode: "character";
|
||||
data: TGApp.App.Character.WikiBriefInfo;
|
||||
curItem: TGApp.App.Character.WikiBriefInfo;
|
||||
}
|
||||
| {
|
||||
mode: "weapon";
|
||||
data: TGApp.App.Weapon.WikiBriefInfo;
|
||||
curItem: TGApp.App.Weapon.WikiBriefInfo;
|
||||
};
|
||||
import { getOdStarColor } from "@utils/colorFunc.js";
|
||||
import { computed } from "vue";
|
||||
|
||||
/** 角色数据 */
|
||||
type TwcListItemAvatar = {
|
||||
mode: "character";
|
||||
data: TGApp.App.Character.WikiBriefInfo;
|
||||
curItem: TGApp.App.Character.WikiBriefInfo;
|
||||
};
|
||||
/** 武器数据 */
|
||||
type TwcListItemWeapon = {
|
||||
mode: "weapon";
|
||||
data: TGApp.App.Weapon.WikiBriefInfo;
|
||||
curItem: TGApp.App.Weapon.WikiBriefInfo;
|
||||
};
|
||||
type TwcListItemProps = (TwcListItemAvatar | TwcListItemWeapon) & {
|
||||
width?: number;
|
||||
};
|
||||
|
||||
const props = defineProps<TwcListItemProps>();
|
||||
const idColor = computed<string>(() => getOdStarColor(props.data.star));
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.twc-li-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 45px;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
border: 1px solid var(--common-shadow-1);
|
||||
border-radius: 5px;
|
||||
background: v-bind("props.data.id === props.curItem.id ? 'var(--box-bg-2)' : 'var(--box-bg-1)'");
|
||||
border-radius: 4px;
|
||||
background: var(--box-bg-1);
|
||||
cursor: pointer;
|
||||
gap: 10px;
|
||||
gap: 4px;
|
||||
|
||||
&.selected {
|
||||
background: var(--box-bg-2);
|
||||
}
|
||||
}
|
||||
|
||||
.twc-li-left {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
.twc-li-bg,
|
||||
.twc-li-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
.twc-li-bg img,
|
||||
.twc-li-icon img {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
object-fit: cover;
|
||||
flex-shrink: 0;
|
||||
aspect-ratio: 1;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
|
||||
.bg,
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.bg {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.twc-li-right {
|
||||
overflow: hidden;
|
||||
padding-right: 8px;
|
||||
color: var(--app-page-content);
|
||||
font-size: 14px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.twc-li-id {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 2px;
|
||||
bottom: 0;
|
||||
color: v-bind(idColor); /* stylelint-disable-line value-keyword-case */
|
||||
font-size: 6px;
|
||||
font-style: italic;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.twc-li-icons {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- 游戏签到 TODO: 补签 -->
|
||||
<!-- 游戏签到 -->
|
||||
<template>
|
||||
<div class="tuss-box">
|
||||
<div class="tuss-top">
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<span
|
||||
v-if="mode == 'link'"
|
||||
:style="getTextStyle()"
|
||||
:title="props.data.attributes?.link"
|
||||
class="tp-text-link"
|
||||
@click="toLink()"
|
||||
@contextmenu="copyLink()"
|
||||
:title="props.data.attributes?.link"
|
||||
:style="getTextStyle()"
|
||||
>
|
||||
{{ decodeRegExp(props.data.insert) }}
|
||||
</span>
|
||||
<span v-else-if="mode == 'emoji'" class="tp-text-emoji">
|
||||
<img :src="getEmojiUrl()" :alt="getEmojiName()" :title="getEmojiName()" />
|
||||
<img :alt="getEmojiName()" :src="getEmojiUrl()" :title="getEmojiName()" />
|
||||
</span>
|
||||
<TpText
|
||||
v-else-if="mode == 'emojis'"
|
||||
v-for="(emoji, indexE) in emojis"
|
||||
:data="emoji"
|
||||
v-else-if="mode == 'emojis'"
|
||||
:key="indexE"
|
||||
:data="emoji"
|
||||
/>
|
||||
<span v-else :style="getTextStyle()">{{ decodeRegExp(props.data.insert) }}</span>
|
||||
</template>
|
||||
@@ -24,8 +24,9 @@
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import bbsReq from "@req/bbsReq.js";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import { isColorSimilar } from "@utils/colorFunc.js";
|
||||
import { parseLink, parsePost } from "@utils/linkParser.js";
|
||||
import { isColorSimilar, decodeRegExp } from "@utils/toolFunc.js";
|
||||
import { decodeRegExp } from "@utils/toolFunc.js";
|
||||
import { onMounted, ref, shallowRef, StyleValue, toRaw } from "vue";
|
||||
|
||||
export type TpText = {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import useAppStore from "@store/app.js";
|
||||
import { str2Color } from "@utils/toolFunc.js";
|
||||
import { str2Color } from "@utils/colorFunc.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed } from "vue";
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<span class="tag-label" :title="`点击跳转#${props.tag}#`">
|
||||
<span :title="`点击跳转#${props.tag}#`" class="tag-label">
|
||||
{{ props.tag }}
|
||||
</span>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import useAppStore from "@store/app.js";
|
||||
import { str2Color } from "@utils/toolFunc.js";
|
||||
import { str2Color } from "@utils/colorFunc.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed } from "vue";
|
||||
|
||||
|
||||
@@ -278,12 +278,12 @@ async function refresh(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
await TGLogger.Info(`[Character][refreshRoles][${account.value.gameUid}] 正在更新角色数据`);
|
||||
if (!cookie.value) {
|
||||
showSnackbar.warn("请先登录");
|
||||
loadData.value = false;
|
||||
return;
|
||||
}
|
||||
await TGLogger.Info(`[Character][refreshRoles][${account.value.gameUid}] 正在更新角色数据`);
|
||||
await showLoading.start(`正在更新${account.value.gameUid}的角色数据`);
|
||||
loadData.value = true;
|
||||
await showLoading.update("正在刷新首页数据");
|
||||
@@ -308,7 +308,7 @@ async function refresh(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
const idList = listRes.map((i) => i.id.toString());
|
||||
await showLoading.update(`共${idList.length}个角色`);
|
||||
await showLoading.update(`共${idList.length}个角色,正在获取角色详情`);
|
||||
const res = await recordReq.character.detail(cookie.value, account.value, idList);
|
||||
if ("retcode" in res) {
|
||||
showSnackbar.error(`[${res.retcode}] ${res.message}`);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
:key="index"
|
||||
v-model:cur-item="curItem"
|
||||
:data="item"
|
||||
:width="160"
|
||||
mode="character"
|
||||
@click="switchC(item)"
|
||||
/>
|
||||
@@ -128,30 +129,31 @@ async function toOuter(item?: TGApp.App.Character.WikiBriefInfo): Promise<void>
|
||||
.wc-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: calc(100vh - 40px);
|
||||
column-gap: 10px;
|
||||
max-height: calc(100vh - 32px);
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.wc-left {
|
||||
display: flex;
|
||||
width: 500px;
|
||||
width: fit-content;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.wc-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.wc-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--tgc-btn-1);
|
||||
color: var(--btn-text);
|
||||
}
|
||||
@@ -159,21 +161,20 @@ async function toOuter(item?: TGApp.App.Character.WikiBriefInfo): Promise<void>
|
||||
.wc-list {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 500px;
|
||||
height: calc(100% - 40px);
|
||||
padding-right: 10px;
|
||||
gap: 10px;
|
||||
grid-auto-rows: 45px;
|
||||
grid-template-columns: repeat(3, minmax(100px, 1fr));
|
||||
width: 100%;
|
||||
padding-right: 8px;
|
||||
gap: 8px;
|
||||
grid-template-columns: repeat(3, 160px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.wc-detail {
|
||||
max-height: 100%;
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px var(--common-shadow-2);
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 4px var(--common-shadow-2);
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -99,34 +99,35 @@ async function toOuter(item?: TGApp.App.Weapon.WikiBriefInfo): Promise<void> {
|
||||
await toObcPage(item.contentId);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
<style lang="scss" scoped>
|
||||
.ww-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
max-height: calc(100vh - 40px);
|
||||
column-gap: 10px;
|
||||
max-height: calc(100vh - 32px);
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.ww-left {
|
||||
display: flex;
|
||||
width: 500px;
|
||||
width: fit-content;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ww-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ww-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--tgc-btn-1);
|
||||
color: var(--btn-text);
|
||||
}
|
||||
@@ -134,24 +135,20 @@ async function toOuter(item?: TGApp.App.Weapon.WikiBriefInfo): Promise<void> {
|
||||
.ww-list {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 500px;
|
||||
height: calc(100% - 40px);
|
||||
padding-right: 10px;
|
||||
gap: 10px;
|
||||
grid-auto-rows: 45px;
|
||||
grid-template-columns: repeat(3, minmax(100px, 1fr));
|
||||
width: 100%;
|
||||
padding-right: 8px;
|
||||
gap: 8px;
|
||||
grid-template-columns: repeat(3, 160px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ww-detail {
|
||||
position: relative;
|
||||
height: calc(100vh - 40px);
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px var(--common-shadow-2);
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 4px var(--common-shadow-2);
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
60
src/utils/colorFunc.ts
Normal file
60
src/utils/colorFunc.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 颜色相关处理
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
import { score } from "wcag-color";
|
||||
|
||||
/**
|
||||
* 根据传入星级获取对应颜色
|
||||
* @since Beta v0.9.0
|
||||
* @param {number} star
|
||||
* @returns {string} color
|
||||
*/
|
||||
export function getOdStarColor(star: number): string {
|
||||
switch (star) {
|
||||
case 5:
|
||||
return "var(--tgc-od-orange)";
|
||||
case 4:
|
||||
return "var(--tgc-od-purple)";
|
||||
case 3:
|
||||
return "var(--tgc-od-blue)";
|
||||
case 2:
|
||||
return "var(--tgc-od-green)";
|
||||
case 1:
|
||||
return "var(--tgc-od-white)";
|
||||
default:
|
||||
return "var(--tgc-od-red)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断颜色是否相似
|
||||
* @since Beta v0.9.0
|
||||
* @param {string} colorBg - 背景颜色
|
||||
* @param {string} colorText - 文本颜色
|
||||
* @returns {boolean} 是否相似
|
||||
*/
|
||||
export function isColorSimilar(colorBg: string, colorText: string): boolean {
|
||||
return score(colorText, colorBg) === "Fail";
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据字符串生成颜色
|
||||
* @since Beta v0.8.2
|
||||
* @param {string} str - 输入字符串
|
||||
* @param {number} adjust - 亮度调整值,正数变亮,负数变暗
|
||||
* @returns {string} 生成的颜色 rgb(r, g, b)
|
||||
*/
|
||||
export function str2Color(str: string, adjust: number): string {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
let r = (hash >> 16) & 0xff;
|
||||
let g = (hash >> 8) & 0xff;
|
||||
let b = hash & 0xff;
|
||||
r = Math.min(Math.max(r + adjust, 0), 255);
|
||||
g = Math.min(Math.max(g + adjust, 0), 255);
|
||||
b = Math.min(Math.max(b + adjust, 0), 255);
|
||||
return `rgb(${r}, ${g}, ${b})`;
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
/**
|
||||
* 一些工具函数
|
||||
* @since Beta v0.9.0
|
||||
*/
|
||||
|
||||
import { AvatarExtResTypeEnum, AvatarExtTypeEnum } from "@enum/bbs.js";
|
||||
import { path } from "@tauri-apps/api";
|
||||
import { type } from "@tauri-apps/plugin-os";
|
||||
import colorConvert from "color-convert";
|
||||
import type { KEYWORD } from "color-convert/conversions.js";
|
||||
import { v4 } from "uuid";
|
||||
import { score } from "wcag-color";
|
||||
|
||||
import { AppCharacterData, AppWeaponData } from "@/data/index.js";
|
||||
|
||||
@@ -179,43 +177,6 @@ export function getRandomString(length: number, type: string = "all"): string {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将颜色转为 hex
|
||||
* @since Beta v0.3.9
|
||||
* @param {string} color - 颜色
|
||||
* @returns {string} hex
|
||||
*/
|
||||
function color2Hex(color: string): string {
|
||||
if (color.startsWith("#")) return color;
|
||||
if (color.startsWith("rgb")) {
|
||||
// 正则获取 rgb(0, 0, 0) 或 rgba(0, 0, 0, 0) 或 rgb(0 0 0/0)
|
||||
const reg = /rgba?\((.*?)\)/;
|
||||
const match = reg.exec(color);
|
||||
if (match === null) return "#000000";
|
||||
const rgb = match[1];
|
||||
const rgbArr = rgb.split(/[ ,/]/);
|
||||
if (rgbArr.length < 3) return "#000000";
|
||||
const r = parseInt(rgbArr[0]);
|
||||
const g = parseInt(rgbArr[1]);
|
||||
const b = parseInt(rgbArr[2]);
|
||||
return colorConvert.rgb.hex([r, g, b]);
|
||||
}
|
||||
return colorConvert.keyword.hex(<KEYWORD>color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 判断颜色是否相似
|
||||
* @since Beta v0.3.9
|
||||
* @param {string} colorBg - 背景颜色
|
||||
* @param {string} colorText - 文本颜色
|
||||
* @returns {boolean} 是否相似
|
||||
*/
|
||||
export function isColorSimilar(colorBg: string, colorText: string): boolean {
|
||||
const hexBg = color2Hex(colorBg);
|
||||
const hexText = color2Hex(colorText);
|
||||
return score(hexText, hexBg) === "Fail";
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析带样式的文本
|
||||
* @since Beta v0.8.1
|
||||
@@ -357,24 +318,3 @@ export function getUserAvatar(
|
||||
// TODO: 处理其他类型头像
|
||||
return user.avatar_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据字符串生成颜色
|
||||
* @since Beta v0.8.2
|
||||
* @param {string} str - 输入字符串
|
||||
* @param {number} adjust - 亮度调整值,正数变亮,负数变暗
|
||||
* @returns {string} 生成的颜色 rgb(r, g, b)
|
||||
*/
|
||||
export function str2Color(str: string, adjust: number): string {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
let r = (hash >> 16) & 0xff;
|
||||
let g = (hash >> 8) & 0xff;
|
||||
let b = hash & 0xff;
|
||||
r = Math.min(Math.max(r + adjust, 0), 255);
|
||||
g = Math.min(Math.max(g + adjust, 0), 255);
|
||||
b = Math.min(Math.max(b + adjust, 0), 255);
|
||||
return `rgb(${r}, ${g}, ${b})`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user