mirror of
https://github.com/purocean/yn.git
synced 2026-09-24 15:46:02 +08:00
feat: add action bar
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<div class="action-bar">
|
||||
<div class="btns">
|
||||
<div>
|
||||
<div class="btn flat" @click="toggleOutline()" :title="$t(showOutline ? 'files' : 'outline')">
|
||||
<svg-icon v-if="showOutline" name="folder-tree-solid" />
|
||||
<svg-icon v-else name="list" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">{{$t(showOutline ? 'outline' : 'files')}}</div>
|
||||
<div class="btns" v-if="navigation">
|
||||
<div v-for="(item, i) in navigation.items" :key="i">
|
||||
<div
|
||||
v-if="item.showInActionBar && item.type === 'btn'"
|
||||
:class="{ btn: true, flat: item.flat, disabled: item.disabled, checked: item.checked }"
|
||||
:title="item.title"
|
||||
@click.stop="item.onClick"
|
||||
>
|
||||
<svg-icon :name="item.icon" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, ref, toRef } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { registerAction, removeAction } from '@fe/core/action'
|
||||
import { getSchema, Schema } from '@fe/services/control-center'
|
||||
import type { AppState } from '@fe/support/store'
|
||||
import SvgIcon from './SvgIcon.vue'
|
||||
import { useI18n } from '@fe/services/i18n'
|
||||
import { toggleOutline } from '@fe/services/layout'
|
||||
|
||||
const store = useStore<AppState>()
|
||||
const navigation = ref<Schema['navigation']>()
|
||||
const showOutline = toRef(store.state, 'showOutline')
|
||||
|
||||
useI18n()
|
||||
|
||||
registerAction({
|
||||
name: 'action-bar.refresh',
|
||||
handler () {
|
||||
navigation.value = getSchema().navigation
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
removeAction('action-bar.refresh')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@fe/styles/mixins.scss';
|
||||
|
||||
.action-bar {
|
||||
height: 30px;
|
||||
flex: none;
|
||||
border-bottom: 1px solid var(--g-color-87);
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
& > .title {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: var(--g-color-20);
|
||||
z-index: -1;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: var(--g-color-20);
|
||||
border-radius: var(--g-border-radius);
|
||||
margin: 4px;
|
||||
transition: .1s ease-in-out;
|
||||
|
||||
&.flat {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.checked {
|
||||
background: var(--g-color-96);
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:not(.disabled):not(.checked):hover {
|
||||
background: var(--g-color-92);
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: var(--g-color-50);
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include dark-theme {
|
||||
.action-bar {
|
||||
.btn {
|
||||
&.checked {
|
||||
background: var(--g-color-60);
|
||||
}
|
||||
|
||||
&:not(.disabled):not(.checked):hover {
|
||||
background: var(--g-color-76);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -231,6 +231,18 @@ export default defineComponent({
|
||||
flex: none;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--g-color-86);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--g-color-98);
|
||||
|
||||
::v-deep(.action-bar .btns) {
|
||||
opacity: 0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
&:hover ::v-deep(.action-bar .btns) {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.sash-right {
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div class="outline-toc">
|
||||
<div v-if="(headings || heads).length < 1" class="empty">Empty</div>
|
||||
<div
|
||||
class="heading"
|
||||
v-for="(head, index) in (headings || heads)"
|
||||
:key="index"
|
||||
:class="head.class"
|
||||
:style="{paddingLeft: `${head.level + 1}em`}"
|
||||
@click="handleClickItem(head)">
|
||||
{{ head.text }}
|
||||
<span class="tag-name">{{head.tag}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { registerHook, removeHook } from '@fe/core/hook'
|
||||
import { revealLineInCenter } from '@fe/services/editor'
|
||||
import { getHeadings, Heading } from '@fe/services/view'
|
||||
import { defineComponent, onBeforeUnmount, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'outline',
|
||||
props: {
|
||||
headings: Array as () => Heading[],
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
setup (props, { emit }) {
|
||||
function handleClickItem (heading: Heading) {
|
||||
emit('click-item', heading)
|
||||
if (props.autoScroll) {
|
||||
revealLineInCenter(heading.sourceLine)
|
||||
}
|
||||
}
|
||||
|
||||
const heads = ref<Heading[]>([])
|
||||
|
||||
function refresh () {
|
||||
if (props.headings) {
|
||||
heads.value = []
|
||||
} else {
|
||||
heads.value = getHeadings()
|
||||
}
|
||||
}
|
||||
|
||||
registerHook('VIEW_RENDERED', refresh)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
removeHook('VIEW_RENDERED', refresh)
|
||||
})
|
||||
|
||||
return { heads, handleClickItem }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@fe/styles/mixins.scss';
|
||||
|
||||
.outline-toc {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 16px;
|
||||
user-select: none;
|
||||
|
||||
& > .empty {
|
||||
text-align: center;
|
||||
padding-top: 4em;
|
||||
font-size: 20px;
|
||||
color: var(--g-color-40);
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
& > .heading {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding: 7px .5em;
|
||||
display: flex;
|
||||
border-radius: var(--g-border-radius);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
&.tag-h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tag-name {
|
||||
color: var(--g-color-60);
|
||||
font-size: 12px;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include dark-theme {
|
||||
.outline-toc > .heading:hover {
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -26,15 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="catalog" :style="{maxHeight: `min(${(height - 120) + 'px'}, 70vh)`}">
|
||||
<div
|
||||
v-for="(head, index) in heads"
|
||||
:key="index"
|
||||
:class="head.class"
|
||||
:style="{paddingLeft: `${head.level + 1}em`}"
|
||||
@click="syncScroll(head.sourceLine)">
|
||||
{{ head.text }}
|
||||
<span class="tag-name">{{head.tag}}</span>
|
||||
</div>
|
||||
<Outline :headings="heads" :auto-scroll="false" @click-item="(head: any) => syncScroll(head.sourceLine)" />
|
||||
</div>
|
||||
</div>
|
||||
<div :class="{'scroll-to-top': true, 'hide': scrollTop < 30}" :style="scrollToTopStyle" @click="scrollToTop">TOP</div>
|
||||
@@ -55,7 +47,7 @@ import { registerHook, removeHook, triggerHook } from '@fe/core/hook'
|
||||
import { registerAction, removeAction } from '@fe/core/action'
|
||||
import { revealLineInCenter } from '@fe/services/editor'
|
||||
import { showExport, toUri } from '@fe/services/document'
|
||||
import { getContextMenuItems } from '@fe/services/view'
|
||||
import { getContextMenuItems, getHeadings, Heading } from '@fe/services/view'
|
||||
import { useContextMenu } from '@fe/support/ui/context-menu'
|
||||
import { DOM_ATTR_NAME } from '@fe/support/constant'
|
||||
import { useI18n } from '@fe/services/i18n'
|
||||
@@ -64,6 +56,7 @@ import type { RenderEnv } from '@fe/types'
|
||||
|
||||
import Render from './Render.vue'
|
||||
import SvgIcon from './SvgIcon.vue'
|
||||
import Outline from './Outline.vue'
|
||||
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import 'katex/dist/katex.min.css'
|
||||
@@ -72,7 +65,7 @@ const logger = getLogger('preview')
|
||||
|
||||
export default defineComponent({
|
||||
name: 'xview',
|
||||
components: { Render, SvgIcon },
|
||||
components: { Render, SvgIcon, Outline },
|
||||
setup () {
|
||||
useI18n()
|
||||
|
||||
@@ -93,13 +86,7 @@ export default defineComponent({
|
||||
|
||||
const width = ref(1024)
|
||||
const height = ref(1024)
|
||||
const heads = ref<{
|
||||
tag: string;
|
||||
class: string[];
|
||||
text: string;
|
||||
level: number;
|
||||
sourceLine: number;
|
||||
}[]>([])
|
||||
const heads = ref<Heading[]>([])
|
||||
const todoCount = ref(0)
|
||||
const todoDoneCount = ref(0)
|
||||
const scrollTop = ref(0)
|
||||
@@ -122,18 +109,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function updateOutline () {
|
||||
const tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
|
||||
const nodes = refView.value!.querySelectorAll<HTMLHeadElement>(tags.join(','))
|
||||
heads.value = Array.from(nodes).map(node => {
|
||||
const tag = node.tagName.toLowerCase()
|
||||
return {
|
||||
tag,
|
||||
class: [...node.classList, 'tag-' + tag],
|
||||
text: node.innerText,
|
||||
level: tags.indexOf(tag),
|
||||
sourceLine: parseInt(node.dataset.sourceLine || '0')
|
||||
}
|
||||
})
|
||||
heads.value = getHeadings()
|
||||
}
|
||||
|
||||
function updateTodoCount () {
|
||||
@@ -447,25 +423,6 @@ export default defineComponent({
|
||||
cursor: pointer;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 1em;
|
||||
|
||||
& > div {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding: 7px .5em;
|
||||
display: flex;
|
||||
border-radius: var(--g-border-radius);
|
||||
|
||||
&:hover {
|
||||
background: var(--g-color-75);
|
||||
}
|
||||
|
||||
.tag-name {
|
||||
color: var(--g-color-60);
|
||||
font-size: 12px;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.outline-title {
|
||||
|
||||
@@ -48,6 +48,7 @@ export default defineComponent({
|
||||
'star-solid': '<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="star" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-star fa-w-18"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class=""></path></svg>',
|
||||
'star-regular': '<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="star" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-star fa-w-18"><path fill="currentColor" d="M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z" class=""></path></svg>',
|
||||
'pen-solid': '<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="pen" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-pen fa-w-16"><path fill="currentColor" d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z" class=""></path></svg>',
|
||||
'folder-tree-solid': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M544 32h-112l-32-32H320c-17.62 0-32 14.38-32 32v160c0 17.62 14.38 32 32 32h224c17.62 0 32-14.38 32-32V64C576 46.38 561.6 32 544 32zM544 320h-112l-32-32H320c-17.62 0-32 14.38-32 32v160c0 17.62 14.38 32 32 32h224c17.62 0 32-14.38 32-32v-128C576 334.4 561.6 320 544 320zM64 16C64 7.125 56.88 0 48 0h-32C7.125 0 0 7.125 0 16V416c0 17.62 14.38 32 32 32h224v-64H64V160h192V96H64V16z"/></svg>',
|
||||
}
|
||||
|
||||
const name = props.name!
|
||||
|
||||
@@ -92,7 +92,6 @@ export default defineComponent({
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
background: var(--g-color-98);
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ export default {
|
||||
flat: true,
|
||||
title: ctx.i18n.t('control-center.navigation.back', ctx.command.getKeysLabel(backId)),
|
||||
disabled: idx <= 0,
|
||||
showInActionBar: true,
|
||||
onClick: () => ctx.action.getActionHandler(backId)()
|
||||
},
|
||||
{
|
||||
@@ -101,6 +102,7 @@ export default {
|
||||
flat: true,
|
||||
title: ctx.i18n.t('control-center.navigation.forward', ctx.command.getKeysLabel(forwardId)),
|
||||
disabled: idx >= stack.length - 1,
|
||||
showInActionBar: true,
|
||||
onClick: () => ctx.action.getActionHandler(forwardId)()
|
||||
},
|
||||
)
|
||||
|
||||
@@ -46,31 +46,31 @@ export default {
|
||||
counter(h6counter) ".\\0000a0\\0000a0";
|
||||
}
|
||||
|
||||
.markdown-view .outline .tag-h1.show-number { counter-reset: outline-h2counter; }
|
||||
.markdown-view .outline .tag-h2.show-number { counter-reset: outline-h3counter; }
|
||||
.markdown-view .outline .tag-h3.show-number { counter-reset: outline-h4counter; }
|
||||
.markdown-view .outline .tag-h4.show-number { counter-reset: outline-h5counter; }
|
||||
.markdown-view .outline .tag-h5.show-number { counter-reset: outline-h6counter; }
|
||||
.outline-toc .tag-h1.show-number { counter-reset: outline-h2counter; }
|
||||
.outline-toc .tag-h2.show-number { counter-reset: outline-h3counter; }
|
||||
.outline-toc .tag-h3.show-number { counter-reset: outline-h4counter; }
|
||||
.outline-toc .tag-h4.show-number { counter-reset: outline-h5counter; }
|
||||
.outline-toc .tag-h5.show-number { counter-reset: outline-h6counter; }
|
||||
|
||||
.markdown-view .outline .tag-h2.show-number:before {
|
||||
.outline-toc .tag-h2.show-number:before {
|
||||
counter-increment: outline-h2counter;
|
||||
content: counter(outline-h2counter) ".\\0000a0\\0000a0";
|
||||
}
|
||||
|
||||
.markdown-view .outline .tag-h3.show-number:before {
|
||||
.outline-toc .tag-h3.show-number:before {
|
||||
counter-increment: outline-h3counter;
|
||||
content: counter(outline-h2counter) "."
|
||||
counter(outline-h3counter) ".\\0000a0\\0000a0";
|
||||
}
|
||||
|
||||
.markdown-view .outline .tag-h4.show-number:before {
|
||||
.outline-toc .tag-h4.show-number:before {
|
||||
counter-increment: outline-h4counter;
|
||||
content: counter(outline-h2counter) "."
|
||||
counter(outline-h3counter) "."
|
||||
counter(outline-h4counter) ".\\0000a0\\0000a0";
|
||||
}
|
||||
|
||||
.markdown-view .outline .tag-h5.show-number:before {
|
||||
.outline-toc .tag-h5.show-number:before {
|
||||
counter-increment: outline-h5counter;
|
||||
content: counter(outline-h2counter) "."
|
||||
counter(outline-h3counter) "."
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
counter(outline-h5counter) ".\\0000a0\\0000a0";
|
||||
}
|
||||
|
||||
.markdown-view .outline .tag-h6.show-number:before {
|
||||
.outline-toc .tag-h6.show-number:before {
|
||||
counter-increment: outline-h6counter;
|
||||
content: counter(outline-h2counter) "."
|
||||
counter(outline-h3counter) "."
|
||||
|
||||
@@ -111,6 +111,7 @@ export default {
|
||||
icon: 'search-solid',
|
||||
flat: true,
|
||||
title: ctx.i18n.t('control-center.navigation.goto', ctx.command.getKeysLabel('filter.show-quick-open')),
|
||||
showInActionBar: true,
|
||||
onClick: () => {
|
||||
ctx.action.getActionHandler('filter.show-quick-open')()
|
||||
ctx.controlCenter.toggle(false)
|
||||
|
||||
@@ -12,6 +12,7 @@ export type Item = {
|
||||
icon: string,
|
||||
title: string,
|
||||
onClick?: () => void,
|
||||
showInActionBar?: boolean,
|
||||
}
|
||||
|
||||
export type SchemaItem = { items: Item[] }
|
||||
@@ -26,6 +27,7 @@ export type SchemaTapper = (schema: Schema) => void
|
||||
|
||||
const _refresh = debounce(() => {
|
||||
getActionHandler('control-center.refresh')()
|
||||
getActionHandler('action-bar.refresh')()
|
||||
}, 10)
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,6 +67,13 @@ export function toggleXterm (visible?: boolean) {
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* Toggle outline visible.
|
||||
* @param visible
|
||||
*/
|
||||
export function toggleOutline (visible?: boolean) {
|
||||
store.commit('setShowOutline', typeof visible === 'boolean' ? visible : !store.state.showOutline)
|
||||
}
|
||||
|
||||
registerAction({ name: 'layout.toggle-side', handler: toggleSide, keys: [Alt, 'e'] })
|
||||
registerAction({ name: 'layout.toggle-editor', handler: toggleEditor, keys: [Alt, 'x'] })
|
||||
|
||||
@@ -12,6 +12,13 @@ import { switchDoc } from './document'
|
||||
|
||||
export type MenuItem = Components.ContextMenu.Item
|
||||
export type BuildContextMenu = (items: MenuItem[], e: MouseEvent) => void
|
||||
export type Heading = {
|
||||
tag: string;
|
||||
class: string[];
|
||||
text: string;
|
||||
level: number;
|
||||
sourceLine: number;
|
||||
}
|
||||
|
||||
let tmpEnableSyncScroll = true
|
||||
let syncScrollTimer: any
|
||||
@@ -168,6 +175,29 @@ export function getViewDom () {
|
||||
return getActionHandler('view.get-view-dom')()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Headings
|
||||
*/
|
||||
export function getHeadings (): Heading[] {
|
||||
const tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
|
||||
const dom = getViewDom()
|
||||
if (!dom) {
|
||||
return []
|
||||
}
|
||||
|
||||
const nodes = dom.querySelectorAll<HTMLHeadElement>(tags.join(','))
|
||||
return Array.from(nodes).map(node => {
|
||||
const tag = node.tagName.toLowerCase()
|
||||
return {
|
||||
tag,
|
||||
class: [...node.classList, 'tag-' + tag],
|
||||
text: node.innerText,
|
||||
level: tags.indexOf(tag),
|
||||
sourceLine: parseInt(node.dataset.sourceLine || '0')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get render env.
|
||||
* @returns
|
||||
|
||||
@@ -11,6 +11,7 @@ export const initState = {
|
||||
showView: storage.get('showView', true),
|
||||
showEditor: storage.get('showEditor', true),
|
||||
showXterm: false,
|
||||
showOutline: false,
|
||||
autoPreview: true,
|
||||
syncScroll: true,
|
||||
showSetting: false,
|
||||
@@ -88,6 +89,9 @@ export default createStore({
|
||||
setShowXterm (state, data) {
|
||||
state.showXterm = data
|
||||
},
|
||||
setShowOutline (state, data) {
|
||||
state.showOutline = data
|
||||
},
|
||||
setInComposition (state, data) {
|
||||
state.inComposition = data
|
||||
},
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
<StatusBar />
|
||||
</template>
|
||||
<template v-slot:left>
|
||||
<Tree />
|
||||
<ActionBar />
|
||||
<Outline v-show="showOutline" />
|
||||
<Tree v-show="!showOutline" />
|
||||
</template>
|
||||
<template v-slot:terminal>
|
||||
<Xterm @hide="hideXterm" />
|
||||
@@ -29,10 +31,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted } from 'vue'
|
||||
import { defineComponent, onMounted, toRef } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import startup from '@fe/startup'
|
||||
import { getActionHandler } from '@fe/core/action'
|
||||
import { FLAG_DISABLE_XTERM } from '@fe/support/args'
|
||||
import type { AppState } from '@fe/support/store'
|
||||
import Layout from '@fe/components/Layout.vue'
|
||||
import TitleBar from '@fe/components/TitleBar.vue'
|
||||
import StatusBar from '@fe/components/StatusBar.vue'
|
||||
@@ -48,6 +52,8 @@ import Premium from '@fe/components/Premium.vue'
|
||||
import XFilter from '@fe/components/Filter.vue'
|
||||
import ControlCenter from '@fe/components/ControlCenter.vue'
|
||||
import DocHistory from '@fe/components/DocHistory.vue'
|
||||
import ActionBar from '@fe/components/ActionBar.vue'
|
||||
import Outline from '@fe/components/Outline.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'x-main',
|
||||
@@ -66,8 +72,12 @@ export default defineComponent({
|
||||
ExportPanel,
|
||||
ControlCenter,
|
||||
DocHistory,
|
||||
ActionBar,
|
||||
Outline,
|
||||
},
|
||||
setup () {
|
||||
const store = useStore<AppState>()
|
||||
const showOutline = toRef(store.state, 'showOutline')
|
||||
onMounted(startup)
|
||||
|
||||
const classes = {
|
||||
@@ -78,7 +88,7 @@ export default defineComponent({
|
||||
getActionHandler('layout.toggle-xterm')(false)
|
||||
}
|
||||
|
||||
return { classes, hideXterm }
|
||||
return { classes, hideXterm, showOutline }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -26,6 +26,8 @@ const data = {
|
||||
'close': 'Close',
|
||||
'discard': 'Discard',
|
||||
'edit': 'Edit',
|
||||
'outline': 'Outline',
|
||||
'files': 'Files',
|
||||
'premium': {
|
||||
'need-purchase': '[%s] Premium is required',
|
||||
'buy-license': 'Buy License',
|
||||
|
||||
@@ -27,6 +27,8 @@ const data: BaseLanguage = {
|
||||
'close': '关闭',
|
||||
'edit': '编辑',
|
||||
'discard': '放弃',
|
||||
'outline': '目录',
|
||||
'files': '文件',
|
||||
'premium': {
|
||||
'need-purchase': '[%s] 需要高级版',
|
||||
'buy-license': '立即购买',
|
||||
|
||||
Reference in New Issue
Block a user