右键快捷编辑缺少编辑主页功能和刷新功能

This commit is contained in:
expdsn 2024-11-15 20:32:15 +08:00
parent 368be88b5d
commit 9c32a9129e
11 changed files with 195 additions and 103 deletions

BIN
public/bg/del_icon_img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

View File

@ -17,6 +17,8 @@ import WelcomePage from './layout/grid/WelcomePage'
import TomatoPage from './layout/grid/TomatoPage' import TomatoPage from './layout/grid/TomatoPage'
import useRouterStore from './useRouterStore' import useRouterStore from './useRouterStore'
import BackupRecovery from './user/BackupRecovery' import BackupRecovery from './user/BackupRecovery'
import { ConfigProvider } from 'ant-design-vue'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
const Grid = asyncLoader(() => import('./layout/grid')) const Grid = asyncLoader(() => import('./layout/grid'))
const Fox = asyncLoader(() => import('./fox')) const Fox = asyncLoader(() => import('./fox'))
const settings = useSettingsStore() const settings = useSettingsStore()
@ -28,6 +30,7 @@ const router = useRouterStore()
const layout = useLayoutStore() const layout = useLayoutStore()
</script> </script>
<template> <template>
<ConfigProvider :locale="zhCN">
<div class="fixed left-0 top-0 w-full h-screen style-root" @contextmenu.prevent> <div class="fixed left-0 top-0 w-full h-screen style-root" @contextmenu.prevent>
<Header /> <Header />
<Background <Background
@ -73,6 +76,7 @@ const layout = useLayoutStore()
<BackupRecovery v-if="router.path === 'global-backup'"></BackupRecovery> <BackupRecovery v-if="router.path === 'global-backup'"></BackupRecovery>
</div> </div>
</ConfigProvider>
</template> </template>
<style lang="less"> <style lang="less">

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { computed, defineComponent, onUnmounted, reactive, ref } from 'vue' import { computed, defineComponent, onUnmounted, reactive, ref } from 'vue'
import type { Block, LayoutPages } from './layout.types' import type { Block } from './layout.types'
import clsx from 'clsx' import clsx from 'clsx'
import useLayoutStore from './useLayoutStore' import useLayoutStore from './useLayoutStore'
import widgetList from '@/widgets' import widgetList from '@/widgets'
@ -21,6 +21,7 @@ export const useMenuStore = defineStore('menu', () => {
label: string label: string
name: string name: string
}>() }>()
const isEditPage = ref(false)
const showEditPage = ref(false) const showEditPage = ref(false)
const mPos = { const mPos = {
x: 0, x: 0,
@ -49,6 +50,7 @@ export const useMenuStore = defineStore('menu', () => {
display, display,
open, open,
dismiss, dismiss,
isEditPage,
show, show,
selectPage, selectPage,
showEditPage showEditPage
@ -155,6 +157,15 @@ export default defineComponent(() => {
> >
</Item> </Item>
<Item
noStyle
onClick={() => {
menu.isEditPage = true
menu.dismiss()
}}
>
</Item>
<Item <Item
noStyle noStyle
onClick={() => { onClick={() => {
@ -164,6 +175,15 @@ export default defineComponent(() => {
> >
</Item> </Item>
<Item
noStyle
onClick={() => {
window.location.reload()
menu.dismiss()
}}
>
</Item>
</> </>
) )
} }

View File

@ -154,7 +154,6 @@ export default defineComponent(() => {
fill={isGame.value ? 'white' : 'black'} fill={isGame.value ? 'white' : 'black'}
name={BiChevronDown.name} name={BiChevronDown.name}
class="group pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 size-4 " class="group pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 size-4 "
aria-hidden="true"
/> />
</div> </div>
</div> </div>

View File

@ -7,6 +7,9 @@ import LinkBlock from './LinkBlock'
import DirBlock from './DirBlock' import DirBlock from './DirBlock'
import WidgetBlock from './WidgetBlock' import WidgetBlock from './WidgetBlock'
import useSettingsStore from '@/settings/useSettingsStore' import useSettingsStore from '@/settings/useSettingsStore'
import { useMenuStore } from '../GlobalMenu'
import { block } from '@milkdown/kit/plugin/block'
import clsx from 'clsx'
export default defineComponent({ export default defineComponent({
props: { props: {
@ -22,11 +25,15 @@ export default defineComponent({
setup(props) { setup(props) {
const settings = useSettingsStore() const settings = useSettingsStore()
const layout = useLayoutStore() const layout = useLayoutStore()
const menu = useMenuStore()
let it: any = 0 let it: any = 0
const hover = ref(false) const hover = ref(false)
return () => ( return () => (
<div <div
class="w-full h-full p-[var(--block-padding)] relative rounded-lg" class={clsx(
'w-full h-full p-[var(--block-padding)] relative rounded-lg ',
menu.isEditPage && 'animate-wiggle'
)}
key={props.block.id} key={props.block.id}
id={props.block.id} id={props.block.id}
style={{ style={{
@ -115,10 +122,38 @@ export default defineComponent({
} }
}} }}
> >
{menu.isEditPage && (
<div
v-outside-click={() => {
menu.isEditPage = false
}}
onClick={(e) => {
e.stopPropagation()
const idx = layout.state.content[layout.state.current].pages[
layout.state.currentPage
].list.findIndex((val) => val.id === props.block.id)
if (idx < 0) return
layout.state.content[layout.state.current].pages[
layout.state.currentPage
].list.splice(idx, 1)
}}
class={
'rounded-full cursor-pointer backdrop-blur-md absolute w-[20px] h-[20px] top-[8px] right-[12px] z-10 '
}
style={{
backgroundImage: `url('/tab/bg/del_icon_img.png')`,
backgroundSize: 'cover'
}}
></div>
)}
<div <div
class="w-full h-full overflow-hidden relative cursor-pointer shadow-lg hover-move " class="w-full h-full overflow-hidden relative cursor-pointer shadow-lg hover-move "
style={{ style={{
borderRadius: `calc(var(--block-radius) * var(--block-size))` borderRadius: `calc(var(--block-radius) * var(--block-size))`,
transition: 'transform 0.2s'
}} }}
onContextmenu={(e) => { onContextmenu={(e) => {
e.stopPropagation() e.stopPropagation()

View File

@ -2,18 +2,17 @@ import './main.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate' import persist from 'pinia-plugin-persistedstate'
import App from './App.vue' import App from './App.vue'
import getFp from './utils/getFp' import getFp from './utils/getFp'
import vOutsideClick from './utils/vOutsideClick' import vOutsideClick from './utils/vOutsideClick'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import Toast, { useToast } from 'vue-toastification'
import Toast, { useToast, type PluginOptions } from 'vue-toastification'
import customParseFormat from 'dayjs/plugin/customParseFormat' import customParseFormat from 'dayjs/plugin/customParseFormat'
import 'vue-toastification/dist/index.css' import 'vue-toastification/dist/index.css'
import 'dayjs/locale/zh-cn' import 'dayjs/locale/zh-cn'
dayjs.locale('zh-cn') dayjs.locale('zh-cn')
const app = createApp(App) const app = createApp(App)
export const globalToast = useToast() export const globalToast = useToast()
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)

View File

@ -3,6 +3,7 @@ import { useWeApplyStore } from './useWeApplyStore'
import { addIcons, OhVueIcon } from 'oh-vue-icons' import { addIcons, OhVueIcon } from 'oh-vue-icons'
import { HiChevronDown } from 'oh-vue-icons/icons' import { HiChevronDown } from 'oh-vue-icons/icons'
import clsx from 'clsx' import clsx from 'clsx'
import jump from '@/utils/jump'
addIcons(HiChevronDown) addIcons(HiChevronDown)
export default defineComponent(() => { export default defineComponent(() => {
const store = useWeApplyStore() const store = useWeApplyStore()
@ -74,7 +75,12 @@ export default defineComponent(() => {
{store.state.list {store.state.list
.filter((val) => val.type === 'game') .filter((val) => val.type === 'game')
.map((item) => ( .map((item) => (
<div class={'flex gap-x-2 items-center'}> <div
class={'flex gap-x-2 items-center'}
onClick={() => {
jump(item.url)
}}
>
<img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img> <img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img>
<div class={'flex-1 flex flex-col overflow-hidden'}> <div class={'flex-1 flex flex-col overflow-hidden'}>
<span class={'text-white text-[14px]'}>{item.name}</span> <span class={'text-white text-[14px]'}>{item.name}</span>
@ -107,7 +113,6 @@ export default defineComponent(() => {
if (workRef.value) { if (workRef.value) {
workRef.value.scrollTop += 20 workRef.value.scrollTop += 20
handleWorkScroll() handleWorkScroll()
} }
}} }}
> >
@ -125,7 +130,12 @@ export default defineComponent(() => {
{store.state.list {store.state.list
.filter((val) => val.type === 'work') .filter((val) => val.type === 'work')
.map((item) => ( .map((item) => (
<div class={'flex gap-x-2 items-center'}> <div
class={'flex gap-x-2 items-center'}
onClick={() => {
jump(item.url)
}}
>
<img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img> <img src={item.icon} alt="game icon" class={'w-[37px] h-[37px] rounded'}></img>
<div class={'flex-1 flex flex-col overflow-hidden'}> <div class={'flex-1 flex flex-col overflow-hidden'}>
<span class={'text-white text-[14px]'}>{item.name}</span> <span class={'text-white text-[14px]'}>{item.name}</span>

View File

@ -1,9 +1,9 @@
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { formatSeconds } from '@/utils/tool' import { formatSeconds } from '@/utils/tool'
import PlayStartImg from "~/icons/work/start.png" import PlayStartImg from '~/icons/work/start.png'
import returnImg from "~/icons/work/return.png" import returnImg from '~/icons/work/return.png'
import endImg from "~/icons/work/tomotoIconEnd.png" import endImg from '~/icons/work/tomotoIconEnd.png'
import PlusImg from "~/icons/work/tomatoIconAdd.png" import PlusImg from '~/icons/work/tomatoIconAdd.png'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { Tooltip } from 'ant-design-vue' import { Tooltip } from 'ant-design-vue'
import useTomatoStore from './useTomatoStore' import useTomatoStore from './useTomatoStore'
@ -11,41 +11,54 @@ import useTomatoStore from './useTomatoStore'
export default defineComponent(() => { export default defineComponent(() => {
const store = useTomatoStore() const store = useTomatoStore()
return () => ( return () => (
<div class="w-full h-full flex relative p-6 justify-between" style={{ <div
class="w-full h-full flex relative p-6 justify-between"
style={{
background: `url('https://newfatfox.oss-cn-beijing.aliyuncs.com/admin/tomotoback.png')`, background: `url('https://newfatfox.oss-cn-beijing.aliyuncs.com/admin/tomotoback.png')`,
backgroundSize: 'cover', backgroundSize: 'cover',
backgroundRepeat: 'no-repeat' backgroundRepeat: 'no-repeat'
}}> }}
<div class={"bg-[#0000004d] absolute top-0 left-0 right-0 bottom-0 "}></div> >
<div class={"w-[115px] h-full flex flex-col items-center z-10 text-white"}> <div class={'bg-[#0000004d] absolute top-0 left-0 right-0 bottom-0 '}></div>
<div class={"w-full bg-white/20 text-center rounded text-[14px]"}></div> <div class={'w-[115px] h-full flex flex-col items-center z-10 text-white'}>
<span class={"text-[42px] mb-1"}> <div
{ class={
store.state.beginTime < 0 ? '15:00' : formatSeconds(store.remainingTime) 'w-full bg-white/20 text-center rounded text-[14px] overflow-hidden text-ellipsis whitespace-nowrap'
} }
</span> >
<span class={"text-[14px]"}> {store.state.list[0] ? store.state.list[0].title : '无目标'}
<span class={"text-[#76e6ff] mx-1"}>
{store.state.timeList.filter(val => dayjs(val).isSame(dayjs(), 'day')).length}</span>
</span>
<span class={"text-[14px]"}></span>
</div> </div>
<div class={"flex flex-col justify-end"}> <span class={'text-[42px] mb-1'}>
<div class={"flex gap-x-3 "}> {store.state.beginTime < 0 ? '15:00' : formatSeconds(store.remainingTime)}
<Tooltip title={"沉浸模式"}> </span>
<span class={'text-[14px]'}>
<span class={'text-[#76e6ff] mx-1'}>
{store.state.timeList.filter((val) => dayjs(val).isSame(dayjs(), 'day')).length}
</span>
</span>
<span class={'text-[14px]'}></span>
</div>
<div class={'flex flex-col justify-end'}>
<div class={'flex gap-x-3 '}>
<Tooltip title={'沉浸模式'}>
<div <div
onClick={(e) => { onClick={(e) => {
e.stopPropagation() e.stopPropagation()
store.openFullscreen = true store.openFullscreen = true
}} }}
class={"w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl"}> class={
<img src={returnImg} alt="start" class={"w-[18px]"}></img> 'w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl'
}
>
<img src={returnImg} alt="start" class={'w-[18px]'}></img>
</div> </div>
</Tooltip> </Tooltip>
<Tooltip title={"开始"}> <Tooltip title={'开始'}>
<div class={"w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl"} <div
class={
'w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl'
}
onClick={(e) => { onClick={(e) => {
e.stopPropagation() e.stopPropagation()
if (store.state.isStart) { if (store.state.isStart) {
@ -53,30 +66,30 @@ export default defineComponent(() => {
} else { } else {
store.beginTomatoTime() store.beginTomatoTime()
store.openFullscreen = true store.openFullscreen = true
}
}}>
{
store.state.isStart ?
<img src={endImg} alt="start" class={"w-[18px]"}></img>
:
<img src={PlayStartImg} alt="start" class={"w-[18px]"}></img>
} }
}}
>
{store.state.isStart ? (
<img src={endImg} alt="start" class={'w-[18px]'}></img>
) : (
<img src={PlayStartImg} alt="start" class={'w-[18px]'}></img>
)}
</div> </div>
</Tooltip> </Tooltip>
<Tooltip title={"添加目标"}> <Tooltip title={'添加目标'}>
<div class={"w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl"} <div
class={
'w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl'
}
onClick={() => { onClick={() => {
setTimeout(() => { setTimeout(() => {
store.openShowModel = null store.openShowModel = null
}, 300) }, 300)
}}> }}
<img src={PlusImg} alt="start" class={"w-[18px]"}></img> >
<img src={PlusImg} alt="start" class={'w-[18px]'}></img>
</div> </div>
</Tooltip> </Tooltip>
</div> </div>
</div> </div>
</div> </div>

View File

@ -130,7 +130,8 @@ const EditContent = defineComponent(() => {
{!form.value.remindTime ? '选择时间' : dayjs(form.value.remindTime).format('HH:mm')} {!form.value.remindTime ? '选择时间' : dayjs(form.value.remindTime).format('HH:mm')}
<img src={DownImg} class={"w-[12px] object-cover "}></img> <img src={DownImg} class={"w-[12px] object-cover "}></img>
<TimePicker <TimePicker
format={'HH:mm'}
showNow={false}
class={'absolute opacity-0 left-0 top-0 w-full h-full'} class={'absolute opacity-0 left-0 top-0 w-full h-full'}
onChange={(e) => { onChange={(e) => {
form.value.remindTime = dayjs(e).valueOf() form.value.remindTime = dayjs(e).valueOf()

View File

@ -66,7 +66,8 @@ export default defineComponent(() => {
</div> </div>
<div class={"w-[16px] hidden group-hover:flex z-10 h-[16px] absolute -right-1 -top-1 bg-[#ddd] rounded-full items-center justify-center"} <div class={"w-[16px] hidden group-hover:flex z-10 h-[16px] absolute -right-1 -top-1 bg-[#ddd] rounded-full items-center justify-center"}
onClick={() => { onClick={(e) => {
e.stopPropagation()
const idx = store.state.list.findIndex(val => val.id === item.id) const idx = store.state.list.findIndex(val => val.id === item.id)
if (idx !== -1) { if (idx !== -1) {
store.state.list.splice(0, 1) store.state.list.splice(0, 1)

View File

@ -5,7 +5,17 @@ module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: 'class', darkMode: 'class',
theme: { theme: {
extend: {} extend: {
animation: {
wiggle: 'wiggle .3s ease-in-out infinite'
},
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-1deg)' },
'50%': { transform: 'rotate(1deg)' }
}
}
}
}, },
plugins: [require('@tailwindcss/typography')] plugins: [require('@tailwindcss/typography')]