更改了添图标和设置项的样式

This commit is contained in:
expdsn 2024-10-24 18:08:37 +08:00
parent 56429b19a4
commit 199ca92fb3
9 changed files with 417 additions and 201 deletions

View File

@ -106,7 +106,9 @@ export default defineComponent(() => {
const selected = widgetList.find((el) => el.name === block.name) const selected = widgetList.find((el) => el.name === block.name)
return ( return (
<> <>
{selected?.list.map((el) => ( {selected?.list &&
selected.list.length > 1 &&
selected.list.map((el) => (
<Item <Item
onClick={() => { onClick={() => {
block.w = el.w block.w = el.w
@ -157,13 +159,11 @@ export default defineComponent(() => {
</Item> </Item>
<Item <Item
onClick={() => { onClick={() => {
menu.dismiss() menu.dismiss()
const idx = layout.currentPage.list.findIndex((el) => el.id === block.id) const idx = layout.currentPage.list.findIndex((el) => el.id === block.id)
if (idx < 0) return if (idx < 0) return
layout.state.dir[id].list.forEach(val => { layout.state.dir[id].list.forEach((val) => {
layout.addBlock(val, layout.state.currentPage) layout.addBlock(val, layout.state.currentPage)
}) })
layout.currentPage.list.splice(idx, 1) layout.currentPage.list.splice(idx, 1)
delete layout.state.dir[id] delete layout.state.dir[id]

View File

@ -16,6 +16,7 @@ import clsx from 'clsx'
import ThemeProvider from '@/utils/ThemeProvider' import ThemeProvider from '@/utils/ThemeProvider'
import WidgetAdder from './WidgetAdder' import WidgetAdder from './WidgetAdder'
import { Form, Input, Select } from 'ant-design-vue' import { Form, Input, Select } from 'ant-design-vue'
import HotAdder from './HotAdder'
addIcons(MdKeyboardcommandkey, FaCompass, FaPencilRuler) addIcons(MdKeyboardcommandkey, FaCompass, FaPencilRuler)
const ItemButton = defineComponent({ const ItemButton = defineComponent({
@ -43,14 +44,14 @@ const ItemButton = defineComponent({
ctx.emit('click') ctx.emit('click')
}} }}
class={ class={
'py-4 px-4 mb-2 rounded text-sm cursor-pointer transition-all relative ' + 'py-4 px-4 mb-2 rounded-lg text-sm cursor-pointer transition-all relative ' +
(isGame.value (isGame.value
? props.active ? props.active
? 'bg-[#626471] text-[#f7a94e]' ? 'bg-[#626471] text-[#f7a94e]'
: 'hover:text-[#f7a94e] hover:bg-white/20 text-[#b4b5bb]' : 'hover:text-[#f7a94e] hover:bg-white text-[#b4b5bb]'
: props.active : props.active
? 'bg-white text-black/80 shadow' ? 'bg-white text-[#f7a94e] shadow'
: 'hover:text-black/80 hover:bg-white text-black/50') : ' hover:shadow hover:bg-white text-[#333]')
} }
> >
{props.active && ( {props.active && (
@ -60,7 +61,7 @@ const ItemButton = defineComponent({
></img> ></img>
)} )}
<OhVueIcon name={props.name} class={"ml-1"} /> <OhVueIcon name={props.name} class={'ml-1'} />
<span class="ml-2">{props.label}</span> <span class="ml-2">{props.label}</span>
</div> </div>
) )
@ -77,17 +78,20 @@ export default defineComponent(() => {
provide(AddToToken, addTo) provide(AddToToken, addTo)
return () => ( return () => (
<div <div
class={clsx('w-full h-full relative flex p-[6px]', isGame.value && 'bg-[#2c2e3e]')} class={clsx(
style={{ 'w-full h-full relative flex ',
backgroundImage: `url('/bg/gameModel.png')`, isGame.value ? 'bg-[#2C2E3D]' : 'bg-[#fffc] backdrop-blur'
backgroundSize: '100% 100%' )}
}} // style={{
// backgroundImage: `url('/bg/gameModel.png')`,
// backgroundSize: '100% 100%'
// }}
> >
<ThemeProvider dark={isGame.value}> <ThemeProvider dark={isGame.value}>
<div <div
class={ class={
'w-[220px] h-full relative z-10 pt-[100px] rounded-2xl ' + 'w-[220px] h-full relative z-10 pt-[100px] rounded-2xl ' +
(isGame.value ? 'pl-8 pr-2 bg-[#424b5d4d]' : 'bg-white/60 l backdrop-blur px-4') (isGame.value ? 'pl-8 pr-2 bg-[#424b5d4d]' : 'bg-[#fff7] px-4')
} }
> >
<ItemButton <ItemButton
@ -116,10 +120,7 @@ export default defineComponent(() => {
/> />
</div> </div>
<div <div
class={ class={'w-0 h-full flex-grow relative z-10 flex flex-col ' + (isGame.value ? '' : '')}
'w-0 h-full flex-grow relative z-10 flex flex-col ' +
(isGame.value ? '' : 'bg-white/80 backdrop-blur')
}
onContextmenu={(e) => e.stopPropagation()} onContextmenu={(e) => e.stopPropagation()}
> >
<Form class="w-full px-4 mt-4" layout="inline"> <Form class="w-full px-4 mt-4" layout="inline">
@ -140,7 +141,13 @@ export default defineComponent(() => {
<div class="w-full h-0 flex-grow p-6"> <div class="w-full h-0 flex-grow p-6">
<div class="w-full h-full relative"> <div class="w-full h-full relative">
<Transition> <Transition>
{type.value === 0 ? <WidgetAdder /> : type.value === 1 ? '' : <CustomAdder />} {type.value === 0 ? (
<WidgetAdder />
) : type.value === 1 ? (
<HotAdder />
) : (
<CustomAdder />
)}
</Transition> </Transition>
</div> </div>
</div> </div>

View File

@ -161,7 +161,7 @@ export default defineComponent(() => {
<div <div
class={ class={
'absolute left-0 top-0 w-full h-full rounded-2xl py-5 pl-6 pr-[30%] ' + 'absolute left-0 top-0 w-full h-full rounded-2xl py-5 pl-6 pr-[30%] ' +
(isGame.value ? 'bg-white/20' : 'bg-white/20') (isGame.value ? 'bg-white/20' : 'bg-white/70')
} }
> >
<Form labelCol={{ span: 4 }} labelAlign="left"> <Form labelCol={{ span: 4 }} labelAlign="left">

View File

@ -0,0 +1,168 @@
import CategoryTab from '@/utils/CategoryTab'
import request from '@/utils/request'
import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue'
import type { BackgroundType } from '../background/BackgroundSwtich'
import clsx from 'clsx'
import useLayoutStore from '../useLayoutStore'
import { AddToToken } from './AdderPage'
import { Button } from 'ant-design-vue'
interface HotAppCategoryType {
id: string
name: string
ordinal: number
}
interface HotAppType {
id: string
name: string
url: string
ordinal: number
desc: string
icon: string
background: string
}
export const LinkItem = defineComponent({
props: {
content: {
type: Object as () => HotAppType,
required: true
}
},
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', {
'bg-white/20': isGame.value,
'bg-white/80': !isGame.value
})}
key={props.content.name}
>
<div class="flex">
<img src={props.content.icon} class="w-[48px] h-[48px] bg-cover rounded-lg" />
<div class="px-2 w-0 flex-grow">
<div
class={clsx('text text-sm', {
'text-white': isGame.value,
'text-black/80': !isGame.value
})}
>
{props.content.name}
</div>
<div
class={clsx('text-[12px] line-clamp-2 text-ellipsis', {
'text-white/80': isGame.value,
'text-black/60': !isGame.value
})}
>
{props.content.desc}
</div>
</div>
</div>
<div class="flex justify-end">
<Button size="small" type="primary" onClick={() => {}}>
</Button>
</div>
</div>
)
}
})
export default defineComponent(() => {
const layout = useLayoutStore()
const loading = ref(false)
const isGame = computed(() => layout.state.current === 0)
const appList = ref<HotAppType[]>([])
const categoryList = ref<BackgroundType[]>([])
const selectType = ref('')
onMounted(() => {
console.log('hot')
request<HotAppCategoryType[]>('GET', '/api/app/hotAppTypes').then((res) => {
categoryList.value = res.map((el) => ({
id: el.id,
oridinal: el.ordinal,
type: el.name,
attr: 0
}))
selectType.value = res[0].id
})
})
watch(selectType, (val) => {
loading.value = true
request<HotAppType[]>('GET', `/api/app/hotApps?hotAppsId=${val}`)
.then((res) => {
appList.value = res
})
.finally(() => {
setTimeout(() => {
loading.value = false
}, 200)
})
})
return () => (
<div class={'w-full h-full flex flex-col gap-y-4'}>
<div class={'w-full '}>
<CategoryTab
list={categoryList.value}
selectType={selectType.value}
onUpdate:type={(e) => {
selectType.value = e
}}
v-slots={{
select: (text: string) => (
<button
class={clsx(
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
isGame.value
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
: 'text-[#000] bg-[#D6D6D6]'
)}
>
{text}
</button>
),
unSelect: (text: string) => (
<button
class={clsx(
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
isGame.value ? ' text-[#999] bg-white/10 hover:bg-white/20' : 'text-[#000] hover:bg-[#f0ecec]'
)}
>
{text}
</button>
)
}}
></CategoryTab>
</div>
<div class={'h-0 flex-1 w-full'}>
<div class={'w-full h-full overflow-y-scroll scrollbar-hide'}>
{!loading.value ? (
<div class={'w-full grid grid-cols-3 gap-4 '} style="grid-auto-rows: 100px">
{appList.value.map((el) => (
<LinkItem content={el}></LinkItem>
))}
</div>
) : (
<div class={'w-full grid grid-cols-3 gap-4 '} style="grid-auto-rows: 100px">
{Array(12)
.fill(0)
.map((el, idx) => (
<div
class={
'h-[100px] relative cursor-pointer bg-gray-500 group w-full flex-grow-0 rounded-xl overflow-hidden'
}
key={idx}
/>
))}
</div>
)}
</div>
</div>
</div>
)
})

View File

@ -17,19 +17,28 @@ export const WidgetItem = defineComponent({
const layout = useLayoutStore() const layout = useLayoutStore()
const isGame = computed(() => layout.state.current === 0) const isGame = computed(() => layout.state.current === 0)
const addTo = inject(AddToToken) const addTo = inject(AddToToken)
const isExist = computed(() => {
console.log(layout.state.content[layout.state.currentPage].pages)
return (
layout.state.content[layout.state.current].pages[layout.state.currentPage].list.findIndex(
(el) => el?.name === props.content.name
) !== -1
)
})
return () => ( return () => (
<div <div
class={clsx('bg-white w-full h-full rounded-lg shadow p-4', { class={clsx(' w-full h-full rounded-lg flex flex-col justify-between shadow p-4', {
'bg-white/20': isGame.value, 'bg-white/20': isGame.value,
'bg-white/80': !isGame.value 'bg-white/80': !isGame.value
})} })}
key={props.content.name} key={props.content.name}
> >
<div class="flex"> <div class="flex">
<img src={props.content.icon} class="w-[48px] h-[48px] bg-cover rounded-lg" /> <img src={props.content.icon} class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg" />
<div class="px-2 w-0 flex-grow"> <div class="px-2 w-0 flex-grow ">
<div <div
class={clsx('text text-sm', { class={clsx('text text-sm mb-[2px]', {
'text-white': isGame.value, 'text-white': isGame.value,
'text-black/80': !isGame.value 'text-black/80': !isGame.value
})} })}
@ -59,9 +68,27 @@ export const WidgetItem = defineComponent({
</div> </div>
</div> </div>
<div class="flex justify-end"> <div class="flex justify-end">
<Button {isExist.value ? (
size="small" <button
type="primary" class={clsx(
'rounded-2xl flex justify-center items-center text-[12px] w-[60px] h-[24px]',
{
'bg-white/40 text-[#333] ': isGame.value,
'bg-black/10 text-[#666] ': !isGame.value
}
)}
>
</button>
) : (
<button
class={clsx(
'rounded-2xl text-[12px] flex justify-center items-center w-[60px] h-[24px]',
{
'bg-[#eeeeee] text-[#333] ': isGame.value,
'bg-[#ffaa4e] text-white': !isGame.value
}
)}
onClick={() => { onClick={() => {
const selected = widgetList.find((el) => el.name === props.content.name) const selected = widgetList.find((el) => el.name === props.content.name)
if (!selected || !selected.list[0]) return if (!selected || !selected.list[0]) return
@ -83,7 +110,8 @@ export const WidgetItem = defineComponent({
}} }}
> >
</Button> </button>
)}
</div> </div>
</div> </div>
) )
@ -92,10 +120,10 @@ export const WidgetItem = defineComponent({
export default defineComponent(() => { export default defineComponent(() => {
return () => ( return () => (
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto gap-4"> <div class="absolute left-0 top-0 w-full h-full overflow-y-auto scrollbar-hide gap-4">
<div <div
class="w-full grid grid-cols-3 grid-flow-row-dense pb-[200px] gap-4" class="w-full grid grid-cols-3 grid-flow-row-dense gap-4"
style="grid-auto-rows: 100px" style="grid-auto-rows: 120px"
> >
{widgetList.map((el) => ( {widgetList.map((el) => (
<WidgetItem content={el} key={el.name} /> <WidgetItem content={el} key={el.name} />

View File

@ -8,52 +8,20 @@ export default defineComponent(() => {
return () => ( return () => (
<div class="p-4"> <div class="p-4">
<SettingItem <SettingItem
noRoundedB
v-slots={{ v-slots={{
label: () => <div></div> label: () => <div></div>
}} }}
> >
<Slider <Switch v-model:checked={settings.state.showBlockLabel} />
v-model:value={settings.state.blockSize}
step={0.1}
tooltipOpen={false}
min={4}
max={10}
/>
</SettingItem> </SettingItem>
<SettingItem <SettingItem
noRoundedT
noRoundedB
v-slots={{ v-slots={{
label: () => <div></div> label: () => <div></div>
}} }}
> >
<Slider <Switch v-model:checked={settings.state.showAdder} />
v-model:value={settings.state.blockPadding}
step={0.1}
tooltipOpen={false}
min={1}
max={2}
/>
</SettingItem> </SettingItem>
<SettingItem <SettingItem
noRoundedT
noRoundedB
v-slots={{
label: () => <div></div>
}}
>
<Slider
v-model:value={settings.state.mainWidth}
step={1}
tooltipOpen={false}
min={40}
max={80}
/>
</SettingItem>
<SettingItem
noRoundedT
noRoundedB
v-slots={{ v-slots={{
label: () => <div></div> label: () => <div></div>
}} }}
@ -67,22 +35,48 @@ export default defineComponent(() => {
/> />
</SettingItem>{' '} </SettingItem>{' '}
<SettingItem <SettingItem
v-slots={{
label: () => <div></div>
}}
>
<Slider
v-model:value={settings.state.mainWidth}
step={1}
tooltipOpen={false}
min={40}
max={80}
/>
</SettingItem>
{/* <SettingItem
noRoundedB
v-slots={{
label: () => <div></div>
}}
>
<Slider
v-model:value={settings.state.blockSize}
step={0.1}
class={"w-[200px]"}
tooltipOpen={false}
min={4}
max={10}
/>
</SettingItem> */}
{/* <SettingItem
noRoundedT noRoundedT
noRoundedB noRoundedB
v-slots={{ v-slots={{
label: () => <div></div> label: () => <div></div>
}} }}
> >
<Switch v-model:checked={settings.state.showAdder} /> <Slider
</SettingItem> v-model:value={settings.state.blockPadding}
<SettingItem step={0.1}
noRoundedT tooltipOpen={false}
v-slots={{ min={1}
label: () => <div></div> max={2}
}} />
> </SettingItem> */}
<Switch v-model:checked={settings.state.showBlockLabel} />
</SettingItem>
</div> </div>
) )
}) })

View File

@ -24,7 +24,7 @@ export default defineComponent({
setup(props, ctx) { setup(props, ctx) {
return () => ( return () => (
<div <div
class={clsx('flex items-center py-2 px-3 rounded-lg', { class={clsx('flex items-center w-full py-2 px-3 rounded-lg justify-between', {
'rounded-b-none': props.noRoundedB, 'rounded-b-none': props.noRoundedB,
'rounded-t-none': props.noRoundedT, 'rounded-t-none': props.noRoundedT,
'bg-black/5': !props.noBg 'bg-black/5': !props.noBg
@ -34,8 +34,8 @@ export default defineComponent({
}} }}
> >
<div class="text-sm text-black/60 mr-4">{ctx.slots.label?.()}</div> <div class="text-sm text-black/60 mr-4">{ctx.slots.label?.()}</div>
<div class="w-0 flex-grow">{ctx.slots.default?.()}</div> <div class="">{ctx.slots.default?.()}</div>
{ctx.slots.end?.()} {/* {ctx.slots.end?.()} */}
</div> </div>
) )
} }

View File

@ -1,8 +1,15 @@
import type { BackgroundType } from "@/layout/background/BackgroundSwtich"; import type { BackgroundType } from '@/layout/background/BackgroundSwtich'
import clsx from "clsx"; import clsx from 'clsx'
import gsap from "gsap"; import gsap from 'gsap'
import { defineComponent, reactive, ref, watch, type SlotsType, type VNode } from "vue"; import { defineComponent, reactive, ref, watch, type SlotsType, type VNode } from 'vue'
/**
* @description
* @props props:list
* @props selectType
* @slots select
* @slots unSelect
* @emits update:type
*/
export default defineComponent({ export default defineComponent({
props: { props: {
list: { list: {
@ -11,9 +18,8 @@ export default defineComponent({
}, },
selectType: { selectType: {
type: String, type: String,
required: true, required: true
}, }
}, },
slots: {} as SlotsType<{ slots: {} as SlotsType<{
select?: (text: string) => VNode[] select?: (text: string) => VNode[]
@ -21,30 +27,35 @@ export default defineComponent({
}>, }>,
emits: ['update:type'], emits: ['update:type'],
setup(props, ctx) { setup(props, ctx) {
const tabRefs = ref<(Element | null)[]>([]) const tabRefs = ref<(any | null)[]>([])
const parentRef = ref<Element | null>(null) const parentRef = ref<any | null>(null)
const number = ref(0) const number = ref(0)
const tweened = reactive({ const tweened = reactive({
number: 0 number: 0
}) })
watch(number, (n, old) => {
console.log(Math.abs(n - old) / 400)
watch(number, (n) => {
gsap.to(tweened, { gsap.to(tweened, {
number: n, number: n,
duration: .5, duration: Math.abs(n - old) / 400 < 0.5 ? 0.5 : Math.abs(n - old) / 400,
onUpdate: () => { onUpdate: () => {
if (parentRef.value) if (parentRef.value) parentRef.value.scrollLeft = tweened.number
parentRef.value.scrollLeft = tweened.number }
}, })
});
}) })
watch(() => [props.selectType], () => { watch(
() => [props.selectType],
() => {
const idx = props.list.findIndex((item) => item.id === props.selectType) const idx = props.list.findIndex((item) => item.id === props.selectType)
if (idx === -1) return if (idx === -1) return
console.log(tabRefs.value)
if (tabRefs.value[idx]) { if (tabRefs.value[idx]) {
const childRef = tabRefs.value[idx] const childRef = tabRefs.value[idx]
if (!childRef) return if (!childRef) return
if (!childRef.parentElement) return if (!childRef.parentElement) return
const parentRect = childRef.parentElement.getBoundingClientRect() const parentRect = childRef.parentElement.getBoundingClientRect()
@ -52,43 +63,51 @@ export default defineComponent({
const distance = childRect.left - parentRect.left const distance = childRect.left - parentRect.left
if (!parentRef.value) return if (!parentRef.value) return
if (idx > 3) { if (idx > 3) {
number.value = distance - 350 number.value = distance - 280
} else { } else {
number.value = 0 number.value = 0
} }
} else { } else {
number.value = 0 number.value = 0
} }
} }
) )
return () => ( return () => (
<div <div
ref={parentRef} ref={parentRef}
class="w-full overflow-x-scroll scrollbar-hide" onWheel={(e) => { class="w-full overflow-x-scroll scrollbar-hide"
onWheel={(e) => {
e.preventDefault() e.preventDefault()
if (parentRef.value) if (parentRef.value) parentRef.value.scrollLeft += e.deltaY
parentRef.value.scrollLeft += e.deltaY }}
>
}}> <div class="w-full flex gap-x-4 ">
< div class="w-full flex gap-x-2 " > {props.list.map((item, index) =>
{ item.id === props.selectType ? (
<div
props.list.map((item, index) => ( key={index}
item.id === props.selectType ? ref={(e) => {
<div > tabRefs.value[index] = e
}}
>
{ctx.slots.select?.(item.type) || <button>loading</button>} {ctx.slots.select?.(item.type) || <button>loading</button>}
</div> </div>
: <div onClick={()=> { ) : (
<div
key={index}
ref={(e) => {
tabRefs.value[index] = e
}}
onClick={() => {
ctx.emit('update:type', item.id) ctx.emit('update:type', item.id)
}}> }}
>
{ctx.slots.unSelect?.(item.type) || <button>loading</button>} {ctx.slots.unSelect?.(item.type) || <button>loading</button>}
</div> </div>
)) )
} )}
</div > </div>
</div> </div>
) )
}, }
}) })

View File

@ -38,10 +38,10 @@ export default defineComponent(() => {
watch( watch(
() => useLayoutStore().state.current, () => useLayoutStore().state.current,
(val) => { (val) => {
const type = val === 0 ? 'game' : val === 1 ? 'study' : 'entertainment' const type = val === 0 ? 'game' : val === 1 ? 'know' : 'ent'
request<GameData[]>('GET', `/api/hotVideo?type=${type}`).then((res) => { request<GameData[]>('GET', `/api/hotVideo?type=${type}`).then((res) => {
list.value = res list.value = res
currentIndex.value = randomNum(0, list.value.length) currentIndex.value = randomNum(0, res.length)
}) })
}, },
{ {