feat: 代码整理

This commit is contained in:
Tinhone 2023-10-13 05:19:04 +08:00
parent 5f3e401239
commit 829ea2d13b
8 changed files with 145 additions and 143 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="custom-font-family-extra-options-entry"> <div class="custom-font-family-extra-options-entry">
<VButton ref="button" @mouseover="loadPanel()" @click="togglePanelDisplay()"> <VButton @mouseover="loadPanel()" @click="togglePanelDisplay()">
字体设置<VIcon icon="right-arrow" :size="16"></VIcon> 字体设置<VIcon icon="right-arrow" :size="16"></VIcon>
</VButton> </VButton>
</div> </div>
@ -9,7 +9,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { VIcon, VButton } from '@/ui' import { VIcon, VButton } from '@/ui'
import { getPanelLoadState, mountPanel, togglePanelDisplay } from './vm' import { loadPanel, togglePanelDisplay } from './vm'
export default defineComponent({ export default defineComponent({
components: { components: {
@ -18,12 +18,7 @@ export default defineComponent({
}, },
methods: { methods: {
async loadPanel() { loadPanel,
const isLoaded = await getPanelLoadState()
if (!isLoaded) {
await mountPanel()
}
},
togglePanelDisplay, togglePanelDisplay,
}, },
}) })

View File

@ -1,23 +1,24 @@
<template> <template>
<VPopup v-model="popupOpen" class="extra-options-panel" fixed :lazy="false"> <VPopup v-model="popupOpen" class="be-extra-options-panel" fixed :lazy="false">
<div class="eop-header"> <div class="be-eop-header">
<div class="eop-h-left"> <div class="be-eop-h-title">
<VIcon class="eop-h-l-symbol" :icon="initData.header.title.icon" :size="24"></VIcon> <VIcon class="be-eop-h-t-icon" :icon="initData.header.title.icon" :size="24"></VIcon>
<div class="eop-h-l-title">{{ initData.header.title.text }}</div> <div class="be-eop-h-t-text">{{ initData.header.title.text }}</div>
</div> </div>
<div class="eop-h-right"> <div class="be-eop-h-actions">
<div v-for="action in initData.header.actions" :key="action.id" class="be-eop-h-a-action">
<VIcon <VIcon
v-for="action in initData.header.actions"
:key="action.id"
:ref="`action${action.id}`" :ref="`action${action.id}`"
:class="`eop-h-r-${action.iconClassNameSuffix}`" :class="`action-${action.actionClassNameSuffix}`"
:title="action.title" :title="action.title"
:icon="action.icon" :icon="action.icon"
:size="24" :size="24"
></VIcon> ></VIcon>
</div>
<div class="be-eop-h-a-action">
<VIcon <VIcon
class="eop-h-r-close" class="action-close"
title="关闭" title="关闭"
icon="mdi-close" icon="mdi-close"
:size="24" :size="24"
@ -25,15 +26,16 @@
></VIcon> ></VIcon>
</div> </div>
</div> </div>
</div>
<div class="eop-separator"></div> <div class="be-eop-separator"></div>
<div class="eop-content"> <div class="be-eop-content">
<div v-for="option in initData.content.options" :key="option.id" class="eop-c-option"> <div v-for="option in initData.content.options" :key="option.id" class="be-eop-c-option">
<div class="eop-c-o-title">{{ option.title }}</div> <div class="be-eop-c-o-title">{{ option.title }}</div>
<div class="eop-c-o-description">{{ option.description }}</div> <div class="be-eop-c-o-description">{{ option.description }}</div>
<div class="eop-c-o-input" :class="option.inputClassName"> <div class="be-eop-c-o-input" :class="`input-${option.inputClassNameSuffix}`">
<slot :name="`eop-c-o-input-slot-${option.id}`"> <slot :name="`input${option.id}`">
选项输入入口默认文字使用含 v-slot 指令的 template 元素以替换默认内容 选项输入入口默认文字使用含 v-slot 指令的 template 元素以替换默认内容
</slot> </slot>
</div> </div>
@ -73,7 +75,7 @@ export default defineComponent({
<style lang="scss"> <style lang="scss">
@import './extra-options-panel'; @import './extra-options-panel';
.extra-options-panel { .be-extra-options-panel {
@include extra-options-panel; @include extra-options-panel();
} }
</style> </style>

View File

@ -5,7 +5,7 @@
:class="{ peek: isPeeking }" :class="{ peek: isPeeking }"
:init-data="initData" :init-data="initData"
> >
<template #eop-c-o-input-slot-0> <template #input0>
<TextArea v-model="inputFontFamily" /> <TextArea v-model="inputFontFamily" />
</template> </template>
</ExtraOptionsPanel> </ExtraOptionsPanel>
@ -33,13 +33,13 @@ const initData: ExtraOptionsPanelInitData = {
id: 0, id: 0,
title: '重置面板中的所有选项为默认值', title: '重置面板中的所有选项为默认值',
icon: 'mdi-cog-sync-outline', icon: 'mdi-cog-sync-outline',
iconClassNameSuffix: 'reset', actionClassNameSuffix: 'reset',
}, },
{ {
id: 1, id: 1,
title: '透视', title: '透视',
icon: 'mdi-eye-outline', icon: 'mdi-eye-outline',
iconClassNameSuffix: 'peek', actionClassNameSuffix: 'peek',
}, },
], ],
}, },
@ -49,7 +49,7 @@ const initData: ExtraOptionsPanelInitData = {
id: 0, id: 0,
title: '自定义字体', title: '自定义字体',
description: '输入需要设置的字体,不同字体之间必须以英文逗号分隔', description: '输入需要设置的字体,不同字体之间必须以英文逗号分隔',
inputClassName: 'input-font-family', inputClassNameSuffix: 'input-font-family',
}, },
], ],
}, },
@ -74,10 +74,10 @@ export default defineComponent({
}, },
watch: { watch: {
// inputFontFamily fontFamily inputFontFamily 500ms // inputFontFamily fontFamily inputFontFamily 1000ms
inputFontFamily: lodash.debounce(value => { inputFontFamily: lodash.debounce(value => {
getComponentSettings('customFontFamily').options.fontFamily = value getComponentSettings('customFontFamily').options.fontFamily = value
}, 500), }, 1000),
async isMouseOverPeekIcon(value: boolean) { async isMouseOverPeekIcon(value: boolean) {
if (!value) { if (!value) {
@ -128,8 +128,8 @@ export default defineComponent({
resetOptions() { resetOptions() {
getComponentSettings('customFontFamily').options.fontFamily = fontFamilyDefaultValue getComponentSettings('customFontFamily').options.fontFamily = fontFamilyDefaultValue
this.inputFontFamily = fontFamilyDefaultValue this.inputFontFamily = fontFamilyDefaultValue
Toast.success('成功将字体设置面板中的所有选项重置为默认值', '自定义字体', 2000) Toast.success('字体设置面板中的所有选项已成功被重置为默认值', '自定义字体', 2000)
console.log('成功将字体设置面板中的所有选项重置为默认值') console.log('字体设置面板中的所有选项已成功被重置为默认值')
}, },
}, },
}) })
@ -141,7 +141,7 @@ export default defineComponent({
opacity: 0.1; opacity: 0.1;
} }
> .eop-content > .eop-c-option > .eop-c-o-input.input-font-family > .be-text-area { > .be-eop-content > .be-eop-c-option > .be-eop-c-o-input.input-input-font-family > .be-text-area {
min-height: 160px; min-height: 160px;
} }
} }

