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) {
return createElement('div', {
class: "no-dark-mode"
class: "no-dark-content"
})
},
data: () => ({

View File

@ -1,6 +1,7 @@
<template>
<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>
</template>
@ -15,11 +16,13 @@
display: flex;
align-items: center;
justify-content: center;
.placeholder {
flex: 1;
width: 100%;
height: 100%;
}
.office-loading {
position: absolute;
top: 0;
@ -33,6 +36,26 @@
}
}
</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>
import {mapState} from "vuex";
@ -66,6 +89,7 @@ export default {
data() {
return {
loadIng: 0,
loadError: false,
docEditor: null,
}
@ -101,10 +125,11 @@ export default {
return;
}
this.loadIng++;
this.loadError = false;
$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"), (e) => {
this.loadIng--;
if (e !== null) {
$A.modalAlert("组件加载失败!");
this.loadError = true;
return;
}
if (!this.documentKey) {

View File

@ -1,131 +1,141 @@
<template>
<div ref="view" class="common-preview-view no-dark-mode">
<template v-if="!isSingle">
<div class="preview-view-prev" :class="{ 'is-disabled': !infinite && isFirst }" @click="prev">
<i class="taskfont">&#xe72d;</i>
<div ref="view" class="common-preview-image">
<div class="common-preview-view no-dark-content">
<template v-if="!isSingle">
<div class="preview-view-prev" :class="{ 'is-disabled': !infinite && isFirst }" @click="prev">
<i class="taskfont">&#xe72d;</i>
</div>
<div class="preview-view-next" :class="{ 'is-disabled': !infinite && isLast }" @click="next">
<i class="taskfont">&#xe733;</i>
</div>
</template>
<div class="preview-view-actions">
<div class="actions-inner">
<i class="taskfont" @click="handleActions('zoomOut')">&#xe7a2;</i>
<i class="taskfont" @click="handleActions('zoomIn')">&#xe79f;</i>
<i class="actions-divider"></i>
<i class="taskfont" @click="toggleMode" v-html="mode.icon"></i>
<i class="actions-divider"></i>
<i class="taskfont" @click="handleActions('anticlocelise')">&#xe7a7;</i>
<i class="taskfont" @click="handleActions('clocelise')">&#xe7a6;</i>
</div>
</div>
<div class="preview-view-next" :class="{ 'is-disabled': !infinite && isLast }" @click="next">
<i class="taskfont">&#xe733;</i>
<div class="preview-view-canvas">
<img
v-for="(url, i) in urlList"
v-if="i === index"
ref="img"
class="preview-view-img"
:key="url"
:src="currentImg"
:style="imgStyle"
@load="handleImgLoad"
@error="handleImgError"
@mousedown="handleMouseDown">
</div>
</template>
<div class="preview-view-actions">
<div class="actions-inner">
<i class="taskfont" @click="handleActions('zoomOut')">&#xe7a2;</i>
<i class="taskfont" @click="handleActions('zoomIn')">&#xe79f;</i>
<i class="actions-divider"></i>
<i class="taskfont" @click="toggleMode" v-html="mode.icon"></i>
<i class="actions-divider"></i>
<i class="taskfont" @click="handleActions('anticlocelise')">&#xe7a7;</i>
<i class="taskfont" @click="handleActions('clocelise')">&#xe7a6;</i>
</div>
</div>
<div class="preview-view-canvas no-dark-mode">
<img
v-for="(url, i) in urlList"
v-if="i === index"
ref="img"
class="preview-view-img"
:key="url"
:src="currentImg"
:style="imgStyle"
@load="handleImgLoad"
@error="handleImgError"
@mousedown="handleMouseDown">
</div>
</div>
</template>
<style lang="scss" scoped>
.common-preview-view {
.common-preview-image {
position: fixed;
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
background: rgba(0, 0, 0, .8);
backdrop-filter: blur(4px);
.preview-view-prev,
.preview-view-next {
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
opacity: .8;
cursor: pointer;
background-color: #606266;
border-color: #fff;
height: 44px;
width: 44px;
overflow: hidden;
.common-preview-view {
position: absolute;
top: 50%;
z-index: 2;
transform: translateY(-50%);
bottom: 0;
left: 0;
right: 0;
top: 0;
background: rgba(0, 0, 0, .8);
&.is-disabled {
cursor: no-drop;
.preview-view-prev,
.preview-view-next {
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
opacity: .8;
cursor: pointer;
background-color: #606266;
border-color: #fff;
height: 44px;
width: 44px;
overflow: hidden;
position: absolute;
top: 50%;
z-index: 2;
transform: translateY(-50%);
&.is-disabled {
cursor: no-drop;
> i {
opacity: 0.8;
}
}
> i {
opacity: 0.8;
color: #fff;
font-size: 24px;
}
}
> i {
color: #fff;
font-size: 24px;
.preview-view-prev {
left: 40px;
}
}
.preview-view-prev {
left: 40px;
}
.preview-view-next {
right: 40px;
}
.preview-view-next {
right: 40px;
}
.preview-view-actions {
display: flex;
align-items: center;
justify-content: center;
opacity: .8;
background-color: #606266;
border-color: #fff;
border-radius: 22px;
bottom: 30px;
height: 44px;
position: absolute;
left: 50%;
z-index: 2;
padding: 0 23px;
transform: translateX(-50%);
width: 282px;
.actions-inner {
.preview-view-actions {
display: flex;
align-items: center;
justify-content: center;
opacity: .8;
background-color: #606266;
border-color: #fff;
border-radius: 22px;
bottom: 30px;
height: 44px;
position: absolute;
left: 50%;
z-index: 2;
padding: 0 23px;
transform: translateX(-50%);
width: 282px;
.actions-inner {
align-items: center;
color: #fff;
cursor: default;
display: flex;
height: 100%;
justify-content: space-around;
text-align: justify;
width: 100%;
> i {
cursor: pointer;
font-size: 23px;
}
}
}
.preview-view-canvas {
align-items: center;
color: #fff;
cursor: default;
display: flex;
height: 100%;
justify-content: space-around;
text-align: justify;
justify-content: center;
width: 100%;
> i {
cursor: pointer;
font-size: 23px;
}
}
}
.preview-view-canvas {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
width: 100%;
}
}
</style>
@ -221,7 +231,10 @@ export default {
this.onSwitch(val);
}
},
currentImg(val) {
initialIndex(index) {
this.index = index
},
currentImg() {
this.$nextTick(_ => {
const $img = this.$refs.img[0];
if (!$img.complete) {

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<div class="page-login">
<PageTitle :title="$L('登录')"/>
<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-title">{{welcomeTitle}}</div>

View File

@ -1,6 +1,6 @@
<template>
<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)">
<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>
@ -8,7 +8,7 @@
</ul>
<ul class="chat-emoji-menu">
<li :class="{active: type === 'emoji'}" @click="type='emoji'">
<span class="no-dark-mode">&#128512;</span>
<span class="no-dark-content">&#128512;</span>
</li>
<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"/>

View File

@ -1,6 +1,6 @@
<template>
<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">
<slot name="toolbarBefore"/>

View File

@ -9,7 +9,7 @@
<!--详情-->
<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>
</div>
<!--文件-->

View File

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

View File

@ -58,7 +58,7 @@
<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>
</div>
<div class="dialog-text no-dark-mode">
<div class="dialog-text no-dark-content">
<template v-if="dialog.type=='group' && dialog.last_msg">
<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"/>

View File

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

View File

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