File size: 1,519 Bytes
38ee3c1
f0b240d
 
 
 
 
 
 
 
 
 
38ee3c1
f0b240d
 
38ee3c1
f0b240d
 
 
 
 
 
 
 
0f0ce9b
 
 
 
 
 
 
 
 
 
 
 
f0b240d
 
 
38ee3c1
 
f0b240d
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { useI18n } from "../i18n/I18nContext";
import type { SuggestedVideo } from "../types/api";

type Props = {
  videos: SuggestedVideo[];
  activeId: string | null;
  loadingId: string | null;
  onSelect: (video: SuggestedVideo) => void;
};

export function SuggestedRail({ videos, activeId, loadingId, onSelect }: Props) {
  const { t } = useI18n();
  return (
    <aside className="suggested-rail">
      <p className="rail-title">{t.watch.upNext}</p>
      {videos.map((v) => (
        <button
          key={v.id}
          type="button"
          className={`suggested-card ${activeId === v.id ? "active" : ""}`}
          onClick={() => onSelect(v)}
          disabled={loadingId === v.id}
        >
          <img
            src={v.thumbnail_url}
            alt=""
            className="suggested-thumb"
            onError={(e) => {
              const img = e.currentTarget;
              if (!img.dataset.fallback) {
                img.dataset.fallback = "1";
                img.src = `https://i.ytimg.com/vi/${v.id}/hqdefault.jpg`;
              }
            }}
          />
          <div className="suggested-info">
            <p className="suggested-title">{v.title}</p>
            <p className="suggested-channel">{v.channel_title}</p>
            {!v.embeddable && <span className="embed-badge">{t.watch.externalOnly}</span>}
            {loadingId === v.id && <span className="loading-tag">{t.watch.loadingComments}</span>}
          </div>
        </button>
      ))}
    </aside>
  );
}