Skip to content

Commit a205135

Browse files
committed
✨ サイドバーにメインサービスのみを集約した簡易切り替えメニューを追加
1 parent d93666b commit a205135

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/components/contentPlayer/controllers/Sidebar.tsx

+91
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useRecoilValue } from "recoil"
66
import { lastEpgUpdatedAtom } from "../../../atoms/contentPlayer"
77
import { useNow } from "../../../hooks/date"
88
import { ChannelType, Program, Service } from "../../../infra/mirakurun/api"
9+
import { convertVariationSelectedClosed } from "../../../utils/enclosed"
910
import { EscapeEnclosed } from "../../common/EscapeEnclosed"
1011

1112
export const ControllerSidebar: React.FC<{
@@ -106,6 +107,96 @@ export const ControllerSidebar: React.FC<{
106107
))}
107108
</div>
108109
<div className={clsx("overflow-auto")}>
110+
<div
111+
className={clsx("grid", "grid-cols-2", "gap-2", "lg:grid-cols-3")}
112+
>
113+
{Object.values(
114+
targetServices.reduce(
115+
(services: Record<string, Service[]>, service) => {
116+
const identifier =
117+
service.channel?.type === "CS"
118+
? service.id
119+
: service.remoteControlKeyId ??
120+
service.channel?.channel ??
121+
service.id
122+
if (!identifier) {
123+
return services
124+
}
125+
if (!services[identifier]) {
126+
services[identifier] = [service]
127+
} else {
128+
services[identifier].push(service)
129+
}
130+
return services
131+
},
132+
{}
133+
)
134+
)
135+
.sort(
136+
(a, b) =>
137+
(a[0].remoteControlKeyId ?? a[0].serviceId) -
138+
(b[0].remoteControlKeyId ?? b[0].serviceId)
139+
)
140+
.map((services) => {
141+
const service = services[0]
142+
const programs = queriedPrograms
143+
.filter(
144+
(program) =>
145+
program.serviceId === service.serviceId &&
146+
program.networkId === service.networkId
147+
)
148+
.sort((a, b) => a.startAt - b.startAt)
149+
const current = programs?.[0]
150+
return (
151+
<button
152+
key={service.id}
153+
type="button"
154+
className={clsx(
155+
"bg-gray-800",
156+
"bg-opacity-70",
157+
"rounded-md",
158+
"flex",
159+
"flex-col",
160+
"truncate",
161+
"p-1",
162+
"cursor-pointer"
163+
)}
164+
onClick={(e) => {
165+
e.preventDefault()
166+
setService(service)
167+
}}
168+
title={convertVariationSelectedClosed(
169+
[(service.name, current?.name)]
170+
.filter((s) => s)
171+
.join("\n")
172+
)}
173+
>
174+
<span
175+
className={clsx(
176+
"flex",
177+
"space-x-2",
178+
"pointer-events-none"
179+
)}
180+
>
181+
{service.logoData && (
182+
<img
183+
className={clsx("h-6", "rounded-md", "flex-shrink-0")}
184+
src={`data:image/jpeg;base64,${service.logoData}`}
185+
/>
186+
)}
187+
<span className={clsx("flex-shrink-0")}>
188+
{service.remoteControlKeyId} {service.name}
189+
</span>
190+
</span>
191+
{current?.name && (
192+
<span className={clsx("pointer-events-none")}>
193+
<EscapeEnclosed str={current.name || ""} />
194+
</span>
195+
)}
196+
</button>
197+
)
198+
})}
199+
</div>
109200
{targetServices.map((service) => {
110201
const programs = queriedPrograms
111202
.filter(

0 commit comments

Comments
 (0)