pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

translations, bugs, and add back missing buttons

Pas 3507db40 b59b136e

+49 -26
+2
src/assets/locales/en.json
··· 758 758 "copyHlsPlaylist": "Copy HLS playlist link", 759 759 "downloadSubtitle": "Download current subtitle", 760 760 "downloadVideo": "Download video", 761 + "desktopDisclaimer": "Download this video directly to your app for offline playback.", 762 + "offlineButton": "Download for Offline Use", 761 763 "openIn": "Open in...", 762 764 "vlc": "VLC", 763 765 "iina": "IINA",
+47 -26
src/components/player/atoms/settings/Downloads.tsx
··· 16 16 const source = usePlayerStore((s) => s.source); 17 17 const currentQuality = usePlayerStore((s) => s.currentQuality); 18 18 const url = useMemo(() => { 19 - if (source?.type === "file" && currentQuality) 20 - return source.qualities[currentQuality]?.url ?? null; 19 + if (source?.type === "file") { 20 + const quality = currentQuality 21 + ? source.qualities[currentQuality] 22 + : undefined; 23 + if (quality) return quality.url; 24 + // Fallback to the first available quality if currentQuality is not set 25 + const firstQuality = Object.values(source.qualities)[0]; 26 + return firstQuality?.url; 27 + } 21 28 if (source?.type === "hls") return source.url; 22 - return null; 29 + return undefined; 23 30 }, [source, currentQuality]); 24 31 return url; 25 32 } ··· 73 80 74 81 const startOfflineDownload = useCallback(async () => { 75 82 if (!downloadUrl) return; 76 - const title = meta?.title ? meta.title : "Video"; 83 + const title = meta?.title ? meta.title : t("player.menus.downloads.title"); 77 84 const poster = meta?.poster; 78 85 let subtitleText: string | undefined; 79 86 ··· 112 119 duration, 113 120 router, 114 121 sourceType, 122 + t, 115 123 ]); 116 124 117 125 const openSubtitleDownload = useCallback(() => { ··· 121 129 if (!dataUrl) return; 122 130 window.open(dataUrl); 123 131 }, [selectedCaption]); 124 - 125 - if (!downloadUrl) return null; 126 132 127 133 return ( 128 134 <> ··· 136 142 {isDesktopApp ? ( 137 143 <> 138 144 <Menu.Paragraph marginClass="mb-6"> 139 - <Trans i18nKey="player.menus.downloads.desktopDisclaimer"> 140 - Download this video directly to your app for offline 141 - playback. 142 - </Trans> 145 + <StyleTrans k="player.menus.downloads.disclaimer" /> 146 + </Menu.Paragraph> 147 + 148 + <Menu.Paragraph marginClass="mb-6"> 149 + <Trans i18nKey="player.menus.downloads.desktopDisclaimer" /> 143 150 </Menu.Paragraph> 144 151 <Button 145 152 className="w-full mt-2" 146 153 theme="purple" 147 154 onClick={startOfflineDownload} 148 155 > 149 - {t( 150 - "player.menus.downloads.offlineButton", 151 - "Download for Offline Use", 152 - )} 156 + {t("player.menus.downloads.offlineButton")} 153 157 </Button> 154 158 </> 155 159 ) : ( ··· 183 187 // Allow context menu & left click to copy 184 188 event.preventDefault(); 185 189 186 - copyToClipboard(downloadUrl); 190 + copyToClipboard(downloadUrl ?? ""); 187 191 }} 188 192 > 189 193 {t("player.menus.downloads.copyHlsPlaylist")} ··· 202 206 {isDesktopApp ? ( 203 207 <> 204 208 <Menu.Paragraph marginClass="mb-6"> 205 - <Trans i18nKey="player.menus.downloads.desktopDisclaimer"> 206 - Download this video directly to your app for offline 207 - playback. 208 - </Trans> 209 + <Trans i18nKey="player.menus.downloads.desktopDisclaimer" /> 209 210 </Menu.Paragraph> 210 211 <Button 211 212 className="w-full mt-2" 212 213 theme="purple" 213 214 onClick={startOfflineDownload} 214 215 > 215 - {t( 216 - "player.menus.downloads.offlineButton", 217 - "Download for Offline Use", 218 - )} 216 + {t("player.menus.downloads.offlineButton")} 219 217 </Button> 220 218 </> 221 219 ) : ( 222 - <Button className="w-full" href={downloadUrl} theme="purple"> 223 - {t("player.menus.downloads.downloadVideo")} 224 - </Button> 220 + <> 221 + <Menu.ChevronLink 222 + onClick={() => router.navigate("/download/pc")} 223 + > 224 + {t("player.menus.downloads.onPc.title")} 225 + </Menu.ChevronLink> 226 + <Menu.ChevronLink 227 + onClick={() => router.navigate("/download/ios")} 228 + > 229 + {t("player.menus.downloads.onIos.title")} 230 + </Menu.ChevronLink> 231 + <Menu.ChevronLink 232 + onClick={() => router.navigate("/download/android")} 233 + > 234 + {t("player.menus.downloads.onAndroid.title")} 235 + </Menu.ChevronLink> 236 + 237 + <Menu.Divider /> 238 + 239 + <Menu.Paragraph marginClass="my-6"> 240 + <StyleTrans k="player.menus.downloads.disclaimer" /> 241 + </Menu.Paragraph> 242 + <Button className="w-full" href={downloadUrl} theme="purple"> 243 + {t("player.menus.downloads.downloadVideo")} 244 + </Button> 245 + </> 225 246 )} 226 247 <Button 227 248 className="w-full mt-2"