Merge commit '5c3bd6b7b3d480bfaef1f5cc40995bb94a4388a5' into weather

This commit is contained in:
expdsn 2024-09-29 15:30:46 +08:00
commit 1eb9a6e0d6
14 changed files with 128 additions and 19 deletions

View File

@ -3,6 +3,7 @@ import { computed, defineComponent, ref, Transition, watch } from 'vue'
import { OhVueIcon, addIcons } from 'oh-vue-icons'
import { MdClose, MdOpeninfull, MdClosefullscreen } from 'oh-vue-icons/icons'
import asyncLoader from './utils/asyncLoader'
import widgetList from '@/widgets'
addIcons(MdClose, MdOpeninfull, MdClosefullscreen)
const SearchPage = asyncLoader(() => import('@/layout/header/search/SearchPage'))
const AdderPage = asyncLoader(() => import('@/layout/adder/AdderPage'))
@ -79,6 +80,20 @@ export default defineComponent(() => {
<SearchPage />
) : router.path === 'global-adder' ? (
<AdderPage />
) : router.path.startsWith('widget-') ? (
(() => {
const name = router.path.split('-')[1]
const selected = widgetList.find((el) => el.name === name)
if (!selected)
return (
<div class="w-full h-full flex justify-center items-center text-black/80">
</div>
)
const compo = selected.modal
console.log(compo)
return <compo />
})()
) : null}
</Transition>
</div>

12
src/index.html Normal file
View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>要什么服务器,直接 oss</div>
<script src="/test.js" />
</body>
</html>

View File

