Skip to content

Commit a5ebebd

Browse files
committed
しょぼいカレンダーの放送時間の取得を改善 & 整理
1 parent f4bb649 commit a5ebebd

File tree

8 files changed

+617
-521
lines changed

8 files changed

+617
-521
lines changed

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"dependencies": {
1919
"@icons-pack/react-simple-icons": "^10.0.0",
2020
"@internationalized/date": "^3.5.6",
21-
"@midra/nco-api": "^1.6.12",
21+
"@midra/nco-api": "^1.7.1",
2222
"@midra/nco-parser": "^1.0.25",
2323
"@nextui-org/react": "^2.4.8",
2424
"@webext-core/messaging": "^1.4.0",
@@ -27,29 +27,30 @@
2727
"deepmerge": "^4.3.1",
2828
"fast-deep-equal": "^3.1.3",
2929
"filesize": "^10.1.6",
30-
"framer-motion": "^11.11.8",
30+
"framer-motion": "^11.11.9",
3131
"hotkeys-js": "^3.13.7",
32-
"lucide-react": "^0.452.0",
32+
"lucide-react": "^0.453.0",
3333
"nanoid": "^5.0.7",
3434
"nanoid-dictionary": "^4.3.0",
3535
"react": "^18.3.1",
3636
"react-detectable-overflow": "^0.8.0",
3737
"react-dom": "^18.3.1",
3838
"react-hotkeys-hook": "^4.5.1",
39-
"react-virtuoso": "^4.11.0"
39+
"react-virtuoso": "^4.12.0"
4040
},
4141
"devDependencies": {
4242
"@types/nanoid-dictionary": "^4.2.3",
4343
"@types/react": "^18.3.11",
4444
"@types/react-dom": "^18.3.1",
4545
"@wxt-dev/module-react": "^1.1.1",
4646
"autoprefixer": "^10.4.20",
47+
"clsx": "^2.1.1",
4748
"cssnano": "^7.0.6",
4849
"postcss": "^8.4.47",
4950
"prettier": "^3.3.3",
5051
"prettier-plugin-tailwindcss": "^0.6.8",
5152
"sass": "^1.79.5",
52-
"tailwindcss": "^3.4.13",
53+
"tailwindcss": "^3.4.14",
5354
"typescript": "^5.6.3",
5455
"utility-types": "^3.11.0",
5556
"wxt": "^0.19.11"

pnpm-lock.yaml

+400-388
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constants/channels.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
import {
77
JIKKYO_CHANNELS_DTV,
88
JIKKYO_CHANNELS_BS_CS,
9+
CHANNEL_IDS_JIKKYO_SYOBOCAL,
910
} from '@midra/nco-api/constants'
1011

1112
export const JIKKYO_CHANNEL_GROUPS = {
@@ -18,3 +19,7 @@ export const JIKKYO_CHANNEL_GROUPS = {
1819
IDS: Object.keys(JIKKYO_CHANNELS_BS_CS) as JikkyoBsCsChannelId[],
1920
},
2021
}
22+
23+
export const SYOBOCAL_CHANNEL_IDS = CHANNEL_IDS_JIKKYO_SYOBOCAL.map(
24+
([_, scChId]) => scChId
25+
)

src/entrypoints/popup/MainPane/Search/SyobocalResults/SubtitleDetail.tsx

+49-47
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,16 @@ import {
1212
} from 'react'
1313
import { Spinner } from '@nextui-org/react'
1414
import { ncoApi } from '@midra/nco-api'
15-
import { CHANNEL_IDS_JIKKYO_SYOBOCAL } from '@midra/nco-api/constants'
1615
import { syobocalToJikkyoChId } from '@midra/nco-api/utils/syobocalToJikkyoChId'
1716

17+
import { SYOBOCAL_CHANNEL_IDS } from '@/constants/channels'
18+
1819
import { useNcoState } from '@/hooks/useNco'
1920

2021
import { SlotItem } from '@/components/slot-item'
2122

2223
let controller: AbortController | undefined
2324

24-
const SYOBOCAL_CHANNEL_IDS = CHANNEL_IDS_JIKKYO_SYOBOCAL.map(
25-
([_, scChId]) => scChId
26-
)
27-
2825
export type SubtitleDetailHandle = {
2926
initialize: () => void
3027
}
@@ -39,18 +36,57 @@ export const SubtitleDetail = forwardRef<
3936
SubtitleDetailProps
4037
>(({ title, subtitle }, ref) => {
4138
const [isLoading, setIsLoading] = useState(false)
42-
const [slotDetails, setSlotDetails] = useState<StateSlotDetailJikkyo[]>([])
39+
const [currentTid, setCurrentTid] = useState('')
40+
const [programs, setPrograms] = useState<SyoboCalProgram[]>([])
4341

4442
const stateSlotDetails = useNcoState('slotDetails')
4543

4644
const ids = useMemo(() => {
4745
return stateSlotDetails?.map((v) => v.id)
4846
}, [stateSlotDetails])
4947

48+
const programItems = useMemo(() => {
49+
const currentTime = Date.now() / 1000
50+
const slotTitle = [title.Title, `#${Number(subtitle[0])}`, subtitle[1]]
51+
.join(' ')
52+
.trim()
53+
54+
const details: StateSlotDetailJikkyo[] = programs.flatMap((program) => {
55+
const id = `${syobocalToJikkyoChId(program.ChID)}:${program.StTime}-${program.EdTime}`
56+
57+
if (currentTime < parseInt(program.EdTime)) {
58+
return []
59+
}
60+
61+
const starttime = parseInt(program.StTime) * 1000
62+
const endtime = parseInt(program.EdTime) * 1000
63+
64+
return {
65+
type: 'jikkyo',
66+
id,
67+
status: 'pending',
68+
info: {
69+
id: program.TID,
70+
title: slotTitle,
71+
duration: (endtime - starttime) / 1000,
72+
date: [starttime, endtime],
73+
count: {
74+
comment: 0,
75+
},
76+
},
77+
}
78+
})
79+
80+
return details
81+
}, [programs])
82+
5083
const initialize = useCallback(() => {
84+
if (title.TID === currentTid) return
85+
5186
controller?.abort()
5287

53-
setSlotDetails([])
88+
setCurrentTid(title.TID)
89+
setPrograms([])
5490
setIsLoading(true)
5591

5692
controller = new AbortController()
@@ -77,50 +113,16 @@ export const SubtitleDetail = forwardRef<
77113
})
78114
.catch(() => reject())
79115
})
80-
.then((programs) => {
81-
const slotTitle = [title.Title, `#${subtitle[0]}`, subtitle[1]]
82-
.join(' ')
83-
.trim()
84-
85-
const currentTime = Date.now() / 1000
86-
87-
const details: StateSlotDetailJikkyo[] = programs.flatMap((program) => {
88-
const id = `${syobocalToJikkyoChId(program.ChID)}:${program.StTime}-${program.EdTime}`
89-
90-
if (currentTime < parseInt(program.EdTime)) {
91-
return []
92-
}
93-
94-
const starttime = parseInt(program.StTime) * 1000
95-
const endtime = parseInt(program.EdTime) * 1000
96-
97-
return {
98-
type: 'jikkyo',
99-
id,
100-
status: 'pending',
101-
info: {
102-
id: program.TID,
103-
title: slotTitle,
104-
duration: (endtime - starttime) / 1000,
105-
date: [starttime, endtime],
106-
count: {
107-
comment: 0,
108-
},
109-
},
110-
}
111-
})
112-
113-
setSlotDetails(details)
114-
})
115-
.catch(() => setSlotDetails([]))
116+
.then((value) => setPrograms(value))
117+
.catch(() => setPrograms([]))
116118
.finally(() => setIsLoading(false))
117-
}, [title, subtitle])
119+
}, [title, subtitle, currentTid])
118120

