feat: QuillEditor footer help slot

This commit is contained in:
KUN1007 2023-09-18 16:29:19 +08:00
parent 051a031831
commit b599ac10c6
7 changed files with 181 additions and 56 deletions

View file

@ -78,6 +78,7 @@ const messageClass = (type: string): string => {
box-shadow: var(--shadow);
span {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

View file

@ -1,8 +1,7 @@
<script setup lang="ts">
import { computed, defineAsyncComponent, ref } from 'vue'
//
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
//
import { Icon } from '@iconify/vue'
@ -11,30 +10,32 @@ import { Icon } from '@iconify/vue'
const EditorSettingsMenu = defineAsyncComponent(
() => import('./EditorSettingsMenu.vue')
)
// css
import 'animate.css'
//
defineProps<{
textCount: number
}>()
// store
import { useKUNGalgameEditStore } from '@/store/modules/edit'
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'
const router = useRouter()
// store
const { textCount } = storeToRefs(useKUNGalgameEditStore())
// store
const { replyDraft } = storeToRefs(useKUNGalgameTopicStore())
//
const route = useRoute()
//
const routeName = computed(() => route.name as string)
const textCountNumber = computed(() =>
routeName.value === 'Edit' ? textCount.value : replyDraft.value.textCount
)
//
const isShowSettingsMenu = ref(false)
//
const settingsPanelActive = ref('')
//
const x = ref(0)
//
const isShowInfo = ref(false)
//
const onMousemove = (e: MouseEvent) => {
x.value = e.clientX
}
//
const handelClickSettings = () => {
@ -59,33 +60,11 @@ const handelClickSettings = () => {
<Icon icon="uiw:setting-o" />
</span>
<span class="help" @click="isShowInfo = true">
<Icon icon="line-md:question-circle" />
</span>
<div
v-if="isShowInfo"
@mousemove="onMousemove"
@mouseleave="isShowInfo = false"
class="info"
:style="{ backgroundColor: `hsl(${x}, 77%, 77%)` }"
>
<ul>
<li>{{ $tm('edit.help1') }}</li>
<li>{{ $tm('edit.help2') }}</li>
<li>{{ $tm('edit.help3') }}</li>
<li>{{ $tm('edit.help4') }}</li>
<li>
{{ $tm('edit.help5') }}
<span @click="router.push('/contact')">
{{ $tm('edit.contact') }}
</span>
</li>
</ul>
</div>
<slot name="help" />
</div>
<!-- 文字计数 -->
<span class="count">{{ textCount + ` ${$tm('edit.word')}` }}</span>
<span class="count">{{ textCountNumber + ` ${$tm('edit.word')}` }}</span>
<!-- 设置面板 -->
<EditorSettingsMenu :isShowSettingsMenu="isShowSettingsMenu" />

View file

@ -28,11 +28,6 @@ const route = useRoute()
//
const routeName = computed(() => route.name as string)
//
const editorMode = computed(() =>
routeName.value === 'Edit' ? mode.value : replyDraft.value.mode
)
//
const isRefreshPage = ref(false)
@ -101,13 +96,24 @@ const handleRefreshPage = () => location.reload()
</Transition>
</div>
<!-- 切换按钮 -->
<select class="select" v-model="editorMode">
<!-- 编辑界面切换按钮 -->
<select class="select" v-if="routeName === 'Edit'" v-model="mode">
<option value="minimal">{{ $tm('edit.minimal') }}</option>
<option value="">{{ $tm('edit.default') }}</option>
<option value="essential">{{ $tm('edit.essential') }}</option>
<option value="full">{{ $tm('edit.full') }}</option>
</select>
<!-- 回复面板切换按钮 -->
<select
class="select"
v-if="routeName === 'Topic'"
v-model="replyDraft.mode"
>
<option value="minimal">{{ $tm('edit.minimal') }}</option>
<option value="">{{ $tm('edit.default') }}</option>
<option value="essential">{{ $tm('edit.essential') }}</option>
</select>
</div>
<!-- 是否显示热门关键词 -->

View file

@ -0,0 +1,131 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
//
import message from '@/components/alert/Message'
//
import { useRoute, useRouter } from 'vue-router'
//
import { Icon } from '@iconify/vue'
// css
import 'animate.css'
const router = useRouter()
//
const route = useRoute()
//
const routeName = computed(() => route.name as string)
//
const x = ref(0)
//
const isShowInfo = ref(false)
//
const onMousemove = (e: MouseEvent) => {
x.value = e.clientX
}
//
const handleClickHelp = () => {
if (routeName.value === 'Edit') {
isShowInfo.value = true
} else {
const helpHtmlEN = `<p>You can click on the left settings to adjust the editor's mode.</p>
<p>We recommend finishing your text before formatting.</p>
<p>The website's code is handwritten, and errors are inevitable.</p>
<p>If you encounter any errors, please <a style="color: var(--kungalgame-blue-4); border-bottom: 2px solid var(--kungalgame-blue-4);" href="/contact">Contact Us</a>.</p>`
const helpHtmlCN = `<p>您可以点击左侧的设置调整编辑器的模式</p>
<p>我们建议您写完文本再进行格式化</p>
<p>网站的代码是手写的错误在所难免</p>
<p>如果您遇到错误<a style="color: var(--kungalgame-blue-4); border-bottom: 2px solid var(--kungalgame-blue-4);" href="/contact">联系我们</a></p>`
message(helpHtmlEN, helpHtmlCN, 'info', 5000)
}
}
</script>
<template>
<div class="help">
<div class="title" @click="handleClickHelp">
<span><Icon icon="line-md:question-circle" /></span>
</div>
<div
v-if="isShowInfo"
@mousemove="onMousemove"
@mouseleave="isShowInfo = false"
class="info"
:style="{ backgroundColor: `hsl(${x}, 77%, 77%)` }"
>
<ul>
<li>{{ $tm('edit.help1') }}</li>
<li>{{ $tm('edit.help2') }}</li>
<li>{{ $tm('edit.help3') }}</li>
<li>{{ $tm('edit.help4') }}</li>
<li>
{{ $tm('edit.help5') }}
<span @click="router.push('/contact')">
{{ $tm('edit.contact') }}
</span>
</li>
</ul>
</div>
</div>
</template>
<style lang="scss" scoped>
.help {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.title {
cursor: pointer;
margin-left: 20px;
color: var(--kungalgame-font-color-1);
font-size: 23px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
span {
display: flex;
}
}
.info {
padding: 3px;
color: var(--kungalgame-font-color-2);
position: absolute;
left: 200px;
transition: 0.3s background-color ease;
border-radius: 5px;
margin-bottom: 100px;
ul {
display: flex;
flex-direction: column;
background-color: var(--kungalgame-white);
padding: 5px;
border-radius: 5px;
li {
&::before {
content: '❆ ';
color: var(--kungalgame-pink-3);
}
cursor: default;
font-size: 15px;
line-height: 27px;
span {
cursor: pointer;
color: var(--kungalgame-blue-4);
&:hover {
text-decoration: underline;
}
}
}
}
}
</style>

View file

@ -18,6 +18,8 @@ const Title = defineAsyncComponent(
// Footer
import EditorFooter from './EditorFooter.vue'
// Footer
import Help from './Help.vue'
// store
import { useKUNGalgameEditStore } from '@/store/modules/edit'
@ -79,11 +81,6 @@ const editorMode = computed(() =>
routeName.value === 'Edit' ? mode.value : replyDraft.value.mode
)
//
const textCountNumber = computed(() =>
routeName.value === 'Edit' ? textCount.value : replyDraft.value.textCount
)
//
const isShowEditorToolbar = computed(() =>
props.isShowToolbar ? 'block' : 'none'
@ -152,7 +149,11 @@ const handleTextChange = async () => {
/>
<!-- 编辑器 footer -->
<EditorFooter :textCount="textCountNumber" />
<EditorFooter>
<template #help>
<Help />
</template>
</EditorFooter>
</div>
</template>

View file

@ -29,7 +29,8 @@ interface ReplyDraft {
*/
editorHeight: number
textCount: number
mode: '' | 'essential' | 'minimal' | 'full'
// 这里仅支持三种模式
mode: '' | 'essential' | 'minimal'
theme: 'snow' | 'bubble'
// 是否显示热门关键词
isShowHotKeywords: boolean
@ -105,7 +106,7 @@ export const useKUNGalgameTopicStore = defineStore({
replyDraft: {
editorHeight: 200,
textCount: 0,
mode: '',
mode: 'minimal',
theme: 'snow',
isShowHotKeywords: true,

View file

@ -286,4 +286,10 @@ onBeforeMount(() => {
padding: 0;
}
}
@media (max-width: 700px) {
.content-container {
width: 100%;
}
}
</style>