View File

@ -1,27 +1,24 @@
@import 'common'; @import 'common';
$pref: 'eop'; $pref: 'be-eop';
$prefH: 'eop-h'; $panel-padding: 18px;
$prefHL: 'eop-h-l'; $internal-spacing: 14px;
$prefHR: 'eop-h-r';
$prefC: 'eop-c';
$prefCO: 'eop-c-o';
$panelPadding: 22px;
@mixin extra-options-panel { @mixin extra-options-panel {
&.extra-options-panel { &.be-extra-options-panel {
@include popup(); @include popup();
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 500px; width: 500px;
max-width: 80vw;
max-height: 80vh; max-height: 80vh;
padding: $panelPadding 0; padding: $panel-padding 0;
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translateX(-50%) translateY(-50%) scale(0.95); transform: translateX(-50%) translateY(-50%) scale(0.95);
transition: all 0.2s ease-out; transition: all 0.2s ease-out;
font-size: 14px; font-size: 14px;
line-height: normal;
z-index: 100002; z-index: 100002;
&.open { &.open {
@ -31,25 +28,25 @@ $panelPadding: 22px;
> .#{$pref}-header { > .#{$pref}-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0 $panelPadding 18px $panelPadding; padding: 0 $panel-padding $internal-spacing $panel-padding;
flex-shrink: 0; flex-shrink: 0;
> .#{$prefH}-left { > .#{$pref}-h-title {
display: flex; display: flex;
column-gap: 4px; column-gap: 4px;
> .#{$prefHL}-title { > .#{$pref}-h-t-text {
@include semi-bold(); @include semi-bold();
font-size: 19px; font-size: 19px;
line-height: 20px; line-height: 20px;
} }
} }
> .#{$prefH}-right { > .#{$pref}-h-actions {
display: flex; display: flex;
column-gap: 20px; column-gap: ($internal-spacing + 4px);
> [class*='#{$prefHR}'] { > .#{$pref}-h-a-action {
cursor: pointer; cursor: pointer;
transition: all 0.2s ease-out; transition: all 0.2s ease-out;
@ -62,40 +59,41 @@ $panelPadding: 22px;
> .#{$pref}-separator { > .#{$pref}-separator {
height: 1px; height: 1px;
margin: 0 $panelPadding; margin: 0 $panel-padding;
background: rgba(0, 0, 0, 0.1); background-color: rgba(0, 0, 0, 0.1);
flex-shrink: 0; flex-shrink: 0;
body.dark & { body.dark & {
background: rgba(255, 255, 255, 0.1); background-color: rgba(255, 255, 255, 0.1);
} }
} }
> .#{$pref}-content { > .#{$pref}-content {
padding: 0 $panelPadding; @include no-scrollbar();
padding: $internal-spacing $panel-padding 0 $panel-padding;
overflow: auto; overflow: auto;
flex-grow: 1; flex-grow: 1;
flex-shrink: 1; flex-shrink: 1;
> .#{$prefC}-option { > .#{$pref}-c-option {
margin: 18px 0; margin-bottom: ($internal-spacing + 4px);
&:nth-child(1):nth-last-child(1) { &:nth-last-child(1) {
margin-bottom: 12px; margin-bottom: ($internal-spacing - 2px);
} }
> .#{$prefCO}-title { > .#{$pref}-c-o-title {
margin-bottom: 2px; margin-bottom: 2px;
font-size: 14px; font-size: 14px;
} }
> .#{$prefCO}-description { > .#{$pref}-c-o-description {
margin-bottom: 8px; margin-bottom: 8px;
opacity: 0.6; opacity: 0.6;
font-size: 12px; font-size: 12px;
} }
> .#{$prefCO}-input { > .#{$pref}-c-o-input {
@include h-center(); @include h-center();
flex-wrap: wrap; flex-wrap: wrap;
} }

