Skip to content

Commit 6c0cbac

Browse files
committed
✨ [epgs] サービス上書き機能を追加
1 parent cd3d9f2 commit 6c0cbac

File tree

3 files changed

+99
-9
lines changed

3 files changed

+99
-9
lines changed

src/miraktest-epgs/EpgsRenderer.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export const EpgsRenderer: InitPlugin["renderer"] = ({
173173
useEffect(() => {
174174
rpc.setWindowTitle(`EPGStation 録画一覧 - ${appInfo.name}`)
175175
}, [])
176+
const services = useRecoilValue(atoms.mirakurunServicesSelector)
176177

177178
return (
178179
<>
@@ -188,7 +189,7 @@ export const EpgsRenderer: InitPlugin["renderer"] = ({
188189
"leading-loose"
189190
)}
190191
>
191-
{api && channels !== null ? (
192+
{api && channels !== null && services ? (
192193
<Records
193194
api={api}
194195
channels={channels}
@@ -200,6 +201,7 @@ export const EpgsRenderer: InitPlugin["renderer"] = ({
200201
playingContent,
201202
})
202203
}}
204+
services={services}
203205
/>
204206
) : (
205207
<div

src/miraktest-epgs/components/RecordDetail.tsx

+90-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dayjs from "dayjs"
44
import React, { useCallback, useEffect, useState } from "react"
55
import { Play } from "react-feather"
66
import { useRecoilState } from "recoil"
7-
import { ContentPlayerPlayingContent } from "../../@types/plugin"
7+
import { ContentPlayerPlayingContent, Service } from "../../@types/plugin"
88
import { AutoLinkedText } from "../../shared/AutoLinkedText"
99
import { EPGStationAPI } from "../api"
1010
import { thumbnailFamily } from "../atom"
@@ -18,15 +18,23 @@ import { EPGSChannel, EPGSProgramRecord } from "../types"
1818
import "dayjs/locale/ja"
1919
dayjs.locale("ja")
2020

21-
export const RecordDetail: React.VFC<{
21+
export const RecordDetail: React.FC<{
2222
api: EPGStationAPI
2323
record: EPGSProgramRecord
2424
channels: EPGSChannel[]
2525
setPlayingContent: React.Dispatch<
2626
React.SetStateAction<ContentPlayerPlayingContent | null>
2727
>
2828
openContentPlayer: (_: ContentPlayerPlayingContent) => Promise<number>
29-
}> = ({ api, record, channels, setPlayingContent, openContentPlayer }) => {
29+
services: Service[]
30+
}> = ({
31+
api,
32+
record,
33+
channels,
34+
setPlayingContent,
35+
openContentPlayer,
36+
services,
37+
}) => {
3038
const thumbnail = [...record.thumbnails].shift()
3139
const [thumbnailUrl, setThunbnailUrl] = useRecoilState(
3240
thumbnailFamily(thumbnail || 0)
@@ -47,6 +55,8 @@ export const RecordDetail: React.VFC<{
4755
const [startAtOver, setStartAtOver] = useState(
4856
dayjs(record.startAt).format("YYYY-MM-DDTHH:mm")
4957
)
58+
const [isServiceOverride, setIsServiceOverride] = useState(false)
59+
const [serviceIdOver, setServiceIdOver] = useState(-1)
5060
const [durationOver, setDurationOver] = useState(duration / 60)
5161

5262
useEffect(() => {
@@ -66,7 +76,11 @@ export const RecordDetail: React.VFC<{
6676
(videoId: number, isNewWindow: boolean) => {
6777
const url = api.getVideoUrl({ videoId })
6878
const program = convertProgramRecordToProgram(record, channel)
69-
const service = channel ? convertChannelToService(channel) : undefined
79+
const service =
80+
isServiceOverride && 0 < serviceIdOver
81+
? services.find((service) => service.serviceId === serviceIdOver)
82+
: undefined ||
83+
(channel ? convertChannelToService(channel) : undefined)
7084
if (isStartAtOverride) {
7185
program.startAt = dayjs(startAtOver).unix() * 1000
7286
program.duration = durationOver * 1000 * 60
@@ -84,7 +98,15 @@ export const RecordDetail: React.VFC<{
8498
setPlayingContent(payload)
8599
}
86100
},
87-
[record, isStartAtOverride, startAtOver, durationOver]
101+
[
102+
record,
103+
isStartAtOverride,
104+
startAtOver,
105+
durationOver,
106+
isServiceOverride,
107+
serviceIdOver,
108+
services,
109+
]
88110
)
89111

90112
return (
@@ -249,6 +271,69 @@ export const RecordDetail: React.VFC<{
249271
</label>
250272
</div>
251273
)}
274+
<Switch.Group>
275+
<div className={clsx("flex", "items-center", "mb-2")}>
276+
<Switch
277+
checked={isServiceOverride}
278+
onChange={setIsServiceOverride}
279+
className={`${
280+
isServiceOverride ? "bg-blue-600" : "bg-gray-300"
281+
} relative inline-flex items-center h-6 rounded-full w-11`}
282+
>
283+
<span
284+
className={clsx(
285+
isServiceOverride ? "translate-x-6" : "translate-x-1",
286+
"inline-block",
287+
"w-4",
288+
"h-4",
289+
"bg-white",
290+
"rounded-full",
291+
"transition",
292+
"ease-in-out",
293+
"duration-200"
294+
)}
295+
/>
296+
</Switch>
297+
<Switch.Label className="ml-2">サービスを上書きする</Switch.Label>
298+
</div>
299+
</Switch.Group>
300+
{isServiceOverride && (
301+
<div className="w-full">
302+
<label className={clsx("block", "mt-2", "w-full")}>
303+
<span className={clsx("block", "mb-1")}>サービス</span>
304+
<select
305+
className={clsx(
306+
"appearance-none",
307+
"border",
308+
"rounded",
309+
"p-2",
310+
"mb-4",
311+
"leading-tight"
312+
)}
313+
value={serviceIdOver}
314+
onChange={(e) => {
315+
const selectedServiceId = parseInt(e.target.value)
316+
if (Number.isNaN(selectedServiceId)) {
317+
setServiceIdOver(-1)
318+
return
319+
}
320+
setServiceIdOver(selectedServiceId)
321+
}}
322+
>
323+
<option value="-1" defaultChecked>
324+
選択解除
325+
</option>
326+
{services.map((service) => {
327+
return (
328+
<option key={service.id} value={service.serviceId}>
329+
{service.name}
330+
</option>
331+
)
332+
})}
333+
</select>
334+
</label>
335+
</div>
336+
)}
252337
<div className={clsx("flex space-x-2 overflow-auto flex-wrap")}>
253338
{record.videoFiles.map((videoFile) => (
254339
<button

src/miraktest-epgs/components/Records.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ import { Switch } from "@headlessui/react"
22
import clsx from "clsx"
33
import React, { useState } from "react"
44
import { RotateCw, Search } from "react-feather"
5-
import { ContentPlayerPlayingContent } from "../../@types/plugin"
5+
import { ContentPlayerPlayingContent, Service } from "../../@types/plugin"
66
import { EPGStationAPI } from "../api"
77
import type { EPGSChannel, EPGSProgramRecord } from "../types"
88
import { RecordDetail } from "./RecordDetail"
99
import { RecordList } from "./RecordList"
1010

11-
export const Records: React.VFC<{
11+
export const Records: React.FC<{
1212
api: EPGStationAPI
1313
channels: EPGSChannel[]
1414
setPlayingContent: React.Dispatch<
1515
React.SetStateAction<ContentPlayerPlayingContent | null>
1616
>
1717
openContentPlayer: (_: ContentPlayerPlayingContent) => Promise<number>
18-
}> = ({ api, channels, setPlayingContent, openContentPlayer }) => {
18+
services: Service[]
19+
}> = ({ api, channels, setPlayingContent, openContentPlayer, services }) => {
1920
const [searchTerm, setSearchTerm] = useState<string | null>(null)
2021
const [localTerm, setLocalTerm] = useState<string>("")
2122

@@ -156,6 +157,8 @@ export const Records: React.VFC<{
156157
channels={channels}
157158
setPlayingContent={setPlayingContent}
158159
openContentPlayer={openContentPlayer}
160+
services={services}
161+
key={record.id}
159162
/>
160163
</div>
161164
) : (

0 commit comments

Comments
 (0)