feat: Optimize dialog
- Change the method of open dialog - Fix the problem of open dialog disappearing due to virtual scrolling - Float the active dialog to the top
This commit is contained in:
@@ -23,7 +23,7 @@ export const useConfig = defineStore('config', () => {
|
||||
window.removeEventListener('resize', checkDeviceType)
|
||||
})
|
||||
|
||||
const refreshSetting = async () => {
|
||||
const refresh = async () => {
|
||||
return Promise.all([refreshModelFolders()])
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export const useConfig = defineStore('config', () => {
|
||||
cardWidth: 240,
|
||||
aspect: 7 / 9,
|
||||
modelFolders,
|
||||
refreshSetting,
|
||||
refresh,
|
||||
}
|
||||
|
||||
useAddConfigSettings(config)
|
||||
|
||||
66
src/hooks/dialog.ts
Normal file
66
src/hooks/dialog.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { defineStore } from 'hooks/store'
|
||||
import { Component, markRaw, ref } from 'vue'
|
||||
|
||||
interface HeaderButton {
|
||||
icon: string
|
||||
command: () => void
|
||||
}
|
||||
|
||||
interface DialogItem {
|
||||
key: string
|
||||
title: string
|
||||
content: Component
|
||||
contentProps?: Record<string, any>
|
||||
keepAlive?: boolean
|
||||
headerButtons?: HeaderButton[]
|
||||
defaultSize?: Partial<ContainerSize>
|
||||
defaultMobileSize?: Partial<ContainerSize>
|
||||
resizeAllow?: { x?: boolean; y?: boolean }
|
||||
minWidth?: number
|
||||
maxWidth?: number
|
||||
minHeight?: number
|
||||
maxHeight?: number
|
||||
}
|
||||
|
||||
export const useDialog = defineStore('dialog', () => {
|
||||
const stack = ref<(DialogItem & { visible?: boolean })[]>([])
|
||||
|
||||
const rise = (dialog: { key: string }) => {
|
||||
const index = stack.value.findIndex((item) => item.key === dialog.key)
|
||||
if (index !== -1) {
|
||||
const item = stack.value.splice(index, 1)
|
||||
stack.value.push(...item)
|
||||
}
|
||||
}
|
||||
|
||||
const open = (dialog: DialogItem) => {
|
||||
const item = stack.value.find((item) => item.key === dialog.key)
|
||||
if (item) {
|
||||
item.visible = true
|
||||
rise(dialog)
|
||||
} else {
|
||||
stack.value.push({
|
||||
...dialog,
|
||||
content: markRaw(dialog.content),
|
||||
visible: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const close = (dialog: { key: string }) => {
|
||||
const item = stack.value.find((item) => item.key === dialog.key)
|
||||
if (item?.keepAlive) {
|
||||
item.visible = false
|
||||
} else {
|
||||
stack.value = stack.value.filter((item) => item.key !== dialog.key)
|
||||
}
|
||||
}
|
||||
|
||||
return { stack, open, close, rise }
|
||||
})
|
||||
|
||||
declare module 'hooks/store' {
|
||||
interface StoreProvider {
|
||||
dialog: ReturnType<typeof useDialog>
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@ import { MarkdownTool, useMarkdown } from 'hooks/markdown'
|
||||
import { socket } from 'hooks/socket'
|
||||
import { defineStore } from 'hooks/store'
|
||||
import { useToast } from 'hooks/toast'
|
||||
import { useBoolean } from 'hooks/utils'
|
||||
import { bytesToSize } from 'utils/common'
|
||||
import { onBeforeMount, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export const useDownload = defineStore('download', (store) => {
|
||||
const [visible, toggle] = useBoolean()
|
||||
const { toast, confirm } = useToast()
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -118,7 +116,7 @@ export const useDownload = defineStore('download', (store) => {
|
||||
refresh()
|
||||
})
|
||||
|
||||
return { visible, toggle, data: taskList, refresh }
|
||||
return { data: taskList, refresh }
|
||||
})
|
||||
|
||||
declare module 'hooks/store' {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { defineStore } from 'hooks/store'
|
||||
import { useBoolean } from 'hooks/utils'
|
||||
import { Ref, ref } from 'vue'
|
||||
|
||||
class GlobalLoading {
|
||||
@@ -25,7 +24,7 @@ class GlobalLoading {
|
||||
export const globalLoading = new GlobalLoading()
|
||||
|
||||
export const useGlobalLoading = defineStore('loading', () => {
|
||||
const [loading] = useBoolean()
|
||||
const loading = ref(false)
|
||||
|
||||
globalLoading.bind(loading)
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { defineStore } from 'hooks/store'
|
||||
import { useBoolean } from 'hooks/utils'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
export const useDialogManager = defineStore('dialogManager', () => {
|
||||
const [visible, toggle] = useBoolean()
|
||||
|
||||
const mounted = ref(false)
|
||||
const open = ref(false)
|
||||
|
||||
watch(visible, (visible) => {
|
||||
open.value = visible
|
||||
mounted.value = true
|
||||
})
|
||||
|
||||
const updateVisible = (val: boolean) => {
|
||||
visible.value = val
|
||||
}
|
||||
|
||||
return { visible: mounted, open, updateVisible, toggle }
|
||||
})
|
||||
|
||||
declare module 'hooks/store' {
|
||||
interface StoreProvider {
|
||||
dialogManager: ReturnType<typeof useDialogManager>
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useBoolean = (defaultValue?: boolean) => {
|
||||
const target = ref(defaultValue ?? false)
|
||||
|
||||
const toggle = (value?: any) => {
|
||||
target.value = typeof value === 'boolean' ? value : !target.value
|
||||
}
|
||||
|
||||
return [target, toggle] as const
|
||||
}
|
||||
Reference in New Issue
Block a user