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>
<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>
</VButton>
</div>
@ -9,7 +9,7 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { VIcon, VButton } from '@/ui'
import { getPanelLoadState, mountPanel, togglePanelDisplay } from './vm'
import { loadPanel, togglePanelDisplay } from './vm'
export default defineComponent({
components: {
@ -18,12 +18,7 @@ export default defineComponent({
},
methods: {
async loadPanel() {
const isLoaded = await getPanelLoadState()
if (!isLoaded) {
await mountPanel()
}
},
loadPanel,
togglePanelDisplay,
},
})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,97 +1,97 @@
$name: 'custom-font-family';
$fontFamilyCss: var(--#{$name}--options--font-family) !important;
$font-family-css: var(--#{$name}--options--font-family) !important;
// 收集 CSS 路径为单一字符串
@function collectPaths($pathList) {
$stringPath: '';
@each $path in $pathList {
$i: index($pathList, $path);
@function collect-paths($path-list) {
$string-path: '';
@each $path in $path-list {
$i: index($path-list, $path);
@if $i!=1 {
$stringPath: '#{$stringPath}, ';
$string-path: '#{$string-path}, ';
}
$stringPath: '#{$stringPath}#{$path}';
$string-path: '#{$string-path}#{$path}';
}
@return $stringPath;
@return $string-path;
}
@function getOrnamentPath() {
$newVideo: '.reply-item .root-reply-container .content-warp .reply-decorate .user-sailing .user-sailing-text .sailing-text';
@function get-ornament-path() {
$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';
$dynamicCommentArea: '.bb-comment .sailing .sailing-info, .comment-bilibili-fold .sailing .sailing-info';
@return collectPaths(($newVideo, $dynamic, $dynamicCommentArea));
$dynamic-comment-area: '.bb-comment .sailing .sailing-info, .comment-bilibili-fold .sailing .sailing-info';
@return collect-paths(($new-video, $dynamic, $dynamic-comment-area));
}
@function getFansMedalPath() {
$newVideo: '.badge-level';
@return collectPaths(($newVideo));
@function get-fans-medal-path() {
$new-video: '.badge-level';
@return collect-paths(($new-video));
}
@function getDanmakuPath() {
@function get-danmaku-path() {
$main: '.bili-dm';
@return collectPaths(($main));
@return collect-paths(($main));
}
@function getIconFontPath() {
$mainA: '.iconfont';
$mainB: '.icon-font';
@function get-icon-font-path() {
$main-a: '.iconfont';
$main-b: '.icon-font';
$note: '.read-icon';
$noteEdit: '.bili-note-iconfont';
$note-edit: '.bili-note-iconfont';
$footer: '.bili-footer-font';
$bangumiInfo: '[class^="icon-"]';
$bangumi-info: '[class^="icon-"]';
$history: '.bilifont';
$message: '.bp-icon-font';
$creativeCenterA: '.bcc-iconfont';
$creativeCenterB: '.fontvt';
@return collectPaths(
$creative-center-a: '.bcc-iconfont';
$creative-center-b: '.fontvt';
@return collect-paths(
(
$mainA,
$mainB,
$main-a,
$main-b,
$note,
$noteEdit,
$note-edit,
$footer,
$bangumiInfo,
$bangumi-info,
$history,
$message,
$creativeCenterA,
$creativeCenterB
$creative-center-a,
$creative-center-b
)
);
}
@function getColumnPath() {
$mainA: '.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 *';
@return collectPaths(($mainA, $mainB));
@function get-column-path() {
$main-a: '.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 collect-paths(($main-a, $main-b));
}
@function getScorePath() {
@function get-score-path() {
$documentary: '.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-fans-medal',
'on-danmaku',
@ -99,17 +99,17 @@ $onOptionNames: (
'on-column',
'on-score'
);
$onOptionPathLists: ($ornament, $fansMedal, $danmaku, $iconFont, $column, $score);
$onOptionGroups: zip($onOptionNames, $onOptionPathLists);
$on-option-path-lists: ($ornament, $fans-medal, $danmaku, $icon-font, $column, $score);
$on-option-groups: zip($on-option-names, $on-option-path-lists);
html[#{$name}--detect--is-input-empty='false'] {
:not(#{$discardPaths}) {
font-family: $fontFamilyCss;
:not(#{$discard-paths}) {
font-family: $font-family-css;
}
@each $onOptionName, $onOptionPathList in $onOptionGroups {
&[#{$name}--options--#{$onOptionName}='true'] :is(#{$onOptionPathList}) {
font-family: $fontFamilyCss;
@each $on-option-name, $on-option-path-list in $on-option-groups {
&[#{$name}--options--#{$on-option-name}='true'] :is(#{$on-option-path-list}) {
font-family: $font-family-css;
}
}
}