mirror of
https://github.com/doocs/md.git
synced 2024-11-24 19:10:34 +08:00
Merge pull request #17 from doocs/feature-night-mode
Feature night mode
This commit is contained in:
commit
32cd4f63d6
@ -155,7 +155,7 @@ section {
|
||||
margin: 10px 8px;
|
||||
color: #333;
|
||||
position: relative;
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
background-color: rgb(238,238,238);
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
@ -228,6 +228,6 @@ section {
|
||||
}
|
||||
|
||||
.CodeMirror-scroll, .preview-wrapper {
|
||||
overflow: unset!important;
|
||||
overflow-y: scroll!important;
|
||||
overflow: unset;
|
||||
overflow-y: scroll;
|
||||
}
|
BIN
src/assets/images/favicon.png
Normal file
BIN
src/assets/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -20,13 +20,18 @@
|
||||
background-color: @nightCodeMirrorColor;
|
||||
box-shadow: inset 0 0 0 1px rgba(100, 37, 37, 0.102);
|
||||
}
|
||||
.preview {
|
||||
background-color: @nightPreviewColor;
|
||||
box-shadow: 0 0 70px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.preview-wrapper {
|
||||
background-color: @nightCodeMirrorColor;
|
||||
box-shadow: inset 0 0 0 1px rgba(233, 231, 231, 0.102);
|
||||
.output_night {
|
||||
.preview {
|
||||
background-color: @nightPreviewColor;
|
||||
box-shadow: 0 0 70px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.preview-wrapper {
|
||||
background-color: @nightCodeMirrorColor;
|
||||
box-shadow: inset 0 0 0 1px rgba(233, 231, 231, 0.102);
|
||||
}
|
||||
.code-snippet__fix {
|
||||
background-color: rgb(238,238,238);
|
||||
}
|
||||
}
|
||||
.cm-s-style-mirror .CodeMirror-matchingbracket {
|
||||
color: @nightWhiteColor!important;
|
||||
@ -60,7 +65,7 @@
|
||||
color: @nightWhiteColor;
|
||||
}
|
||||
}
|
||||
.insert__dialog, .about__dialog {
|
||||
.insert__dialog, .about__dialog, .reset__dialog {
|
||||
.el-dialog {
|
||||
background-color: @nightBgColor;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
<div class="mode__switch" v-if="!nightMode" @click="themeChanged"></div>
|
||||
<div class="mode__switch mode__switch_black" v-else @click="themeChanged"></div>
|
||||
</el-tooltip>
|
||||
<resetDialog :showResetConfirm="showResetConfirm" @confirm="confirmReset" @close="cancelReset"/>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
@ -81,6 +82,7 @@ import {
|
||||
} from '../../scripts/converter'
|
||||
import config from '../../scripts/config'
|
||||
import DEFAULT_CSS_CONTENT from '../../scripts/themes/default-theme-css'
|
||||
import resetDialog from '../codeMirror/resetDialog'
|
||||
import {mapState, mapMutations} from 'vuex'
|
||||
export default {
|
||||
name: 'editor-header',
|
||||
@ -88,11 +90,15 @@ export default {
|
||||
return {
|
||||
config: config,
|
||||
citeStatus: false,
|
||||
showResetConfirm: false,
|
||||
selectFont: '',
|
||||
selectSize: '',
|
||||
selectColor: ''
|
||||
};
|
||||
},
|
||||
components: {
|
||||
resetDialog
|
||||
},
|
||||
computed: {
|
||||
effect() {
|
||||
return this.nightMode ? 'dark' : 'light'
|
||||
@ -165,28 +171,32 @@ export default {
|
||||
},
|
||||
// 复制到微信公众号
|
||||
copy() {
|
||||
let clipboardDiv = document.getElementById('output')
|
||||
solveWeChatImage()
|
||||
this.setHtml(solveHtml())
|
||||
this.$emit('startCopy');
|
||||
setTimeout(() => {
|
||||
let clipboardDiv = document.getElementById('output')
|
||||
solveWeChatImage()
|
||||
this.setHtml(solveHtml(this.nightMode))
|
||||
|
||||
clipboardDiv.focus()
|
||||
window.getSelection().removeAllRanges()
|
||||
let range = document.createRange()
|
||||
clipboardDiv.focus()
|
||||
window.getSelection().removeAllRanges()
|
||||
let range = document.createRange()
|
||||
|
||||
range.setStartBefore(clipboardDiv.firstChild)
|
||||
range.setEndAfter(clipboardDiv.lastChild)
|
||||
window.getSelection().addRange(range)
|
||||
document.execCommand('copy')
|
||||
// 输出提示
|
||||
this.$notify({
|
||||
showClose: true,
|
||||
message: '已复制渲染后的文章到剪贴板,可直接到公众号后台粘贴',
|
||||
offset: 80,
|
||||
duration: 1600,
|
||||
type: 'success'
|
||||
})
|
||||
clipboardDiv.innerHTML = this.output; // 恢复现场
|
||||
this.$emit('refresh')
|
||||
range.setStartBefore(clipboardDiv.firstChild)
|
||||
range.setEndAfter(clipboardDiv.lastChild)
|
||||
window.getSelection().addRange(range)
|
||||
document.execCommand('copy')
|
||||
// 输出提示
|
||||
this.$notify({
|
||||
showClose: true,
|
||||
message: '已复制渲染后的文章到剪贴板,可直接到公众号后台粘贴',
|
||||
offset: 80,
|
||||
duration: 1600,
|
||||
type: 'success'
|
||||
})
|
||||
clipboardDiv.innerHTML = this.output; // 恢复现场
|
||||
this.$emit('refresh');
|
||||
this.$emit('endCopy');
|
||||
}, 350);
|
||||
},
|
||||
// 自定义CSS样式
|
||||
async customStyle () {
|
||||
@ -207,26 +217,22 @@ export default {
|
||||
},
|
||||
// 重置页面
|
||||
reset() {
|
||||
this.$confirm('此操作将丢失本地缓存的文本和自定义样式,是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonClass: 'el-button--success',
|
||||
cancelButtonClass: 'el-button--success is-plain',
|
||||
type: 'warning',
|
||||
center: true
|
||||
}).then(() => {
|
||||
localStorage.clear()
|
||||
this.clearEditorToDefault();
|
||||
this.editor.focus()
|
||||
this.citeStatus = false;
|
||||
this.statusChanged(false);
|
||||
this.fontChanged(this.config.builtinFonts[0].value)
|
||||
this.colorChanged(this.config.colorOption[1].value)
|
||||
this.sizeChanged(this.config.sizeOption[2].value)
|
||||
this.$emit('cssChanged')
|
||||
}).catch(() => {
|
||||
this.editor.focus()
|
||||
})
|
||||
this.showResetConfirm = true;
|
||||
},
|
||||
confirmReset() {
|
||||
localStorage.clear()
|
||||
this.clearEditorToDefault();
|
||||
this.editor.focus()
|
||||
this.citeStatus = false;
|
||||
this.statusChanged(false);
|
||||
this.fontChanged(this.config.builtinFonts[0].value)
|
||||
this.colorChanged(this.config.colorOption[1].value)
|
||||
this.sizeChanged(this.config.sizeOption[2].value)
|
||||
this.$emit('cssChanged')
|
||||
},
|
||||
cancelReset() {
|
||||
this.showResetConfirm = false;
|
||||
this.editor.focus()
|
||||
},
|
||||
// 下载编辑器内容到本地
|
||||
downloadEditorContent () {
|
||||
|
43
src/components/codeMirror/resetDialog.vue
Normal file
43
src/components/codeMirror/resetDialog.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<el-dialog title="提示" class="reset__dialog" :visible="showResetConfirm" @close="$emit('close')">
|
||||
<div class="text">
|
||||
此操作将丢失本地缓存的文本和自定义样式,是否继续?
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :type="btnType" plain @click="$emit('close')">取 消</el-button>
|
||||
<el-button :type="btnType" @click="$emit('confirm')" plain>确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex';
|
||||
export default {
|
||||
props: {
|
||||
showResetConfirm: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
btnType() {
|
||||
return !this.nightMode ? 'success' : 'default';
|
||||
},
|
||||
...mapState({
|
||||
nightMode: state=> state.nightMode
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.reset__dialog {
|
||||
text-align: center;
|
||||
}
|
||||
.text {
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -13,9 +13,9 @@ export function solveWeChatImage() {
|
||||
image.style.height = height;
|
||||
}
|
||||
}
|
||||
export function solveHtml() {
|
||||
export function solveHtml(nightMode = false) {
|
||||
const element = document.getElementById("output-wrapper");
|
||||
let html = element.innerHTML;
|
||||
let html = element.innerHTML
|
||||
let res = "";
|
||||
res = juice.inlineContent(
|
||||
html,
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="container" :class="{'container_night': nightMode}">
|
||||
<el-container>
|
||||
<el-header class="editor__header is-dark">
|
||||
<el-header class="editor__header">
|
||||
<editor-header
|
||||
@refresh="onEditorRefresh"
|
||||
@uploaded="uploaded"
|
||||
@ -9,6 +9,8 @@
|
||||
@showBox="showBox = !showBox"
|
||||
@showAboutDialog="aboutDialogVisible = true"
|
||||
@showDialogForm="dialogFormVisible = true"
|
||||
@startCopy="isCoping = true, backLight = true"
|
||||
@endCopy="endCopy"
|
||||
/>
|
||||
</el-header>
|
||||
<el-main class="main-body">
|
||||
@ -17,11 +19,15 @@
|
||||
<textarea id="editor" type="textarea" placeholder="Your markdown text here." v-model="source">
|
||||
</textarea>
|
||||
</el-col>
|
||||
<el-col :span="12" class="preview-wrapper" id="preview">
|
||||
<section id="output-wrapper" >
|
||||
<el-col :span="12" class="preview-wrapper" id="preview" :class="{'preview-wrapper_night': nightMode && isCoping}">
|
||||
<section id="output-wrapper" :class="{'output_night': nightMode && !backLight}">
|
||||
<div class="preview">
|
||||
<section id="output" v-html="output">
|
||||
</section>
|
||||
<div class="loading-mask" v-if="nightMode && isCoping">
|
||||
<div class="loading__img"></div>
|
||||
<span>正在生成</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</el-col>
|
||||
@ -77,6 +83,8 @@ export default {
|
||||
showBox: false,
|
||||
aboutDialogVisible: false,
|
||||
dialogFormVisible: false,
|
||||
isCoping: false,
|
||||
backLight: false,
|
||||
timeout: null,
|
||||
changeTimer: null,
|
||||
source: ''
|
||||
@ -232,6 +240,12 @@ export default {
|
||||
this.editorRefresh();
|
||||
setTimeout(()=> PR.prettyPrint(), 0);
|
||||
},
|
||||
endCopy() {
|
||||
this.backLight = false;
|
||||
setTimeout(()=> {
|
||||
this.isCoping = false;
|
||||
}, 800);
|
||||
},
|
||||
...mapMutations(['initEditorState', 'initEditorEntity', 'setWxRendererOptions',
|
||||
'editorRefresh', 'initCssEditorEntity'])
|
||||
},
|
||||
@ -258,4 +272,47 @@ export default {
|
||||
.container {
|
||||
transition: all .3s;
|
||||
}
|
||||
.preview {
|
||||
transition: background 0s;
|
||||
transition-delay: .2s;
|
||||
}
|
||||
.preview-wrapper_night {
|
||||
overflow-y: inherit;
|
||||
position: relative;
|
||||
left: -3px;
|
||||
.preview {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
#output-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.loading-mask {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 376px;
|
||||
height: 101%;
|
||||
padding-top: 1px;
|
||||
font-size: 15px;
|
||||
color: gray;
|
||||
background-color: #1e1e1e;
|
||||
.loading__img {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 330px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
transform: translate(-50%, -50%);
|
||||
background: url('../assets/images/favicon.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
span {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 390px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user