@ -3,6 +3,7 @@ import { computed, defineComponent, onUnmounted, reactive } from 'vue'
import type { Block } from './layout.types'
import clsx from 'clsx'
import useLayoutStore from './useLayoutStore'
import widgetList from '@/widgets'
const defaultDisplay = {
x: 0,
@ -102,8 +103,20 @@ export default defineComponent(() => {
const block = menu.display.type
if (!block.link) {
// 小组件
const selected = widgetList.find((el) => el.name === block.name)
return (
<>
{selected?.list.map((el) => (
<Item
onClick={() => {
block.w = el.w
block.h = el.h
menu.dismiss()
}}
>
{el.label}
</Item>
))}
<Item
alert
onClick={() => {

View File

@ -1,10 +1,12 @@
import { computed, defineComponent } from 'vue'
import { computed, defineComponent, inject } from 'vue'
import useLayoutStore from '../useLayoutStore'
import widgetList, { type Widget } from '@/widgets'
import { Button } from 'ant-design-vue'
import clsx from 'clsx'
import { AddToToken } from './AdderPage'
import { v4 as uuid } from 'uuid'
export const Item = defineComponent({
export const WidgetItem = defineComponent({
props: {
content: {
type: Object as () => Widget,
@ -14,6 +16,7 @@ export const Item = defineComponent({
setup(props) {
const layout = useLayoutStore()
const isGame = computed(() => layout.state.current === 0)
const addTo = inject(AddToToken)
return () => (
<div
class={clsx('bg-white w-full h-full rounded-lg shadow p-4', {
@ -44,7 +47,29 @@ export const Item = defineComponent({
</div>
</div>
<div class="flex justify-end">
<Button size="small" type="primary">
<Button
size="small"
type="primary"
onClick={() => {
const selected = widgetList.find((el) => el.name === props.content.name)
if (!selected || !selected.list[0]) return
layout.addBlock(
{
id: uuid(),
link: '',
name: props.content.name,
label: props.content.label,
icon: '',
text: '',
background: '',
color: '',
w: selected.list[0].w,
h: selected.list[0].h
},
addTo?.value
)
}}
>
</Button>
</div>
@ -61,7 +86,7 @@ export default defineComponent(() => {
style="grid-auto-rows: 100px"
>
{widgetList.map((el) => (
<Item content={el} key={el.name} />
<WidgetItem content={el} key={el.name} />
))}
</div>
</div>

View File

@ -5,6 +5,7 @@ import { v4 as uuid } from 'uuid'
import useLayoutStore from '../useLayoutStore'
import LinkBlock from './LinkBlock'
import DirBlock from './DirBlock'
import WidgetBlock from './WidgetBlock'
export default defineComponent({
props: {
@ -124,7 +125,7 @@ export default defineComponent({
)
) : (
// 小组件
<div></div>
<WidgetBlock block={props.block} />
)}
</div>
<div

View File

@ -0,0 +1,43 @@
import { defineComponent } from 'vue'
import widgetList from '@/widgets'
import { useMenuStore } from '../GlobalMenu'
import type { Block } from '../layout.types'
import useRouterStore from '@/useRouterStore'
export default defineComponent({
props: {
block: {
type: Object as () => Block,
required: true
}
},
setup(props) {
const menu = useMenuStore()
const router = useRouterStore()
return () => {
const placeholder = (
<div class="w-full h-full flex justify-center items-center text-black/60"></div>
)
const selected = widgetList.find((el) => el.name === props.block.name)
if (!selected) return placeholder
const compo = selected.list.find(
(el) => el.w === props.block.w && el.h === props.block.h
)?.component
if (!compo) return placeholder
return (
<div
class="w-full h-full relative"
onContextmenu={(e) => {
e.preventDefault()
menu.open(props.block)
}}
onClick={() => {
router.path = `widget-${props.block.name}`
}}
>
<compo />
</div>
)
}
}
})

1
src/test.js Normal file
View File

@ -0,0 +1 @@
console.log('hahaha')

View File

@ -1,7 +1,6 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export type WidgetStr = 'ai' | 'calendar'
export type GlobalStr = 'search' | 'block' | 'adder' | 'login'
export type SettingStr =
| 'user'
@ -14,9 +13,7 @@ export type SettingStr =
| 'dock'
| 'reset'
| 'fallback'
export type SettingSecond =
| 'background'
export type RouteStr = '' | `widget-${WidgetStr}` | `global-${GlobalStr}` | `settings-${SettingStr}` | `s2-${SettingSecond}`
export type RouteStr = '' | `widget-${string}` | `global-${GlobalStr}` | `settings-${SettingStr}`
export default defineStore('router', () => {
const path = ref<RouteStr>('')

View File

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'
export default defineComponent(() => {
return () => <div class="w-full h-full bg-red-50"></div>
return () => <div class="w-full h-full bg-red-50"></div>
})

View File

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'
export default defineComponent(() => {
return () => <div class="w-full h-full bg-red-50"></div>
return () => <div class="w-full h-full bg-red-50"></div>
})

View File

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'
export default defineComponent(() => {
return () => <div class="w-full h-full bg-red-50"></div>
return () => <div class="w-full h-full bg-red-50"></div>
})

View File

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'
export default defineComponent(() => {
return () => <div class="w-full h-full bg-red-50"></div>
return () => <div class="w-full h-full bg-red-50"></div>
})

View File

@ -1,3 +1,4 @@
import asyncLoader from '@/utils/asyncLoader'
import type { Widget } from '..'
export default {
@ -5,25 +6,25 @@ export default {
label: '日历',
description: '日历信息',
icon: '/icons/calendarIcon.png',
modal: () => import('./Modal'),
modal: asyncLoader(() => import('./Modal')),
list: [
{
w: 2,
h: 1,
label: '小',
component: () => import('./Small')
component: asyncLoader(() => import('./Small'))
},
{
w: 2,
h: 2,
label: '中',
component: () => import('./Middle')
component: asyncLoader(() => import('./Middle'))
},
{
w: 4,
h: 2,
label: '大',
component: () => import('./Large')
component: asyncLoader(() => import('./Large'))
}
]
} as Widget

View File

@ -1,3 +1,4 @@
import type { Component } from 'vue'
import calendar from './calendar'
import weather from './weather'
export interface Widget {
@ -5,12 +6,12 @@ export interface Widget {
label: string // 小组件名称
description: string // 小组件描述
icon: string // 小组件图标
modal: () => any // 弹框组件
modal: Component // 弹框组件
list: {
w: number
h: number
label: string
component: () => any
component: Component
}[] // 不同尺寸小组件块
}