pref: remove unused file

This commit is contained in:
KUN1007 2023-10-28 21:30:35 +08:00
parent 14b55bd472
commit 4a7e1ed69e
12 changed files with 4 additions and 1305 deletions

View file

@ -180,7 +180,7 @@ useEditor((root) =>
ul li,
ol li {
color: var(--kungalgame-blue-4);
color: var(--kungalgame-blue-5);
}
.tableWrapper {

View file

@ -1,141 +0,0 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
// Global message component (top)
import Message from '@/components/alert/Message'
// Import the router
import { useRoute, useRouter } from 'vue-router'
// Import the icon font
import { Icon } from '@iconify/vue'
// Import CSS animations
import 'animate.css'
const router = useRouter()
// Current route
const route = useRoute()
// Name of the current page route
const routeName = computed(() => route.name as string)
// Adjust the background color based on the mouse coordinates
const x = ref(0)
// Whether to display information prompts
const isShowInfo = ref(false)
// When the mouse moves
const onMousemove = (e: MouseEvent) => {
x.value = e.clientX
}
// Click the help button
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 {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
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

@ -1,11 +1,9 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { computed, defineAsyncComponent, ref } from 'vue'
// Import the router
import { useRoute } from 'vue-router'
// Import icon font
import { Icon } from '@iconify/vue'
// Asynchronously import the editor settings menu
const EditorSettingsMenu = defineAsyncComponent(
() => import('./EditorSettingsMenu.vue')

View file

@ -1,192 +0,0 @@
<script setup lang="ts">
import { computed, defineAsyncComponent, ref } from 'vue'
// Import the router
import { useRoute } from 'vue-router'
// Import icon font
import { Icon } from '@iconify/vue'
// Asynchronously import the editor settings menu
const EditorSettingsMenu = defineAsyncComponent(
() => import('./EditorSettingsMenu.vue')
)
// Import CSS animations
import 'animate.css'
// Import the topic editing store
import { useKUNGalgameEditStore } from '@/store/modules/edit'
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'
// Topic editing page store
const { textCount } = storeToRefs(useKUNGalgameEditStore())
// Topic page store for replies and adjusting reply panel width
const { replyDraft, replyPanelWidth } = storeToRefs(useKUNGalgameTopicStore())
// Current route
const route = useRoute()
// Name of the current page route
const routeName = computed(() => route.name as string)
const textCountNumber = computed(() =>
routeName.value === 'Edit' ? textCount.value : replyDraft.value.textCount
)
// Whether to display the editor settings panel
const isShowSettingsMenu = ref(false)
// Style when the settings panel is activated
const settingsPanelActive = ref('')
// Click the settings button
const handelClickSettings = () => {
isShowSettingsMenu.value = !isShowSettingsMenu.value
if (isShowSettingsMenu.value) {
settingsPanelActive.value = 'settings-icon-active'
} else {
settingsPanelActive.value = ''
}
}
// Close the panel emits
const handelCloseSettingsMenu = () => {
isShowSettingsMenu.value = false
settingsPanelActive.value = ''
}
</script>
<template>
<div class="footer">
<!-- Display the settings button -->
<div class="settings">
<span
@click="handelClickSettings"
class="settings-icon"
:class="settingsPanelActive"
>
<Icon icon="uiw:setting-o" />
</span>
<!-- Help slot -->
<slot name="help" />
<input
v-if="routeName === 'Topic'"
class="panel-width"
type="range"
min="50"
max="100"
step="1"
v-model="replyPanelWidth"
/>
</div>
<!-- Word count -->
<span class="count">{{ textCountNumber + ` ${$tm('edit.word')}` }}</span>
<!-- Settings panel -->
<EditorSettingsMenu
@close="handelCloseSettingsMenu"
:isShowSettingsMenu="isShowSettingsMenu"
/>
</div>
</template>
<style lang="scss" scoped>
.footer {
padding: 10px 17px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.settings {
color: var(--kungalgame-font-color-1);
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
.settings-icon {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.help {
cursor: pointer;
margin-left: 20px;
color: var(--kungalgame-font-color-1);
font-size: 23px;
display: flex;
justify-content: center;
align-items: center;
}
.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 {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
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;
}
}
}
}
}
.panel-width {
margin-left: 20px;
}
}
.count {
color: var(--kungalgame-font-color-0);
background-color: var(--kungalgame-trans-white-9);
}
// Keep the settings button rotating when activated.
.settings-icon-active {
color: var(--kungalgame-blue-4);
animation: settings 3s linear infinite;
}
@keyframes settings {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View file

@ -1,249 +0,0 @@
<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { useRoute } from 'vue-router'
// Import the icon font
import { Icon } from '@iconify/vue'
// Import CSS animations
import 'animate.css'
// Import the topic editing store
import { useKUNGalgameEditStore } from '@/store/modules/edit'
// Import the reply store
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'
// Import the keyword display toggle button
import SwitchButton from './SwitchButton.vue'
// Topic editing page store
const { editorHeight, mode } = storeToRefs(useKUNGalgameEditStore())
// Topic page store for replies
const { replyDraft } = storeToRefs(useKUNGalgameTopicStore())
defineProps<{
isShowSettingsMenu: boolean
}>()
// Define emits to close the settings panel
const emits = defineEmits<{
close: [isShowSettingsMenu: boolean]
}>()
// Current route
const route = useRoute()
// Name of the current page route
const routeName = computed(() => route.name as string)
// Whether to refresh the page when clicking advanced options
const isRefreshPage = ref(false)
// Remind the user to refresh the page when clicking on advanced options
watch(
() => [replyDraft.value.mode, mode.value],
() => {
isRefreshPage.value = true
}
)
const handleRefreshPage = () => location.reload()
// Close the settings panel
const handelCloseSettingsPanel = () => {
emits('close', false)
}
</script>
<template>
<Transition
enter-active-class="animate__animated animate__jackInTheBox animate__faster"
leave-active-class="animate__animated animate__rollOut animate__faster"
>
<!-- Settings menu -->
<div v-if="isShowSettingsMenu" class="settings-menu">
<div class="content">
<!-- Editor height settings -->
<div class="editor-height-title">
<span> {{ $tm('edit.editorHeight') }} </span>
<span>{{ editorHeight }} px</span>
</div>
<!-- Editor page -->
<div v-if="routeName === 'Edit'" class="editor-height">
<span>300 px</span>
<input
type="range"
min="300"
max="500"
step="1"
v-model="editorHeight"
/>
<span>500 px</span>
</div>
<!-- Reply panel -->
<div v-if="routeName === 'Topic'" class="editor-height">
<span>100 px</span>
<input
type="range"
min="100"
max="500"
step="1"
v-model="replyDraft.editorHeight"
/>
<span>500 px</span>
</div>
<!-- Whether to display editor advanced options -->
<div class="editor-advance">
<div class="editor-advance-title">
<Transition mode="out-in" name="slide-up">
<span v-if="!isRefreshPage"> {{ $tm('edit.editorMode') }} </span>
<span
@click="handleRefreshPage"
class="refresh"
v-else-if="isRefreshPage"
>
{{ $tm('edit.refresh') }}
</span>
</Transition>
</div>
<!-- Editor page switch button -->
<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>
<!-- Reply panel switch button -->
<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>
<!-- Whether to display popular keywords -->
<div class="keywords">
<div class="keywords-title">{{ $tm('edit.tagsHint') }}</div>
<SwitchButton />
</div>
</div>
<!-- Close button -->
<div class="close">
<Icon @click="handelCloseSettingsPanel" icon="line-md:close" />
</div>
</div>
</Transition>
</template>
<style lang="scss" scoped>
.settings-menu {
width: 323px;
padding: 10px;
z-index: 1009;
position: absolute;
margin-bottom: 190px;
background-color: var(--kungalgame-white);
border: 1px solid var(--kungalgame-blue-1);
box-shadow: var(--shadow);
border-radius: 5px;
display: flex;
.content {
width: 100%;
display: flex;
flex-direction: column;
}
.editor-height-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
font-size: 17px;
}
.editor-advance {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
font-size: 17px;
}
}
.editor-height {
margin-bottom: 20px;
display: flex;
justify-content: space between;
align-items: center;
}
.editor-advance-title {
display: flex;
flex-direction: column;
.refresh {
display: flex;
align-items: center;
font-size: 17px;
cursor: pointer;
color: var(--kungalgame-blue-4);
&:hover {
text-decoration: underline;
}
}
}
// Editor mode selection box
.select {
width: 100px;
font-size: 16px;
margin-left: 20px;
color: var(--kungalgame-font-color-3);
border: 1px solid var(--kungalgame-blue-4);
background-color: var(--kungalgame-trans-white-9);
option {
background-color: var(--kungalgame-white);
}
}
// Close settings
.close {
font-size: 25px;
margin-left: 10px;
display: flex;
justify-content: end;
cursor: pointer;
}
// Whether to display popular keywords
.keywords {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 17px;
}
.slide-up-enter-active,
.slide-up-leave-active {
transition: all 0.25s ease-out;
}
.slide-up-enter-from {
opacity: 0;
transform: translateY(30px);
}
.slide-up-leave-to {
opacity: 0;
transform: translateY(-30px);
}
</style>

View file

@ -1,141 +0,0 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
// Global message component (top)
import Message from '@/components/alert/Message'
// Import the router
import { useRoute, useRouter } from 'vue-router'
// Import the icon font
import { Icon } from '@iconify/vue'
// Import CSS animations
import 'animate.css'
const router = useRouter()
// Current route
const route = useRoute()
// Name of the current page route
const routeName = computed(() => route.name as string)
// Adjust the background color based on the mouse coordinates
const x = ref(0)
// Whether to display information prompts
const isShowInfo = ref(false)
// When the mouse moves
const onMousemove = (e: MouseEvent) => {
x.value = e.clientX
}
// Click the help button
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 {
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
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

@ -1,289 +0,0 @@
<script setup lang="ts">
import { defineAsyncComponent, computed, ref, onBeforeMount } from 'vue'
import { useRoute } from 'vue-router'
// Import the editor
import { QuillEditor } from '@vueup/vue-quill'
// Import editor Modules
import { modules } from './modules'
// Custom Quill themes, the second theme is not currently in use
import '@/styles/editor/editor.snow.scss'
// import '@vueup/vue-quill/dist/vue-quill.bubble.css'
// Import Title component
const Title = defineAsyncComponent(
() => import('@/components/quill-editor/Title.vue')
)
// Import EditorFooter
import EditorFooter from './EditorFooter.vue'
// Footer slot
import Help from './Help.vue'
// Import the store for editing topics
import { useKUNGalgameEditStore } from '@/store/modules/edit'
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'
// Import XSS filtering tool
import DOMPurify from 'dompurify'
// Import debounce function
import { debounce } from '@/utils/debounce'
// Topic editing page store
const { editorHeight, textCount, isSaveTopic, content, topicRewrite } =
storeToRefs(useKUNGalgameEditStore())
// Store for topic page used for replies
const { replyDraft, replyRewrite } = storeToRefs(useKUNGalgameTopicStore())
// Current route
const route = useRoute()
// Current page route name
const routeName = computed(() => route.name as string)
// Define props passed from the parent component
/**
* @param {boolean} isShowToolbar - Whether to display the toolbar
* @param {boolean} isShowTitle - Whether to display the title
*/
const props = defineProps<{
isShowToolbar: boolean
isShowTitle: boolean
}>()
// Editor instance
const editorRef = ref<typeof QuillEditor>()
// Content inside the editor
const valueHtml = ref('')
// Editor-related configuration
const editorOptions = {
placeholder: 'Moe Moe Moe!',
}
// Editor height, determined by the route name
const editorHeightStyle = computed(
() =>
`height: ${
routeName.value === 'Edit'
? editorHeight.value
: replyDraft.value.editorHeight
}px`
)
// Whether to show the editor toolbar
const isShowEditorToolbar = computed(() =>
props.isShowToolbar ? 'block' : 'none'
)
onBeforeMount(() => {
/**
* Editor is in the edit mode
*/
// Load topic data before mounting if not saved (and must be on the Edit page)
if (isSaveTopic.value && routeName.value === 'Edit') {
valueHtml.value = content.value
}
/**
* Editor is in the re-editing edit mode
*/
// Load data for re-editing a topic before mounting
if (topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
valueHtml.value = topicRewrite.value.content
}
/**
* Editor is in the reply mode
*/
// Load reply data before mounting if not saved (and must be on the Topic page)
if (replyDraft.value.isSaveReply && routeName.value === 'Topic') {
valueHtml.value = replyDraft.value.content
}
/**
* Editor is in the re-editing reply mode
*/
if (replyRewrite.value.isReplyRewriting && routeName.value === 'Topic') {
valueHtml.value = replyRewrite.value.content
}
})
// Automatically save data when the editor text changes
const handleTextChange = async () => {
// Filter out XSS
const purifiedHtml = DOMPurify.sanitize(editorRef.value?.getHTML())
// Create a debounce function
const debouncedUpdateContent = debounce(() => {
/**
* Editor is in edit mode
*/
// Save to the edit store if not in topic re-edit mode
if (!topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
content.value = purifiedHtml
}
/**
* Editor is in re-editing edit mode
*/
// Load data for re-editing a topic before mounting
if (topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
topicRewrite.value.content = purifiedHtml
}
/**
* Editor is in reply mode
*/
// Save to the reply store if not in reply re-edit mode
if (!replyRewrite.value.isReplyRewriting && routeName.value === 'Topic') {
replyDraft.value.content = purifiedHtml
}
/**
* Editor is in re-editing reply mode
*/
if (replyRewrite.value.isReplyRewriting && routeName.value === 'Topic') {
replyRewrite.value.content = purifiedHtml
}
}, 1007)
// Call the debounce function, which will execute the update operation only once within the delay time
debouncedUpdateContent()
// Calculate how many characters the user has entered
const length = computed(() => editorRef.value?.getText().trim().length)
// Save the count based on the page's route name
if (routeName.value === 'Edit') {
textCount.value = length.value
}
if (routeName.value === 'Topic') {
replyDraft.value.textCount = length.value
}
}
</script>
<template>
<div class="editor">
<!-- Topic title -->
<Title v-if="isShowTitle" />
<!-- Editor body -->
<QuillEditor
ref="editorRef"
contentType="html"
:content="valueHtml"
:style="editorHeightStyle"
:modules="modules"
:options="editorOptions"
@textChange="handleTextChange"
@click.prevent
/>
<!-- Editor footer -->
<EditorFooter>
<template #help>
<Help />
</template>
</EditorFooter>
</div>
</template>
<style lang="scss" scoped>
/*
* Resolve style issues
* These styles are written based on the compiled CSS, it's a bit weird, blame the author www
*/
/* Style of the toolbar */
:deep(.ql-toolbar) {
border-top: 1px solid var(--kungalgame-blue-1);
border-bottom: 1px solid var(--kungalgame-blue-1);
background-color: var(--kungalgame-trans-blue-0);
/* Shadow below the header */
box-shadow: 0 2px 4px 0 var(--kungalgame-trans-blue-1);
display: v-bind(isShowEditorToolbar);
/* Do not display video insertion, this feature has too many bugs */
.ql-video {
display: none;
}
}
/* Style of the editor body */
:deep(.ql-container) {
transition: all 0.2s;
width: 80%;
max-width: 1080px;
border: none;
margin: 0 auto;
font-size: 17px;
margin-top: 40px;
margin-bottom: 40px;
&::before {
content: '∟';
position: absolute;
font-size: 40px;
transform: translateX(-20px) translateY(-20px) rotate(90deg);
color: var(--kungalgame-blue-2);
}
&::after {
content: '∟';
position: absolute;
right: 0;
font-size: 40px;
transform: translateX(20px) translateY(-20px) rotate(-90deg);
color: var(--kungalgame-blue-2);
}
.ql-editor {
padding: 0;
&::-webkit-scrollbar {
display: inline;
width: 7px;
height: 0;
}
&::-webkit-scrollbar-thumb {
cursor: default;
background: var(--kungalgame-blue-4);
border-radius: 3px;
}
/* Compatible with Firefox */
scrollbar-width: thin;
scrollbar-color: var(--kungalgame-blue-4) var(--kungalgame-blue-1); /* Firefox 64+ */
&::before {
left: 0;
}
&::after {
content: '♡ Yuki Yuki';
font-size: 22px;
position: absolute;
bottom: 0;
transform: translateX(-20px) translateY(27px);
color: var(--kungalgame-trans-white-5);
text-shadow: 1px 1px 1px var(--kungalgame-pink-3);
font-style: oblique;
}
}
/* Style of BlotFormatter plugin, important here */
.blot-formatter__toolbar-button {
margin: 0 5px;
border: none !important;
background: var(--kungalgame-trans-white-9) !important;
svg {
border: 1px solid var(--kungalgame-blue-4) !important;
background: var(--kungalgame-trans-white-2) !important;
}
}
.is-selected {
svg {
background: var(--kungalgame-trans-blue-1) !important;
}
}
}
</style>

View file

@ -1,95 +0,0 @@
<!-- Common Toggle Button for KUNGalgame -->
<script setup lang="ts">
import { watch, computed } from 'vue'
import { useRoute } from 'vue-router'
// Import the store for the editing page
import { useKUNGalgameEditStore } from '@/store/modules/edit'
// Import the store for replies
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
import { storeToRefs } from 'pinia'
// Current page's route
const route = useRoute()
// Name of the current page's route
const routeName = computed(() => route.name as string)
// Use the store for the editing page
const { isShowHotKeywords } = storeToRefs(useKUNGalgameEditStore())
// Store for the topic page, used for replies
const { replyDraft } = storeToRefs(useKUNGalgameTopicStore())
// Watch for changes in store states to keep button states in sync with the store
watch(
() => [isShowHotKeywords.value, replyDraft.value.isShowHotKeywords],
([newValue1, newValue2]) => {
isShowHotKeywords.value = newValue1
replyDraft.value.isShowHotKeywords = newValue2
}
)
</script>
<template>
<!-- Bind different models based on the route name -->
<input
v-if="routeName === 'Edit'"
type="checkbox"
id="switch"
v-model="isShowHotKeywords"
/>
<input
v-if="routeName === 'Topic'"
type="checkbox"
id="switch"
v-model="replyDraft.isShowHotKeywords"
/>
<label for="switch"></label>
</template>
<style lang="scss" scoped>
input {
height: 0;
width: 0;
visibility: hidden;
}
label {
cursor: pointer;
text-indent: -9999px;
width: 47px;
height: 24px;
background: var(--kungalgame-trans-blue-2);
display: block;
border-radius: 100px;
position: relative;
}
label:after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: var(--kungalgame-white);
border-radius: 15px;
transition: 0.3s;
}
input:checked + label {
background: var(--kungalgame-blue-4);
}
input:checked + label:after {
left: calc(100% - 2px);
transform: translateX(-100%);
}
// Centering
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
</style>

View file

@ -1,104 +0,0 @@
<script setup lang="ts">
import { onBeforeMount, ref } from 'vue'
// Import the store for editing topics
import { useKUNGalgameEditStore } from '@/store/modules/edit'
import { storeToRefs } from 'pinia'
// Import debounce function
import { debounce } from '@/utils/debounce'
const { isSaveTopic, title, topicRewrite } = storeToRefs(
useKUNGalgameEditStore()
)
// Topic title text
const topicTitle = ref('')
// Maximum length for the title
const maxInputLength = 40
onBeforeMount(() => {
/**
* Editor is in edit mode
*/
if (isSaveTopic.value) {
topicTitle.value = title.value
}
/**
* Editor is in re-editing edit mode
*/
// Load data for re-editing a topic before mounting
if (topicRewrite.value.isTopicRewriting) {
topicTitle.value = topicRewrite.value.title
}
})
// Handle user input
const handleInput = () => {
// Title cannot exceed 40 characters
if (topicTitle.value.length > maxInputLength) {
topicTitle.value = topicTitle.value.slice(0, maxInputLength)
}
// User input is pure whitespace
if (topicTitle.value.trim() === '') {
title.value = ''
topicRewrite.value.title = ''
return
}
// Create a debounce handling function
const debouncedInput = debounce(() => {
/**
* Editor is in reply mode
*/
// Save to the edit store if not in topic re-edit mode
if (!topicRewrite.value.isTopicRewriting) {
title.value = topicTitle.value
}
/**
* Editor is in re-editing edit mode
*/
// Save to the re-editing page's store if in re-edit mode
if (topicRewrite.value.isTopicRewriting) {
topicRewrite.value.title = topicTitle.value
}
}, 300)
// Call the debounce handling function, which will execute the update operation only once within the delay time
debouncedInput()
}
</script>
<template>
<!-- Topic title -->
<div class="title">
<input
type="text"
:placeholder="`${$tm('edit.title')}`"
v-model="topicTitle"
@input="handleInput"
:maxlength="maxInputLength"
/>
</div>
</template>
<style lang="scss" scoped>
/* Title of the topic */
.title {
padding: 10px;
width: 100%;
}
/* Input field for the topic title */
.title input {
background-color: var(--kungalgame-white-9);
color: var(--kungalgame-font-color-2);
/* Distance from the outline */
padding: 7px;
width: 100%;
/* Font size for the title input */
font-size: 40px;
border: none;
}
</style>

View file

@ -1,88 +0,0 @@
/**
* This file contains various modules for Quill. Large modules like markdown and emoji are not used here.
*/
// Import the editor
// import { QuillEditor } from '@vueup/vue-quill'
// Import Quill module for resizing and realigning images and iframe video
// It must be imported this way, otherwise it will throw errors after bundling
// import BlotFormatter from 'quill-blot-formatter'
// import BlotFormatter from 'quill-blot-formatter/dist/BlotFormatter'
// Import module for automatic recognition of URLs and email addresses
import MagicUrl from 'quill-magic-url'
import '@/styles/editor/editor.snow.scss'
// Import module for image compression and uploading (very useful)
import ImageCompress from 'quill-image-compress'
import Message from '../alert/Message'
// Editor modules
export const modules = [
// BlotFormatter
// {
// name: 'blotFormatter',
// module: BlotFormatter,
// // see: https://github.com/Fandom-OSS/quill-blot-formatter/blob/master/src/Options.js
// options: {
// overlay: {
// style: {
// border: '2px solid var(--kungalgame-blue-3)',
// },
// },
// },
// },
// MagicUrl
{
name: 'magicUrl',
module: MagicUrl,
options: {
// Regex used to check URLs during typing
urlRegularExpression:
/(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}(?:\/[^\s]*)?/,
// Regex used to check URLs on paste
globalRegularExpression: /(https?:\/\/|www\.|tel:)[\S]+/g,
mailRegularExpression: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
globalMailRegularExpression:
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
},
},
// ImageCompress
{
name: 'imageCompress',
module: ImageCompress,
options: {
quality: 0.77,
maxWidth: 1007,
maxHeight: 1007,
imageType: 'image/webp',
insertIntoEditor: () => {
Message(
'The image upload API is under development',
'图片上传接口正在开发中',
'warn'
)
},
// insertIntoEditor: (
// imageBase64URL: string,
// imageBlob: Blob,
// editor: typeof QuillEditor
// ) => {
// const formData = new FormData()
// formData.append('file', imageBlob)
// /* TODO: Change this to a backend API */
// fetch('127.0.0.1:10008/upload', { method: 'POST', body: formData })
// .then((response) => response.text())
// .then((result) => {
// const range = editor.getSelection()
// editor.insertEmbed(range.index, 'image', `${result}`, 'user')
// })
// .catch((error) => {
// console.error(error)
// })
// },
// Temporarily enable console debugging
debug: false,
},
},
]

View file

@ -20,8 +20,6 @@ const handlePublish = async () => {
// Backend returns the created topic data
const res = await useKUNGalgameEditStore().createNewTopic()
console.log(res)
if (res?.code === 200) {
// Get the tid of the created topic
const tid = res.data.tid

View file

@ -287,7 +287,9 @@ onBeforeMount(() => {
{{ topicData?.title }}
</div>
</Transition>
<Master v-if="topicData" :topicData="topicData" />
<Reply
v-if="topicData && repliesData"
:repliesData="repliesData"