View File

@ -7,26 +7,26 @@ export interface ExtraOptionsPanelInitData {
icon: string icon: string
} }
actions: { actions: {
/** 动作按钮序号,从 0 开始增长,重复将会导致渲染异常 */ /** 动作序号,从 0 开始增长,重复将会导致渲染异常 */
id: number id: number
/** 动作按钮标题 */ /** 动作标题 */
title: string title: string
/** 动作按钮图标 */ /** 动作图标 */
icon: string icon: string
/** 动作按钮类名的后缀,直接写一个贴切的名字就好了 */ /** 动作类名的后缀,前缀是 action- */
iconClassNameSuffix: string actionClassNameSuffix: string
}[] }[]
} }
content: { content: {
options: { options: {
/** 选项序号,从 0 开始增长,重复将会导致渲染异常。另外会在类似 eop-c-s-input-slot-0 的具名插槽用到 */ /** 选项序号,从 0 开始增长,重复将会导致渲染异常 */
id: number id: number
/** 选项标题 */ /** 选项标题 */
title: string title: string
/** 选项介绍 */ /** 选项介绍 */
description: string description: string
/** 选项输入入口类名 */ /** 选项输入入口类名的后缀,前缀是 input- */
inputClassName: string inputClassNameSuffix: string
}[] }[]
} }
} }
@ -42,13 +42,13 @@ export const defaultInitData: ExtraOptionsPanelInitData = {
id: 0, id: 0,
title: '默认动作 0', title: '默认动作 0',
icon: 'mdi-cog-sync-outline', icon: 'mdi-cog-sync-outline',
iconClassNameSuffix: 'default-action-0', actionClassNameSuffix: 'default-action-0',
}, },
{ {
id: 1, id: 1,
title: '默认动作 1', title: '默认动作 1',
icon: 'mdi-eye-outline', icon: 'mdi-eye-outline',
iconClassNameSuffix: 'default-action-1', actionClassNameSuffix: 'default-action-1',
}, },
], ],
}, },
@ -58,13 +58,13 @@ export const defaultInitData: ExtraOptionsPanelInitData = {
id: 0, id: 0,
title: '默认选项 0', title: '默认选项 0',
description: '默认选项 0 的说明', description: '默认选项 0 的说明',
inputClassName: 'default-option-0', inputClassNameSuffix: 'default-option-0',
}, },
{ {
id: 1, id: 1,
title: '默认选项 1', title: '默认选项 1',
description: '默认选项 1 的说明', description: '默认选项 1 的说明',
inputClassName: 'default-option-1', inputClassNameSuffix: 'default-option-1',
}, },
], ],
}, },

