@@ -4,7 +4,7 @@ import dayjs from "dayjs"
4
4
import React , { useCallback , useEffect , useState } from "react"
5
5
import { Play } from "react-feather"
6
6
import { useRecoilState } from "recoil"
7
- import { ContentPlayerPlayingContent } from "../../@types/plugin"
7
+ import { ContentPlayerPlayingContent , Service } from "../../@types/plugin"
8
8
import { AutoLinkedText } from "../../shared/AutoLinkedText"
9
9
import { EPGStationAPI } from "../api"
10
10
import { thumbnailFamily } from "../atom"
@@ -18,15 +18,23 @@ import { EPGSChannel, EPGSProgramRecord } from "../types"
18
18
import "dayjs/locale/ja"
19
19
dayjs . locale ( "ja" )
20
20
21
- export const RecordDetail : React . VFC < {
21
+ export const RecordDetail : React . FC < {
22
22
api : EPGStationAPI
23
23
record : EPGSProgramRecord
24
24
channels : EPGSChannel [ ]
25
25
setPlayingContent : React . Dispatch <
26
26
React . SetStateAction < ContentPlayerPlayingContent | null >
27
27
>
28
28
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
+ } ) => {
30
38
const thumbnail = [ ...record . thumbnails ] . shift ( )
31
39
const [ thumbnailUrl , setThunbnailUrl ] = useRecoilState (
32
40
thumbnailFamily ( thumbnail || 0 )
@@ -47,6 +55,8 @@ export const RecordDetail: React.VFC<{
47
55
const [ startAtOver , setStartAtOver ] = useState (
48
56
dayjs ( record . startAt ) . format ( "YYYY-MM-DDTHH:mm" )
49
57
)
58
+ const [ isServiceOverride , setIsServiceOverride ] = useState ( false )
59
+ const [ serviceIdOver , setServiceIdOver ] = useState ( - 1 )
50
60
const [ durationOver , setDurationOver ] = useState ( duration / 60 )
51
61
52
62
useEffect ( ( ) => {
@@ -66,7 +76,11 @@ export const RecordDetail: React.VFC<{
66
76
( videoId : number , isNewWindow : boolean ) => {
67
77
const url = api . getVideoUrl ( { videoId } )
68
78
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 )
70
84
if ( isStartAtOverride ) {
71
85
program . startAt = dayjs ( startAtOver ) . unix ( ) * 1000
72
86
program . duration = durationOver * 1000 * 60
@@ -84,7 +98,15 @@ export const RecordDetail: React.VFC<{
84
98
setPlayingContent ( payload )
85
99
}
86
100
} ,
87
- [ record , isStartAtOverride , startAtOver , durationOver ]
101
+ [
102
+ record ,
103
+ isStartAtOverride ,
104
+ startAtOver ,
105
+ durationOver ,
106
+ isServiceOverride ,
107
+ serviceIdOver ,
108
+ services ,
109
+ ]
88
110
)
89
111
90
112
return (
@@ -249,6 +271,69 @@ export const RecordDetail: React.VFC<{
249
271
</ label >
250
272
</ div >
251
273
) }
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
+ ) }
252
337
< div className = { clsx ( "flex space-x-2 overflow-auto flex-wrap" ) } >
253
338
{ record . videoFiles . map ( ( videoFile ) => (
254
339
< button
0 commit comments