Skip to content

Commit

Permalink
feat: fast delete current message (#495)
Browse files Browse the repository at this point in the history
  • Loading branch information
huangjinshe committed Mar 25, 2024
1 parent 6bb7afe commit 5899b04
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 28 deletions.
12 changes: 11 additions & 1 deletion src/components/common/Setting/General.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import { NButton, NDivider, NInput, NPopconfirm, NSelect, useMessage } from 'naive-ui'
import { NButton, NDivider, NInput, NPopconfirm, NSelect, NSwitch, useMessage } from 'naive-ui'
import { UserConfig } from '@/components/common/Setting/model'
import type { Language, Theme } from '@/store/modules/app/helper'
import { SvgIcon } from '@/components/common'
Expand Down Expand Up @@ -271,6 +271,16 @@ function handleImportButtonClick(): void {
/>
</div>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.fastDelMsg') }}</span>
<div class="flex-1">
<NSwitch
:round="false"
:value="appStore.fastDelMsg"
@update-value="value => appStore.setFastDelMsg(value)"
/>
</div>
</div>
</div>
</div>
</template>
1 change: 1 addition & 0 deletions src/locales/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export default {
info2FAStep3Tip2: '1. After logging in, use the two-step verification on the Two-Step Verification page to disable it.',
info2FAStep3Tip3: '2. Contact the administrator to disable two-step verification.',
maxContextCount: 'Max Context Count',
fastDelMsg: 'Fast Delete Message',
},
store: {
siderButton: 'Prompt Store',
Expand Down
1 change: 1 addition & 0 deletions src/locales/ko-KR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export default {
info2FAStep3Tip2: '1. After logging in, use the two-step verification on the Two-Step Verification page to disable it.',
info2FAStep3Tip3: '2. Contact the administrator to disable two-step verification.',
maxContextCount: '최대 컨텍스트 수량',
fastDelMsg: '빠르게 메시지 삭제',
},
store: {
siderButton: '프롬프트 스토어',
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export default {
info2FAStep3Tip2: '1. 登录后,在 两步验证 页面使用两步验证码关闭。',
info2FAStep3Tip3: '2. 联系管理员来关闭两步验证。',
maxContextCount: '最大上下文数量',
fastDelMsg: '快速删除消息',
},
store: {
siderButton: '提示词商店',
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export default {
info2FAStep3Tip2: '1. 登录后,在 两步验证 页面使用两步验证码关闭。',
info2FAStep3Tip3: '2. 联系管理员来关闭两步验证。',
maxContextCount: '最大上下文數量',
fastDelMsg: '快速刪除訊息',
},
store: {
siderButton: '提示詞商店',
Expand Down
5 changes: 4 additions & 1 deletion src/store/modules/app/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ export type Theme = 'light' | 'dark' | 'auto'

export type Language = 'zh-CN' | 'zh-TW' | 'en-US' | 'ko-KR'

export type FastDelMsg = '0' | '1'

export interface AppState {
siderCollapsed: boolean
theme: Theme
language: Language
fastDelMsg: FastDelMsg
}

export function defaultSetting(): AppState {
return { siderCollapsed: false, theme: 'auto', language: 'zh-CN' }
return { siderCollapsed: false, theme: 'auto', language: 'zh-CN', fastDelMsg: '0' }
}

export function getLocalSetting(): AppState {
Expand Down
9 changes: 8 additions & 1 deletion src/store/modules/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import type { AppState, Language, Theme } from './helper'
import type { AppState, FastDelMsg, Language, Theme } from './helper'
import { getLocalSetting, setLocalSetting } from './helper'
import { store } from '@/store/helper'

Expand All @@ -23,6 +23,13 @@ export const useAppStore = defineStore('app-store', {
}
},

setFastDelMsg(fastDelMsg: FastDelMsg) {
if (this.fastDelMsg !== fastDelMsg) {
this.fastDelMsg = fastDelMsg
this.recordState()
}
},

recordState() {
setLocalSetting(this.$state)
},
Expand Down
73 changes: 59 additions & 14 deletions src/views/chat/components/Message/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ import { useIconRender } from '@/hooks/useIconRender'
import { t } from '@/locales'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { copyToClip } from '@/utils/copy'
import { useAppStore } from '@/store'
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const appStore = useAppStore()
interface Props {
index: number
currentNavIndex: number
dateTime?: string
text?: string
images?: string[]
Expand All @@ -24,13 +33,10 @@ interface Props {
estimated: boolean
}
}
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
interface Emit {
(ev: 'regenerate'): void
(ev: 'delete'): void
(ev: 'delete', fast: boolean): void
(ev: 'updateCurrentNavIndex', itemId: number): void
(ev: 'responseHistory', historyIndex: number): void
}
Expand Down Expand Up @@ -85,7 +91,7 @@ function handleSelect(key: 'copyText' | 'delete' | 'toggleRenderType') {
asRawText.value = !asRawText.value
return
case 'delete':
emit('delete')
emit('delete', false)
}
}
Expand All @@ -110,19 +116,58 @@ async function handlePreviousResponse(next: number) {
indexRef.value += next
emit('responseHistory', indexRef.value - 1)
}
function fastDelMsg() {
emit('updateCurrentNavIndex', -1)
emit('delete', true)
}
function toggleShowFastDelMsg(event: any, itemId: number) {
if (window?.getSelection()?.toString())
return
if (!isEventTargetValid(event))
return
if (props.currentNavIndex === itemId)
emit('updateCurrentNavIndex', -1)
else
emit('updateCurrentNavIndex', itemId)
}
function isEventTargetValid(event: any) {
let element = event.target
while (element) {
if (element.classList && element.classList.contains('excludeFastDel'))
return false
element = element.parentElement
}
return true
}
</script>

<template>
<div
ref="messageRef"
class="flex w-full mb-6 overflow-hidden"
ref="messageRef" class="flex w-full mb-6 overflow-hidden"
:class="[{ 'flex-row-reverse': inversion }]"
@click="toggleShowFastDelMsg($event, props.index)"
>
<div
class="flex items-center justify-center flex-shrink-0 h-8 overflow-hidden rounded-full basis-8"
:class="[inversion ? 'ml-2' : 'mr-2']"
>
<AvatarComponent :image="inversion" />
<div class="flex flex-col">
<div
class="flex items-center justify-center flex-shrink-0 h-8 overflow-hidden rounded-full basis-8"
:class="[inversion ? 'ml-2' : 'mr-2']"
>
<AvatarComponent :image="inversion" />
</div>
<div
v-show="props.currentNavIndex === props.index && appStore.fastDelMsg"
class="flex-grow flex items-center justify-center overflow-hidden rounded-full"
:class="[inversion ? 'ml-2' : 'mr-2']"
>
<button class="focus:outline-none" style="opacity: 0.5;" @click="fastDelMsg">
<SvgIcon class="text-lg" icon="ri:delete-bin-line" />
</button>
</div>
</div>
<div class="overflow-hidden text-sm " :class="[inversion ? 'items-end' : 'items-start']">
<p v-if="inversion" class="text-xs text-[#b4bbc4]" :class="[inversion ? 'text-right' : 'text-left']">
Expand Down Expand Up @@ -184,7 +229,7 @@ async function handlePreviousResponse(next: number) {
:loading="loading"
:as-raw-text="asRawText"
/>
<div class="flex flex-col">
<div class="flex flex-col excludeFastDel">
<button
v-if="!inversion"
class="mb-2 transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-300"
Expand Down
36 changes: 25 additions & 11 deletions src/views/chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ const showPrompt = ref(false)
const nowSelectChatModel = ref<string | null>(null)
const currentChatModel = computed(() => nowSelectChatModel.value ?? currentChatHistory.value?.chatModel ?? userStore.userInfo.config.chatModel)
const currentNavIndexRef = ref<number>(-1)
const isVisionModel = computed(() => currentChatModel.value && currentChatModel.value?.includes('vision'))
let loadingms: MessageReactive
Expand Down Expand Up @@ -438,19 +440,28 @@ function handleExport() {
})
}
function handleDelete(index: number) {
function handleDelete(index: number, fast: boolean) {
if (loading.value)
return
dialog.warning({
title: t('chat.deleteMessage'),
content: t('chat.deleteMessageConfirm'),
positiveText: t('common.yes'),
negativeText: t('common.no'),
onPositiveClick: () => {
chatStore.deleteChatByUuid(+uuid, index)
},
})
if (fast === true) {
chatStore.deleteChatByUuid(+uuid, index)
}
else {
dialog.warning({
title: t('chat.deleteMessage'),
content: t('chat.deleteMessageConfirm'),
positiveText: t('common.yes'),
negativeText: t('common.no'),
onPositiveClick: () => {
chatStore.deleteChatByUuid(+uuid, index)
},
})
}
}
function updateCurrentNavIndex(index: number, newIndex: number) {
currentNavIndexRef.value = newIndex
}
function handleClear() {
Expand Down Expand Up @@ -669,6 +680,8 @@ onUnmounted(() => {
<Message
v-for="(item, index) of dataSources"
:key="index"
:index="index"
:current-nav-index="currentNavIndexRef"
:date-time="item.dateTime"
:text="item.text"
:images="item.images"
Expand All @@ -678,7 +691,8 @@ onUnmounted(() => {
:error="item.error"
:loading="item.loading"
@regenerate="onRegenerate(index)"
@delete="handleDelete(index)"
@update-current-nav-index="(itemId: number) => updateCurrentNavIndex(index, itemId)"
@delete="(fast) => handleDelete(index, fast)"
@response-history="(ev) => onResponseHistory(index, ev)"
/>
<div class="sticky bottom-0 left-0 flex justify-center">
Expand Down

0 comments on commit 5899b04

Please sign in to comment.