View File

@ -4,16 +4,23 @@ let panelVm: Vue & {
toggleDisplay: () => void toggleDisplay: () => void
} }
export const getPanelLoadState = async () => { const getPanelLoadState = () => {
return Boolean(panelVm) return Boolean(panelVm)
} }
export const mountPanel = async () => { const mountPanel = async () => {
const panel = await import('./Panel1.vue').then(m => m.default) const panel = await import('./Panel1.vue').then(m => m.default)
panelVm = mountVueComponent(panel) panelVm = mountVueComponent(panel)
document.body.insertAdjacentElement('beforeend', panelVm.$el) document.body.insertAdjacentElement('beforeend', panelVm.$el)
} }
export const loadPanel = async () => {
const isLoaded = getPanelLoadState()
if (!isLoaded) {
await mountPanel()
}
}
export const togglePanelDisplay = async () => { export const togglePanelDisplay = async () => {
panelVm.toggleDisplay() panelVm.toggleDisplay()
} }

View File

@ -104,12 +104,12 @@ const extraOptions = () => import('./extra-options/Entry1.vue').then(m => m.defa
const instantStyles = [ const instantStyles = [
{ {
name: `${name}--style--setFontFamily`, name: `${kebabName}--style--set-font-family`, // style 标签 id
style: () => import('./set-font-family.scss'), style: () => import('./set-font-family.scss'),
important: true, important: true,
}, },
{ {
name: `${name}--style--disableQuotationMarkTextIndent`, name: `${kebabName}--style--disable-quotation-mark-text-indent`,
style: () => import('./disable-quotation-mark-text-indent.scss'), style: () => import('./disable-quotation-mark-text-indent.scss'),
important: true, important: true,
}, },

View File

@ -1,97 +1,97 @@
$name: 'custom-font-family'; $name: 'custom-font-family';
$fontFamilyCss: var(--#{$name}--options--font-family) !important; $font-family-css: var(--#{$name}--options--font-family) !important;
// 收集 CSS 路径为单一字符串 // 收集 CSS 路径为单一字符串
@function collectPaths($pathList) { @function collect-paths($path-list) {
$stringPath: ''; $string-path: '';
@each $path in $pathList { @each $path in $path-list {
$i: index($pathList, $path); $i: index($path-list, $path);
@if $i!=1 { @if $i!=1 {
$stringPath: '#{$stringPath}, '; $string-path: '#{$string-path}, ';
} }
$stringPath: '#{$stringPath}#{$path}'; $string-path: '#{$string-path}#{$path}';
} }
@return $stringPath; @return $string-path;
} }
@function getOrnamentPath() { @function get-ornament-path() {
$newVideo: '.reply-item .root-reply-container .content-warp .reply-decorate .user-sailing .user-sailing-text .sailing-text'; $new-video: '.reply-item .root-reply-container .content-warp .reply-decorate .user-sailing .user-sailing-text .sailing-text';
$dynamic: '.bili-dyn-ornament__type--3 span'; $dynamic: '.bili-dyn-ornament__type--3 span';
$dynamicCommentArea: '.bb-comment .sailing .sailing-info, .comment-bilibili-fold .sailing .sailing-info'; $dynamic-comment-area: '.bb-comment .sailing .sailing-info, .comment-bilibili-fold .sailing .sailing-info';
@return collectPaths(($newVideo, $dynamic, $dynamicCommentArea)); @return collect-paths(($new-video, $dynamic, $dynamic-comment-area));
} }
@function getFansMedalPath() { @function get-fans-medal-path() {
$newVideo: '.badge-level'; $new-video: '.badge-level';
@return collectPaths(($newVideo)); @return collect-paths(($new-video));
} }
@function getDanmakuPath() { @function get-danmaku-path() {
$main: '.bili-dm'; $main: '.bili-dm';
@return collectPaths(($main)); @return collect-paths(($main));
} }
@function getIconFontPath() { @function get-icon-font-path() {
$mainA: '.iconfont'; $main-a: '.iconfont';
$mainB: '.icon-font'; $main-b: '.icon-font';
$note: '.read-icon'; $note: '.read-icon';
$noteEdit: '.bili-note-iconfont'; $note-edit: '.bili-note-iconfont';
$footer: '.bili-footer-font'; $footer: '.bili-footer-font';
$bangumiInfo: '[class^="icon-"]'; $bangumi-info: '[class^="icon-"]';
$history: '.bilifont'; $history: '.bilifont';
$message: '.bp-icon-font'; $message: '.bp-icon-font';
$creativeCenterA: '.bcc-iconfont'; $creative-center-a: '.bcc-iconfont';
$creativeCenterB: '.fontvt'; $creative-center-b: '.fontvt';
@return collectPaths( @return collect-paths(
( (
$mainA, $main-a,
$mainB, $main-b,
$note, $note,
$noteEdit, $note-edit,
$footer, $footer,
$bangumiInfo, $bangumi-info,
$history, $history,
$message, $message,
$creativeCenterA, $creative-center-a,
$creativeCenterB $creative-center-b
) )
); );
} }
@function getColumnPath() { @function get-column-path() {
$mainA: '.article-detail .article-container .article-container__content .article-content .read-article-holder'; $main-a: '.article-detail .article-container .article-container__content .article-content .read-article-holder';
$mainB: '.article-detail .article-container .article-container__content .article-content .read-article-holder *'; $main-b: '.article-detail .article-container .article-container__content .article-content .read-article-holder *';
@return collectPaths(($mainA, $mainB)); @return collect-paths(($main-a, $main-b));
} }
@function getScorePath() { @function get-score-path() {
$documentary: '.season-cover .score'; $documentary: '.season-cover .score';
$big: '.season-cover .season-cover-score'; $big: '.season-cover .season-cover-score';
@return collectPaths(($documentary, $big)); @return collect-paths(($documentary, $big));
} }
// 装扮在评论区动态等界面显示 // 装扮在评论区动态等界面显示
$ornament: getOrnamentPath(); $ornament: get-ornament-path();
// 粉丝勋章在评论区界面显示 // 粉丝勋章在评论区界面显示
$fansMedal: getFansMedalPath(); $fans-medal: get-fans-medal-path();
// 弹幕在播放器里显示 // 弹幕在播放器里显示
$danmaku: getDanmakuPath(); $danmaku: get-danmaku-path();
// 图标字体 // 图标字体
$iconFont: getIconFontPath(); $icon-font: get-icon-font-path();
// 专栏阅读页可能出现的部分自定义字体 // 专栏阅读页可能出现的部分自定义字体
$column: getColumnPath(); $column: get-column-path();
// 分数在部分剧集的右下角显示 // 分数在部分剧集的右下角显示
$score: getScorePath(); $score: get-score-path();
// 收集所有路径 // 收集所有路径
$discardPaths: collectPaths(($ornament, $fansMedal, $danmaku, $iconFont, $column, $score)); $discard-paths: collect-paths(($ornament, $fans-medal, $danmaku, $icon-font, $column, $score));
$onOptionNames: ( $on-option-names: (
'on-ornament', 'on-ornament',
'on-fans-medal', 'on-fans-medal',
'on-danmaku', 'on-danmaku',
@ -99,17 +99,17 @@ $onOptionNames: (
'on-column', 'on-column',
'on-score' 'on-score'
); );
$onOptionPathLists: ($ornament, $fansMedal, $danmaku, $iconFont, $column, $score); $on-option-path-lists: ($ornament, $fans-medal, $danmaku, $icon-font, $column, $score);
$onOptionGroups: zip($onOptionNames, $onOptionPathLists); $on-option-groups: zip($on-option-names, $on-option-path-lists);
html[#{$name}--detect--is-input-empty='false'] { html[#{$name}--detect--is-input-empty='false'] {
:not(#{$discardPaths}) { :not(#{$discard-paths}) {
font-family: $fontFamilyCss; font-family: $font-family-css;
} }
@each $onOptionName, $onOptionPathList in $onOptionGroups { @each $on-option-name, $on-option-path-list in $on-option-groups {
&[#{$name}--options--#{$onOptionName}='true'] :is(#{$onOptionPathList}) { &[#{$name}--options--#{$on-option-name}='true'] :is(#{$on-option-path-list}) {
font-family: $fontFamilyCss; font-family: $font-family-css;
} }
} }
} }