|
|
@@ -1,7 +1,14 @@
|
|
|
<template>
|
|
|
- <p class="flex items-center justify-between gap-4px px-4 py-2 m-0 overflow-hidden group/item">
|
|
|
+ <p
|
|
|
+ ref="listBoxRef"
|
|
|
+ class="h-32px flex items-center justify-between gap-4px px-4 py-2 m-0 overflow-hidden group/item hover:bg-bg-tertiary"
|
|
|
+ @click="handleClick"
|
|
|
+ @contextmenu="handleContextmenu"
|
|
|
+ >
|
|
|
<span v-if="type === 'font'" class="w-32px h-32px grid place-items-center">
|
|
|
- <BsFiletypeTtf size="16px" />
|
|
|
+ <BsFiletypeTtf v-if="data.fielType === 'ttf'" size="16px" />
|
|
|
+ <BsFiletypeWoff v-else-if="data.fielType === 'woff'" size="16px" />
|
|
|
+ <img v-else :src="fontImg" class="w-16px h-16px" />
|
|
|
</span>
|
|
|
<span
|
|
|
v-if="type === 'image'"
|
|
|
@@ -15,12 +22,19 @@
|
|
|
<span class="flex-1 truncate" :title="data.fileName">{{ data.fileName }}</span>
|
|
|
|
|
|
<span class="items-center gap-8px shrink-0 hidden group-hover/item:flex">
|
|
|
- <el-tooltip content="编辑">
|
|
|
- <span class="cursor-pointer" @click="$emit('edit')"><LuPencilLine size="14px" /></span>
|
|
|
+ <el-tooltip content="编辑" :append-to="listBoxRef">
|
|
|
+ <span v-if="type !== 'other'" class="cursor-pointer" @click="handleEdit"
|
|
|
+ ><LuPencilLine size="14px"
|
|
|
+ /></span>
|
|
|
</el-tooltip>
|
|
|
- <el-tooltip content="删除">
|
|
|
+ <el-tooltip content="删除" :append-to="listBoxRef">
|
|
|
<span>
|
|
|
- <el-popconfirm class="box-item" title="确认删除?" @confirm="$emit('delete')">
|
|
|
+ <el-popconfirm
|
|
|
+ :append-to="listBoxRef"
|
|
|
+ class="box-item"
|
|
|
+ title="确认删除?"
|
|
|
+ @confirm="$emit('delete')"
|
|
|
+ >
|
|
|
<template #reference>
|
|
|
<span class="cursor-pointer"><LuTrash2 size="14px" /></span>
|
|
|
</template>
|
|
|
@@ -29,27 +43,122 @@
|
|
|
</el-tooltip>
|
|
|
</span>
|
|
|
</p>
|
|
|
+
|
|
|
+ <el-dropdown
|
|
|
+ ref="dropdownRef"
|
|
|
+ :virtual-ref="triggerRef"
|
|
|
+ :show-arrow="false"
|
|
|
+ :popper-options="{
|
|
|
+ modifiers: [{ name: 'offset', options: { offset: [0, 0] } }]
|
|
|
+ }"
|
|
|
+ virtual-triggering
|
|
|
+ trigger="contextmenu"
|
|
|
+ placement="bottom-start"
|
|
|
+ >
|
|
|
+ <template #dropdown>
|
|
|
+ <el-dropdown-menu>
|
|
|
+ <el-dropdown-item @click="openInExplorer">在资源管理器中打开</el-dropdown-item>
|
|
|
+ <el-dropdown-item @click="copyName">复制名称</el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown>
|
|
|
+
|
|
|
+ <EditImageModal ref="editImageModalRef" @change="handleChangeResource" />
|
|
|
+ <EditFontModal ref="editFontModalRef" @change="handleChangeResource" />
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import type { Resource } from '@/types/resource'
|
|
|
+import type { FontResource, ImageResource, Resource } from '@/types/resource'
|
|
|
+import type { DropdownInstance } from 'element-plus'
|
|
|
|
|
|
-import { defineProps, defineEmits } from 'vue'
|
|
|
+import { defineProps, defineEmits, ref } from 'vue'
|
|
|
import LocalImage from '@/components/LocalImage/index.vue'
|
|
|
import { useProjectStore } from '@/store/modules/project'
|
|
|
import { LuTrash2, LuPencilLine } from 'vue-icons-plus/lu'
|
|
|
import { BsFiletypeTtf, BsFiletypeWoff } from 'vue-icons-plus/bs'
|
|
|
+import fontImg from '@/assets/font.svg'
|
|
|
+import EditImageModal from './EditImageModal.vue'
|
|
|
+import EditFontModal from './EditFontModal.vue'
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
|
|
|
defineEmits<{
|
|
|
delete: []
|
|
|
- edit: []
|
|
|
}>()
|
|
|
|
|
|
-defineProps<{
|
|
|
+const props = defineProps<{
|
|
|
data: Resource
|
|
|
type: 'image' | 'font' | 'other'
|
|
|
}>()
|
|
|
+
|
|
|
+const listBoxRef = ref<HTMLElement>()
|
|
|
const projectStore = useProjectStore()
|
|
|
+const editImageModalRef = ref<InstanceType<typeof EditImageModal>>()
|
|
|
+const editFontModalRef = ref<InstanceType<typeof EditFontModal>>()
|
|
|
+
|
|
|
+const dropdownRef = ref<DropdownInstance>()
|
|
|
+const position = ref({
|
|
|
+ top: 0,
|
|
|
+ left: 0,
|
|
|
+ bottom: 0,
|
|
|
+ right: 0
|
|
|
+} as DOMRect)
|
|
|
+
|
|
|
+const triggerRef = ref({
|
|
|
+ getBoundingClientRect: () => position.value
|
|
|
+})
|
|
|
+
|
|
|
+const handleClick = () => {
|
|
|
+ dropdownRef.value?.handleClose()
|
|
|
+}
|
|
|
+
|
|
|
+const handleContextmenu = (event: MouseEvent) => {
|
|
|
+ const { clientX, clientY } = event
|
|
|
+ position.value = DOMRect.fromRect({
|
|
|
+ x: clientX,
|
|
|
+ y: clientY
|
|
|
+ })
|
|
|
+ event.preventDefault()
|
|
|
+ dropdownRef.value?.handleOpen()
|
|
|
+}
|
|
|
+
|
|
|
+// 资源管理器中打开
|
|
|
+const openInExplorer = () => {
|
|
|
+ window.electron.ipcRenderer.invoke(
|
|
|
+ 'open-file-in-explorer',
|
|
|
+ projectStore.projectPath + props.data.path
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+// 复制名称
|
|
|
+const copyName = () => {
|
|
|
+ navigator.clipboard.writeText(props.data.fileName)
|
|
|
+ ElMessage.success('复制成功')
|
|
|
+}
|
|
|
+
|
|
|
+// 打开编辑
|
|
|
+const handleEdit = () => {
|
|
|
+ if (props.type === 'image') {
|
|
|
+ editImageModalRef.value?.edit(props.data as ImageResource)
|
|
|
+ }
|
|
|
+ if (props.type === 'font') {
|
|
|
+ editFontModalRef.value?.edit(props.data as FontResource)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 编辑完成
|
|
|
+const handleChangeResource = async (resouce: Resource) => {
|
|
|
+ Object.entries(resouce).forEach(([key, value]) => {
|
|
|
+ props.data[key] = value
|
|
|
+ })
|
|
|
+ if (resouce.fileName !== props.data.fileName) {
|
|
|
+ // 文件命名修改后,更新路径及本地资源
|
|
|
+ const sourcePath = projectStore.projectPath + props.data.path
|
|
|
+ const targetPath =
|
|
|
+ projectStore.projectPath + props.data.path.replace(props.data.fileName, resouce.fileName)
|
|
|
+ await window.electron.ipcRenderer.invoke('modify-file-name', sourcePath, targetPath)
|
|
|
+ props.data.path = props.data.path.replace(props.data.fileName, resouce.fileName)
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style scoped></style>
|