perf: 优化暗黑模式

This commit is contained in:
kuaifan 2022-04-19 07:41:55 +08:00
parent 65f53e264c
commit 505f3b8b05
14 changed files with 238 additions and 159 deletions

View File

@ -38,7 +38,7 @@ export default {
}, },
render(createElement) { render(createElement) {
return createElement('div', { return createElement('div', {
class: "no-dark-mode" class: "no-dark-content"
}) })
}, },
data: () => ({ data: () => ({

View File

@ -1,6 +1,7 @@
<template> <template>
<div class="component-only-office"> <div class="component-only-office">
<div :id="this.id" class="placeholder"></div> <Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
<div :id="id" class="placeholder"></div>
<div v-if="loadIng > 0" class="office-loading"><Loading/></div> <div v-if="loadIng > 0" class="office-loading"><Loading/></div>
</div> </div>
</template> </template>
@ -15,11 +16,13 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.placeholder { .placeholder {
flex: 1; flex: 1;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.office-loading { .office-loading {
position: absolute; position: absolute;
top: 0; top: 0;
@ -33,6 +36,26 @@
} }
} }
</style> </style>
<style lang="scss">
.component-only-office {
.load-error {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
padding: 8px;
display: flex;
align-items: center;
.ivu-alert-icon {
position: static;
margin-right: 8px;
margin-left: 4px;
}
}
}
</style>
<script> <script>
import {mapState} from "vuex"; import {mapState} from "vuex";
@ -66,6 +89,7 @@ export default {
data() { data() {
return { return {
loadIng: 0, loadIng: 0,
loadError: false,
docEditor: null, docEditor: null,
} }
@ -101,10 +125,11 @@ export default {
return; return;
} }
this.loadIng++; this.loadIng++;
this.loadError = false;
$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => { $A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => {
this.loadIng--; this.loadIng--;
if (e !== null) { if (e !== null) {
$A.modalAlert("组件加载失败!"); this.loadError = true;
return; return;
} }
if (!this.documentKey) { if (!this.documentKey) {

View File

@ -1,5 +1,6 @@
<template> <template>
<div ref="view" class="common-preview-view no-dark-mode"> <div ref="view" class="common-preview-image">
<div class="common-preview-view no-dark-content">
<template v-if="!isSingle"> <template v-if="!isSingle">
<div class="preview-view-prev" :class="{ 'is-disabled': !infinite && isFirst }" @click="prev"> <div class="preview-view-prev" :class="{ 'is-disabled': !infinite && isFirst }" @click="prev">
<i class="taskfont">&#xe72d;</i> <i class="taskfont">&#xe72d;</i>
@ -19,7 +20,7 @@
<i class="taskfont" @click="handleActions('clocelise')">&#xe7a6;</i> <i class="taskfont" @click="handleActions('clocelise')">&#xe7a6;</i>
</div> </div>
</div> </div>
<div class="preview-view-canvas no-dark-mode"> <div class="preview-view-canvas">
<img <img
v-for="(url, i) in urlList" v-for="(url, i) in urlList"
v-if="i === index" v-if="i === index"
@ -33,17 +34,25 @@
@mousedown="handleMouseDown"> @mousedown="handleMouseDown">
</div> </div>
</div> </div>
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.common-preview-view { .common-preview-image {
position: fixed;
bottom: 0;
left: 0;
right: 0;
top: 0;
backdrop-filter: blur(4px);
.common-preview-view {
position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
position: fixed;
right: 0; right: 0;
top: 0; top: 0;
background: rgba(0, 0, 0, .8); background: rgba(0, 0, 0, .8);
backdrop-filter: blur(4px);
.preview-view-prev, .preview-view-prev,
.preview-view-next { .preview-view-next {
@ -126,6 +135,7 @@
justify-content: center; justify-content: center;
width: 100%; width: 100%;
} }
}
} }
</style> </style>
@ -221,7 +231,10 @@ export default {
this.onSwitch(val); this.onSwitch(val);
} }
}, },
currentImg(val) { initialIndex(index) {
this.index = index
},
currentImg() {
this.$nextTick(_ => { this.$nextTick(_ => {
const $img = this.$refs.img[0]; const $img = this.$refs.img[0];
if (!$img.complete) { if (!$img.complete) {

View File

@ -691,12 +691,9 @@
[style*="background: url"], [style*="background: url"],
[style*="background-image: url"], [style*="background-image: url"],
[background], [background],
twitterwidget,
.sr-reader,
.no-dark-mode, .no-dark-mode,
.no-dark-mode-before:before, .no-dark-content,
.sr-backdrop, .no-dark-before:before {
.dialog-content .content-text {
${this.utils.reverseFilter} ${this.utils.reverseFilter}
} }
@ -706,8 +703,9 @@
[style*="background-image: url"] *, [style*="background-image: url"] *,
input, input,
[background] *, [background] *,
twitterwidget .NaturalImage-image, .no-dark-content img,
.dialog-content .content-text img { .no-dark-content canvas,
.no-dark-content svg image {
${this.utils.noneFilter} ${this.utils.noneFilter}
} }

View File

@ -4,7 +4,7 @@
<div class="page-header"> <div class="page-header">
<div class="header-nav"> <div class="header-nav">
<div class="header-nav-box"> <div class="header-nav-box">
<div class="logo no-dark-mode"></div> <div class="logo no-dark-content"></div>
</div> </div>
<div class="header-nav-box header-nav-boxs" v-if="windowWidth > 780"> <div class="header-nav-box header-nav-boxs" v-if="windowWidth > 780">
<div class="header-right-one"> <div class="header-right-one">
@ -38,20 +38,22 @@
</Dropdown> </Dropdown>
</div> </div>
<div class="header-right-two" @click="register">{{ $L("注册帐号") }}</div> <div class="header-right-two" @click="register">{{ $L("注册帐号") }}</div>
<div class="header-right-three no-dark-mode" @click="login">{{ $L("登录") }}</div> <div class="header-right-three no-dark-content" @click="login">{{ $L("登录") }}</div>
</div> </div>
<div class="header-nav-box header-nav-boxs" v-else> <div class="header-nav-box header-nav-boxs" v-else>
<Dropdown trigger="click"> <Dropdown trigger="click">
<a href="javascript:void(0)"> <a href="javascript:void(0)">
<Icon type="md-menu" class="header-nav-more"/> <Icon type="md-menu" class="header-nav-more no-dark-content"/>
</a> </a>
<DropdownMenu slot="list"> <DropdownMenu slot="list">
<DropdownItem @click.native="login">{{ $L("登录") }}</DropdownItem> <DropdownItem @click.native="login">{{ $L("登录") }}</DropdownItem>
<DropdownItem @click.native="register">{{ $L("注册帐号") }}</DropdownItem> <DropdownItem @click.native="register">{{ $L("注册帐号") }}</DropdownItem>
<Dropdown placement="right-start" @on-click="setLanguage"> <Dropdown placement="right-start" @on-click="setLanguage" transfer>
<DropdownItem> <DropdownItem>
<Icon class="header-right-one-language no-dark-mode" type="md-globe"/> <div class="header-nav-dropdown-item">
<a href="javascript:void(0)" class="header-right-one-dropdown">{{ currentLanguage }}</a> {{ currentLanguage }}
<Icon type="ios-arrow-forward"></Icon>
</div>
</DropdownItem> </DropdownItem>
<DropdownMenu slot="list"> <DropdownMenu slot="list">
<DropdownItem <DropdownItem
@ -61,9 +63,9 @@
:selected="getLanguage() === key">{{ item }}</DropdownItem> :selected="getLanguage() === key">{{ item }}</DropdownItem>
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
<Dropdown trigger="click" placement="right-end" @on-click="setTheme"> <Dropdown trigger="click" placement="right-end" @on-click="setTheme" transfer>
<DropdownItem> <DropdownItem>
<div class="login-setting-item"> <div class="header-nav-dropdown-item">
{{$L('主题皮肤')}} {{$L('主题皮肤')}}
<Icon type="ios-arrow-forward"></Icon> <Icon type="ios-arrow-forward"></Icon>
</div> </div>
@ -88,7 +90,7 @@
<div class="header-tips"> <div class="header-tips">
{{ $L(`${appTitle}是一款轻量级的开源在线项目任务管理工具提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM文件管理等工具。`) }} {{ $L(`${appTitle}是一款轻量级的开源在线项目任务管理工具提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM文件管理等工具。`) }}
</div> </div>
<div class="login-buttom no-dark-mode" @click="login"> <div class="login-buttom no-dark-content" @click="login">
{{ $L("登录") }} {{ $L("登录") }}
</div> </div>
</div> </div>
@ -162,7 +164,7 @@
</Row> </Row>
</div> </div>
<div class="page-footer"> <div class="page-footer">
<div class="footer-service no-dark-mode"> <div class="footer-service no-dark-content">
<div class="footer-bg-box"> <div class="footer-bg-box">
<div class="box-title">{{ $L(`开启您的 ${appTitle} 团队协作`) }}</div> <div class="box-title">{{ $L(`开启您的 ${appTitle} 团队协作`) }}</div>
<div class="buttom-box"> <div class="buttom-box">

View File

@ -2,7 +2,7 @@
<div class="page-login"> <div class="page-login">
<PageTitle :title="$L('登录')"/> <PageTitle :title="$L('登录')"/>
<div class="login-body"> <div class="login-body">
<div class="login-logo no-dark-mode" :class="{'can-click':needStartHome}" @click="goHome"></div> <div class="login-logo no-dark-content" :class="{'can-click':needStartHome}" @click="goHome"></div>
<div class="login-box"> <div class="login-box">
<div class="login-title">{{welcomeTitle}}</div> <div class="login-title">{{welcomeTitle}}</div>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="chat-emoji-wrapper"> <div class="chat-emoji-wrapper">
<ul class="chat-emoji-box overlay-y" :class="type === 'emoji' ? ['no-dark-mode', 'emoji'] : [type]"> <ul class="chat-emoji-box overlay-y" :class="[type, 'no-dark-content']">
<li v-for="item in list" @click="onSelect(item)"> <li v-for="item in list" @click="onSelect(item)">
<img v-if="item.type === 'emoticon'" :src="item.src" :title="item.name" :alt="item.name"/> <img v-if="item.type === 'emoticon'" :src="item.src" :title="item.name" :alt="item.name"/>
<span v-else v-html="item.html" :title="item.name"></span> <span v-else v-html="item.html" :title="item.name"></span>
@ -8,7 +8,7 @@
</ul> </ul>
<ul class="chat-emoji-menu"> <ul class="chat-emoji-menu">
<li :class="{active: type === 'emoji'}" @click="type='emoji'"> <li :class="{active: type === 'emoji'}" @click="type='emoji'">
<span class="no-dark-mode">&#128512;</span> <span class="no-dark-content">&#128512;</span>
</li> </li>
<li v-for="item in emoticonList" :class="{active: type === 'emoticon' && emoticonPath == item.path}" @click="onEmoticon(item.path)"> <li v-for="item in emoticonList" :class="{active: type === 'emoticon' && emoticonPath == item.path}" @click="onEmoticon(item.path)">
<img :title="item.name" :alt="item.name" :src="item.src"/> <img :title="item.name" :alt="item.name" :src="item.src"/>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="chat-input-wrapper" :class="modeClass"> <div class="chat-input-wrapper" :class="modeClass">
<div ref="editor" class="no-dark-mode"></div> <div ref="editor" class="no-dark-content"></div>
<div class="chat-input-toolbar"> <div class="chat-input-toolbar">
<slot name="toolbarBefore"/> <slot name="toolbarBefore"/>

View File

@ -9,7 +9,7 @@
<!--详情--> <!--详情-->
<div class="dialog-content" :class="contentClass"> <div class="dialog-content" :class="contentClass">
<!--文本--> <!--文本-->
<div v-if="msgData.type === 'text'" class="content-text"> <div v-if="msgData.type === 'text'" class="content-text no-dark-content">
<pre @click="viewText" v-html="textMsg(msgData.msg.text)"></pre> <pre @click="viewText" v-html="textMsg(msgData.msg.text)"></pre>
</div> </div>
<!--文件--> <!--文件-->

View File

@ -116,12 +116,12 @@
:ok-text="$L('发送')" :ok-text="$L('发送')"
:enter-ok="true" :enter-ok="true"
@on-ok="pasteSend"> @on-ok="pasteSend">
<div class="dialog-wrapper-paste"> <ul class="dialog-wrapper-paste" :class="pasteWrapperClass">
<template v-for="item in pasteItem"> <li v-for="item in pasteItem">
<img v-if="item.type == 'image'" :src="item.result"/> <img v-if="item.type == 'image'" :src="item.result"/>
<div v-else>{{$L('文件')}}: {{item.name}} ({{$A.bytesToSize(item.size)}})</div> <div v-else>{{$L('文件')}}: {{item.name}} ({{$A.bytesToSize(item.size)}})</div>
</template> </li>
</div> </ul>
</Modal> </Modal>
<!--创建群组--> <!--创建群组-->
@ -268,6 +268,13 @@ export default {
return '发送图片' return '发送图片'
} }
return '发送文件' return '发送文件'
},
pasteWrapperClass() {
if (this.pasteItem.find(({type}) => type !== 'image')) {
return ['multiple'];
}
return [];
} }
}, },

View File

@ -31,13 +31,16 @@
<span v-if="item.share && item.permission == 0" class="readonly">{{$L('只读')}}</span> <span v-if="item.share && item.permission == 0" class="readonly">{{$L('只读')}}</span>
</li> </li>
</ul> </ul>
<Button v-if="shearFirst" :disabled="shearFirst.pid == pid" size="small" type="primary" @click="shearTo"> <template v-if="shearFirst">
<Button :disabled="shearFirst.pid == pid" size="small" type="primary" @click="shearTo">
<div class="file-shear"> <div class="file-shear">
<span>{{$L('粘贴')}}</span> <span>{{$L('粘贴')}}</span>
"<em>{{shearFirst.name}}</em>" "<em>{{shearFirst.name}}</em>"
<span v-if="shearIds.length > 1">{{$L('')}}{{shearIds.length}}{{$L('个文件')}}</span> <span v-if="shearIds.length > 1">{{$L('')}}{{shearIds.length}}{{$L('个文件')}}</span>
</div> </div>
</Button> </Button>
<Button type="primary" size="small" @click="clearShear">{{ $L('取消剪切') }}</Button>
</template>
<template v-else-if="selectIds.length > 0"> <template v-else-if="selectIds.length > 0">
<Button size="small" type="info" @click="handleContextClick('shearSelect')"> <Button size="small" type="info" @click="handleContextClick('shearSelect')">
<Icon type="ios-cut" /> <Icon type="ios-cut" />
@ -83,12 +86,12 @@
<div class="file-menu" @click.stop="handleRightClick($event, item)"> <div class="file-menu" @click.stop="handleRightClick($event, item)">
<Icon type="ios-more" /> <Icon type="ios-more" />
</div> </div>
<div :class="`no-dark-mode-before file-icon ${item.type}`"> <div :class="`no-dark-before file-icon ${item.type}`">
<template v-if="item.share"> <template v-if="item.share">
<UserAvatar v-if="item.userid != userId" :userid="item.userid" class="share-avatar" :size="20"> <UserAvatar v-if="item.userid != userId" :userid="item.userid" class="share-avatar" :size="20">
<p>{{$L('共享权限')}}: {{$L(item.permission == 1 ? '读/写' : '只读')}}</p> <p>{{$L('共享权限')}}: {{$L(item.permission == 1 ? '读/写' : '只读')}}</p>
</UserAvatar> </UserAvatar>
<div v-else class="share-icon no-dark-mode"> <div v-else class="share-icon no-dark-content">
<i class="taskfont">&#xe757;</i> <i class="taskfont">&#xe757;</i>
</div> </div>
</template> </template>
@ -159,7 +162,7 @@
:key="key" :key="key"
:divided="!!type.divided" :divided="!!type.divided"
@click.native="addFile(type.value)"> @click.native="addFile(type.value)">
<div :class="`no-dark-mode-before file-item file-icon ${type.value}`">{{$L(type.label)}}</div> <div :class="`no-dark-before file-item file-icon ${type.value}`">{{$L(type.label)}}</div>
</DropdownItem> </DropdownItem>
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
@ -182,7 +185,7 @@
:key="key" :key="key"
:divided="!!type.divided" :divided="!!type.divided"
@click.native="addFile(type.value)"> @click.native="addFile(type.value)">
<div :class="`no-dark-mode-before file-item file-icon ${type.value}`">{{$L(type.label)}}</div> <div :class="`no-dark-before file-item file-icon ${type.value}`">{{$L(type.label)}}</div>
</DropdownItem> </DropdownItem>
</template> </template>
</DropdownMenu> </DropdownMenu>
@ -347,12 +350,12 @@
:ok-text="$L('立即上传')" :ok-text="$L('立即上传')"
:enter-ok="true" :enter-ok="true"
@on-ok="pasteSend"> @on-ok="pasteSend">
<div class="dialog-wrapper-paste"> <ul class="dialog-wrapper-paste" :class="pasteWrapperClass">
<template v-for="item in pasteItem"> <li v-for="item in pasteItem">
<img v-if="item.type == 'image'" :src="item.result"/> <img v-if="item.type == 'image'" :src="item.result"/>
<div v-else>{{$L('文件')}}: {{item.name}} ({{$A.bytesToSize(item.size)}})</div> <div v-else>{{$L('文件')}}: {{item.name}} ({{$A.bytesToSize(item.size)}})</div>
</template> </li>
</div> </ul>
</Modal> </Modal>
</div> </div>
</template> </template>
@ -596,6 +599,13 @@ export default {
return '上传图片' return '上传图片'
} }
return '上传文件' return '上传文件'
},
pasteWrapperClass() {
if (this.pasteItem.find(({type}) => type !== 'image')) {
return ['multiple'];
}
return [];
} }
}, },
@ -704,7 +714,7 @@ export default {
class: 'file-nbox' class: 'file-nbox'
}, [ }, [
h('div', { h('div', {
class: `no-dark-mode-before file-name file-icon ${row.type}`, class: `no-dark-before file-name file-icon ${row.type}`,
}, array), }, array),
]); ]);
} else { } else {
@ -768,7 +778,7 @@ export default {
class: `file-nbox ${this.shearIds.includes(row.id) ? 'shear' : ''}`, class: `file-nbox ${this.shearIds.includes(row.id) ? 'shear' : ''}`,
}, [ }, [
h('div', { h('div', {
class: `no-dark-mode-before file-name file-icon ${row.type}`, class: `no-dark-before file-name file-icon ${row.type}`,
}, array), }, array),
iconArray iconArray
]); ]);
@ -799,7 +809,7 @@ export default {
if (type) { if (type) {
return h('AutoTip', type.name); return h('AutoTip', type.name);
} else { } else {
return h('div', row.ext || row.type) return h('div', (row.ext || row.type).toUpperCase())
} }
} }
}, },
@ -1430,6 +1440,10 @@ export default {
return $A.getObject(item, 'response.data.full_name') || item.name return $A.getObject(item, 'response.data.full_name') || item.name
}, },
handleTableSort({key, order}) {
$A.setStorage("cacheFileSort", ['asc', 'desc'].includes(order) ? {key, order} : {});
},
handleTableSelect(selection) { handleTableSelect(selection) {
this.selectIds = selection.map(item => item.id); this.selectIds = selection.map(item => item.id);
}, },
@ -1438,8 +1452,8 @@ export default {
this.selectIds = []; this.selectIds = [];
}, },
handleTableSort({key, order}) { clearShear() {
$A.setStorage("cacheFileSort", ['asc', 'desc'].includes(order) ? {key, order} : {}); this.shearIds = [];
}, },
/********************拖动上传部分************************/ /********************拖动上传部分************************/

