212 lines
6.0 KiB
TypeScript
212 lines
6.0 KiB
TypeScript
|
|
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 { v4 as uuid } from 'uuid'
|
||
|
|
import { Button } from 'ant-design-vue'
|
||
|
|
const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||
|
|
interface GameType {
|
||
|
|
id: string
|
||
|
|
name: string
|
||
|
|
rom: string
|
||
|
|
playstation: string
|
||
|
|
hot: number
|
||
|
|
category: string
|
||
|
|
despt: string
|
||
|
|
icon: string
|
||
|
|
}
|
||
|
|
export const GameItem = defineComponent({
|
||
|
|
props: {
|
||
|
|
content: {
|
||
|
|
type: Object as () => GameType,
|
||
|
|
required: true
|
||
|
|
}
|
||
|
|
},
|
||
|
|
setup(props) {
|
||
|
|
const layout = useLayoutStore()
|
||
|
|
const isGame = computed(() => layout.state.current === 0)
|
||
|
|
const addTo = inject(AddToToken)
|
||
|
|
return () => (
|
||
|
|
<div
|
||
|
|
class={clsx(' w-full h-full rounded-lg flex flex-col justify-between 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.replace('res/game', URL_ADDRESS)}
|
||
|
|
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
||
|
|
style={{
|
||
|
|
background: props.content.icon
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<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.despt}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="flex justify-end">
|
||
|
|
<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={() => {
|
||
|
|
layout.addBlock(
|
||
|
|
{
|
||
|
|
id: uuid(),
|
||
|
|
link: '',
|
||
|
|
name: props.content.name,
|
||
|
|
label: props.content.name,
|
||
|
|
icon: '',
|
||
|
|
text: '',
|
||
|
|
background: '',
|
||
|
|
color: '',
|
||
|
|
w: 1,
|
||
|
|
h: 1
|
||
|
|
},
|
||
|
|
addTo?.value
|
||
|
|
)
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
添加
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
export default defineComponent(() => {
|
||
|
|
const layout = useLayoutStore()
|
||
|
|
const loading = ref(false)
|
||
|
|
const isGame = computed(() => layout.state.current === 0)
|
||
|
|
const appList = ref<GameType[]>([])
|
||
|
|
const selectType = ref('fc')
|
||
|
|
|
||
|
|
watch(
|
||
|
|
selectType,
|
||
|
|
(val) => {
|
||
|
|
loading.value = true
|
||
|
|
|
||
|
|
request<GameType[]>('GET', `/api/games?type=${val}`)
|
||
|
|
.then((res) => {
|
||
|
|
appList.value = res
|
||
|
|
})
|
||
|
|
.finally(() => {
|
||
|
|
setTimeout(() => {
|
||
|
|
loading.value = false
|
||
|
|
}, 200)
|
||
|
|
})
|
||
|
|
},
|
||
|
|
{
|
||
|
|
immediate: true
|
||
|
|
}
|
||
|
|
)
|
||
|
|
return () => (
|
||
|
|
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
||
|
|
<div class={'w-full '}>
|
||
|
|
<CategoryTab
|
||
|
|
list={[
|
||
|
|
{
|
||
|
|
id: 'fc',
|
||
|
|
type: '经典红白机',
|
||
|
|
attr: 0,
|
||
|
|
oridinal: 0
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'md',
|
||
|
|
type: '经典世嘉',
|
||
|
|
attr: 1,
|
||
|
|
oridinal: 1
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'gma',
|
||
|
|
type: '经典GBA',
|
||
|
|
attr: 3,
|
||
|
|
oridinal: 3
|
||
|
|
}
|
||
|
|
]}
|
||
|
|
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: 120px">
|
||
|
|
{appList.value.map((el) => (
|
||
|
|
<GameItem content={el}></GameItem>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
<div class={'w-full grid grid-cols-3 gap-4 '} style="grid-auto-rows: 120px">
|
||
|
|
{Array(12)
|
||
|
|
.fill(0)
|
||
|
|
.map((el, idx) => (
|
||
|
|
<div
|
||
|
|
class={
|
||
|
|
' relative cursor-pointer bg-gray-500 group w-full flex-grow-0 rounded-xl overflow-hidden'
|
||
|
|
}
|
||
|
|
key={idx}
|
||
|
|
/>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
})
|