119121
useImperativeHandle(ref, () => {
120122
return { initialize }
121123
}, [initialize])
122124

123-
return isLoading || !slotDetails.length ? (
125+
return isLoading || !programItems.length ? (
124126
<div className="flex size-full items-center justify-center py-1">
125127
{isLoading ? (
126128
<Spinner size="sm" color="primary" />
@@ -131,8 +133,8 @@ export const SubtitleDetail = forwardRef<
131133
)}
132134
</div>
133135
) : (
134-
<div className="flex flex-col gap-2">
135-
{slotDetails.map((detail) => (
136+
<div className="flex flex-col gap-1.5">
137+
{programItems.map((detail) => (
136138
<SlotItem
137139
key={detail.id}
138140
detail={detail}

src/entrypoints/popup/MainPane/Search/SyobocalResults/SubtitleItem.tsx

+20-30
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@ import type { SubtitleDetailHandle } from './SubtitleDetail'
55
import { useState, useImperativeHandle, forwardRef, useRef } from 'react'
66
import { cn } from '@nextui-org/react'
77
import { TRANSITION_VARIANTS } from '@nextui-org/framer-utils'
8-
import {
9-
AnimatePresence,
10-
LazyMotion,
11-
domAnimation,
12-
useWillChange,
13-
m,
14-
} from 'framer-motion'
8+
import { LazyMotion, domAnimation, useWillChange, m } from 'framer-motion'
159
import { useOverflowDetector } from 'react-detectable-overflow'
1610
import { ChevronDownIcon } from 'lucide-react'
1711

@@ -99,29 +93,25 @@ export const SubtitleItem = forwardRef<SubtitleItemHandle, SubtitleItemProps>(
9993
</div>
10094
</div>
10195

102-
<AnimatePresence initial={false}>
103-
{isOpen && (
104-
<LazyMotion features={domAnimation}>
105-
<m.div
106-
key="subtitle-detail"
107-
style={{ willChange }}
108-
initial="exit"
109-
animate="enter"
110-
exit="exit"
111-
variants={transitionVariants}
112-
onKeyDown={(e) => e.stopPropagation()}
113-
>
114-
<div className="border-t-1 border-foreground-200 p-2">
115-
<SubtitleDetail
116-
title={title}
117-
subtitle={subtitle}
118-
ref={detailRef}
119-
/>
120-
</div>
121-
</m.div>
122-
</LazyMotion>
123-
)}
124-
</AnimatePresence>
96+
<LazyMotion features={domAnimation}>
97+
<m.div
98+
key="subtitle-detail"
99+
style={{ willChange }}
100+
initial="exit"
101+
animate={isOpen ? 'enter' : 'exit'}
102+
exit="exit"
103+
variants={transitionVariants}
104+
onKeyDown={(e) => e.stopPropagation()}
105+
>
106+
<div className="border-t-1 border-foreground-200 p-1.5">
107+
<SubtitleDetail
108+
title={title}
109+
subtitle={subtitle}
110+
ref={detailRef}
111+
/>
112+
</div>
113+
</m.div>
114+
</LazyMotion>
125115
</PanelItem>
126116
)
127117
}

0 commit comments

Comments
 (0)