View File

@ -58,7 +58,7 @@
<Icon v-if="dialog.type == 'user' && lastMsgReadDone(dialog.last_msg)" :type="lastMsgReadDone(dialog.last_msg)"/> <Icon v-if="dialog.type == 'user' && lastMsgReadDone(dialog.last_msg)" :type="lastMsgReadDone(dialog.last_msg)"/>
<em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em> <em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em>
</div> </div>
<div class="dialog-text no-dark-mode"> <div class="dialog-text no-dark-content">
<template v-if="dialog.type=='group' && dialog.last_msg"> <template v-if="dialog.type=='group' && dialog.last_msg">
<div v-if="dialog.last_msg.userid == userId" class="last-self">{{$L('')}}</div> <div v-if="dialog.last_msg.userid == userId" class="last-self">{{$L('')}}</div>
<UserAvatar v-else :userid="dialog.last_msg.userid" :show-name="true" :show-icon="false"/> <UserAvatar v-else :userid="dialog.last_msg.userid" :show-name="true" :show-icon="false"/>

View File

@ -711,11 +711,21 @@
} }
.dialog-wrapper-paste { .dialog-wrapper-paste {
margin-top: -4px; display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&.multiple {
display: block;
}
> li {
list-style: none;
img { img {
max-width: 100%; max-width: 100%;
max-height: 1000px; max-height: 500px;
} }
> div, > div,
@ -723,7 +733,11 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0; padding: 0;
margin: 4px 0; }
+ li {
margin-top: 20px;
}
} }
} }

View File

@ -94,6 +94,12 @@
color: #fff; color: #fff;
font-size: 36px; font-size: 36px;
} }
.header-nav-dropdown-item {
display: flex;
align-items: center;
justify-content: space-between;
}
} }
} }