diff --git a/materialious/src/lib/components/settings/About.svelte b/materialious/src/lib/components/settings/About.svelte
index 5c15b6f0..9725cb6b 100644
--- a/materialious/src/lib/components/settings/About.svelte
+++ b/materialious/src/lib/components/settings/About.svelte
@@ -4,7 +4,7 @@
let ghContributors: { login: string; avatar_url: string; type: 'Bot' | 'User' }[] = $state([]);
onMount(() => {
- fetch(`${document.location.origin}/localApi/ghContributors.json`, {
+ fetch('/localApi/ghContributors.json', {
priority: 'low'
}).then(async (resp) => {
if (!resp.ok) {
diff --git a/materialious/src/lib/i18n/locales/de.json b/materialious/src/lib/i18n/locales/de.json
index 4a147b6c..0318a803 100644
--- a/materialious/src/lib/i18n/locales/de.json
+++ b/materialious/src/lib/i18n/locales/de.json
@@ -27,9 +27,9 @@
"hideReplies": "Antworten verstecken",
"hideVideo": "Video verstecken",
"syncParty": {
- "userJoined": "Ein Benutzer ist deiner Wiedergabegruppe beigetreten.",
- "userLeft": "Ein Benutzer hat deine Wiedergabegruppe verlassen.",
- "userOnPrivatePage": "Der Benutzer sieht sich gerade eine private Seite an, die Synchronisierung wird in Kürze fortgesetzt."
+ "userJoined": "Eine Person ist deiner Wiedergabegruppe beigetreten.",
+ "userLeft": "Eine Person hat deine Wiedergabegruppe verlassen.",
+ "userOnPrivatePage": "Die Person sieht sich gerade eine private Seite an, die Synchronisierung wird in Kürze fortgesetzt."
},
"videoTabs": {
"all": "Alle",
@@ -115,10 +115,10 @@
}
},
"layout": {
- "interface": "Benutzeroberfläche",
+ "interface": "Bedienoberfläche",
"star": "Sternchen auf GitHub vergeben!",
"syncParty": "Synchronisationsgruppe",
- "syncPartyWarning": "Bitte beachte, dass deine IP für die von dir eingeladenen Benutzer sichtbar ist.",
+ "syncPartyWarning": "Bitte beachte, dass deine IP für die von dir eingeladenen Personen sichtbar ist.",
"startSyncParty": "Synchronisationsgruppe starten",
"endSyncParty": "Synchronisationsgruppe stoppen",
"notifications": "Benachrichtigungen",
@@ -163,7 +163,8 @@
"defaultPlaybackSpeed": "Standardmäßige Wiedergabegeschwindigkeit",
"ccByDefault": "Untertitel standardmäßig an",
"localVideoFallback": "Lokaler Video-Fallback",
- "playerStatistics": "Player-Statistiken standardmäßig anzeigen"
+ "playerStatistics": "Player-Statistiken standardmäßig anzeigen",
+ "networkChangePause": "Bei Netzwerkwechsel pausieren"
},
"bookmarklet": "Lesezeichen",
"instanceUrl": "URL der Instanz",
@@ -177,7 +178,10 @@
"intermissionIntroAnimation": "Unterbrechung/Einstiegsanimation",
"credits": "Abspann",
"preViewRecapHook": "Vorschau/Rückblick/Hook",
- "tangentJokes": "Füllende Abweichler/Witze"
+ "tangentJokes": "Füllende Abweichler/Witze",
+ "automatic": "Automatisch überspringen",
+ "manual": "Manuell überspringen",
+ "timeline": "Nur Zeitleiste"
},
"deArrow": {
"title": "DeArrow",
@@ -217,5 +221,7 @@
"oldest": "Älteste",
"popular": "Populär",
"favouriteChannel": "Kanal favorisieren",
- "unfavouriteChannel": "Kanal entfavorisieren"
+ "unfavouriteChannel": "Kanal entfavorisieren",
+ "skip": "Überspringen",
+ "upcomingSegment": "Kommend "
}
diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json
index eba4e76a..90354b43 100644
--- a/materialious/src/lib/i18n/locales/en.json
+++ b/materialious/src/lib/i18n/locales/en.json
@@ -146,6 +146,8 @@
"syncPartyWarning": "Please note your IP will be visible to users you invite.",
"startSyncParty": "Start sync party",
"endSyncParty": "End sync party",
+ "joinSyncParty": "Enter sync party URL",
+ "shareURL": "Share URL",
"notifications": "Notifications",
"noNewNotifications": "No new notifications here",
"settings": "Settings",
diff --git a/materialious/src/lib/i18n/locales/gsw.json b/materialious/src/lib/i18n/locales/gsw.json
index 60867133..84d8af64 100644
--- a/materialious/src/lib/i18n/locales/gsw.json
+++ b/materialious/src/lib/i18n/locales/gsw.json
@@ -33,7 +33,8 @@
"youtubeJsAlways": "Immer nutze",
"lockOrientation": "Uusrichtig as Siiteverhältnis bunde",
"defaultPlaybackSpeed": "Standardmässigi Widergabegschwindigkeit",
- "playerStatistics": "Player-Statistike standardmässig aazeige"
+ "playerStatistics": "Player-Statistike standardmässig aazeige",
+ "networkChangePause": "Bi Netzwerchwechsel pausiere"
},
"sponsors": {
"intermissionIntroAnimation": "Unterbrechig/Iistigsanimation",
@@ -45,9 +46,12 @@
"interactionReminder": "Interaktionsufforderig (Abonniere)",
"credits": "Abspann",
"preViewRecapHook": "Vorschau/Rückblick/Hook",
- "tangentJokes": "Füllendi Abwiichler/Witz"
+ "tangentJokes": "Füllendi Abwiichler/Witz",
+ "automatic": "Automatisch überspringe",
+ "manual": "Manuell überspringe",
+ "timeline": "Nur Ziitleischte"
},
- "interface": "Benutzeroberflächi",
+ "interface": "Bedienoberflächi",
"star": "Sternli uf GitHub vergeh!",
"syncParty": "Synchronisationsgruppe",
"startSyncParty": "Synchronisationsgruppe starte",
@@ -83,7 +87,7 @@
"thumbnailInstanceUrl": "URL vo de Vorschaubilder-Instanz",
"titleOnly": "Nur Titel"
},
- "syncPartyWarning": "Bitte denk dra, dass dini IP für die vo dir iigladne Benutzer sichtbar isch.",
+ "syncPartyWarning": "Bitte denk dra, dass dini IP für die vo dir iigladne Persone sichtbar isch.",
"displayThumbnailAvatars": "Vorschaubild-Avatar (Langsam)",
"expandDescription": "Beschriibig standardmässig erwiitere",
"disableAutoUpdate": "Automatischi Updates deaktiviere",
@@ -114,9 +118,9 @@
"hideVideo": "Video verstecke",
"defaultPage": "Standardsiite",
"syncParty": {
- "userJoined": "En Benutzer isch dinere Widergabegruppe biiträte.",
- "userLeft": "En Benutzer het dini Widergabegruppe verlah.",
- "userOnPrivatePage": "De Benutzer luegt sich grad e privati Siite a, d Synchronisierig wird grad wieder fortgsetzt."
+ "userJoined": "E Person isch dinere Widergabegruppe biiträte.",
+ "userLeft": "E Person het dini Widergabegruppe verlah.",
+ "userOnPrivatePage": "D Person luegt sich grad e privati Siite a, d Synchronisierig wird grad wieder fortgsetzt."
},
"videoTabs": {
"all": "Alli",
@@ -217,5 +221,7 @@
"oldest": "Ältisti",
"popular": "Populär",
"favouriteChannel": "Kanal favorisiere",
- "unfavouriteChannel": "Kanal entfavorisiere"
+ "unfavouriteChannel": "Kanal entfavorisiere",
+ "skip": "Überspringe",
+ "upcomingSegment": "Kommend "
}
diff --git a/materialious/src/lib/i18n/locales/hu.json b/materialious/src/lib/i18n/locales/hu.json
index c81f3752..c633ae70 100644
--- a/materialious/src/lib/i18n/locales/hu.json
+++ b/materialious/src/lib/i18n/locales/hu.json
@@ -44,7 +44,10 @@
"intermissionIntroAnimation": "Szünet/bevezető animáció",
"credits": "Végképernyő/köszönet",
"preViewRecapHook": "Bevezető/összegzés/figyelemfelketés",
- "tangentJokes": "Kitöltő mellékvágányok/poénok"
+ "tangentJokes": "Kitöltő mellékvágányok/poénok",
+ "automatic": "Automatikus átugrás",
+ "manual": "Kézi ugrás",
+ "timeline": "Csak idővonal"
},
"syncPartyWarning": "Vegye figyelembe, hogy IP-címe látható lesz az Ön által meghívott felhasználók számára.",
"expandDescription": "Leírás kibontása alapértelmezetten",
@@ -96,7 +99,8 @@
"savePlaybackPosition": "Lejátszási pozíció mentése",
"localVideoFallback": "Helyi videó visszatérés",
"theatreModeByDefault": "Szélesvásznú mód alapértelmezetten",
- "youtubeJsFallback": "Helyi videó visszatérés feldolgozása"
+ "youtubeJsFallback": "Helyi videó visszatérés feldolgozása",
+ "networkChangePause": "Szünet a hálózati változáskor"
},
"bookmarklet": "Bookmarklet",
"instanceUrl": "Példány webcíme",
@@ -217,5 +221,7 @@
"oldest": "Legrégebbi",
"popular": "Népszerű",
"favouriteChannel": "Csatorna kedvelése",
- "unfavouriteChannel": "Csatorna eltávolítása a kedvencekből"
+ "unfavouriteChannel": "Csatorna eltávolítása a kedvencekből",
+ "skip": "Kihagyás",
+ "upcomingSegment": "Közelgő "
}
diff --git a/materialious/src/lib/i18n/locales/lv.json b/materialious/src/lib/i18n/locales/lv.json
index 2dbf7b00..2fd55f21 100644
--- a/materialious/src/lib/i18n/locales/lv.json
+++ b/materialious/src/lib/i18n/locales/lv.json
@@ -7,7 +7,8 @@
"invidiousRedirect": "Kopēt Invidious servera (instances) saiti",
"title": "Dalīties",
"youtubeLink": "Kopēt YouTube saiti",
- "includeTimestamp": "Iekļaut atskaņošanas laiku"
+ "includeTimestamp": "Iekļaut atskaņošanas laiku",
+ "copiedSuccess": "Kopēta starpliktuvē"
},
"download": "Lejupielādēt",
"downloadSteps": {
@@ -31,7 +32,15 @@
"retryText": "Neizdevās ielādēt video. Kā vēlaties turpināt?",
"youtubeJsLoading": "Neizdevās ielādēt video, mēģina atkārtoti ielādēt ar vietējo video ieguves rezerves variantu.",
"enableYoutubejsPerm": "Vienmēr izmantot vietējo video ieguves rezerves variantu",
- "preferredQuality": "Vēlamā kvalitāte"
+ "preferredQuality": "Vēlamā kvalitāte",
+ "premiere": "Video būs pieejams",
+ "controls": {
+ "quality": "Kvalitāte",
+ "playbackSpeed": "Atskaņošanas ātrums",
+ "on": "Ieslēgt",
+ "off": "Izslēgt",
+ "language": "Valoda"
+ }
},
"videos": "video",
"layout": {
@@ -58,7 +67,12 @@
"alwaysLoopVideo": "Vienmēr atskaņot (malt) uz riņķi video",
"miniPlayer": "Mini atskaņotājs",
"playerStatistics": "Rādīt atskaņotāja statistiku pēc noklusējuma",
- "autoPlayNextByDefault": "Automātiski atskaņot nākamo video pēc noklusējuma"
+ "autoPlayNextByDefault": "Automātiski atskaņot nākamo video pēc noklusējuma",
+ "ccByDefault": "Iespējot subtitrus pēc noklusējuma",
+ "backgroundPlay": "Atskaņot audio fonā",
+ "dash": "Izmantot DASH",
+ "silenceSkipper": "Izlaist klusuma brīžus (eksperimentāla)",
+ "defaultPlaybackSpeed": "Noklusējuma atskaņošanas ātrums"
},
"deArrow": {
"titleOnly": "Tikai virsrakstu",
@@ -68,7 +82,8 @@
"Catagories": "Kategorijas",
"unpaidSelfPromotion": "Neapmaksāts/pašreklāma",
"sponsor": "Sponsors",
- "disableToast": "Atspējot uznirstošos logus"
+ "disableToast": "Atspējot uznirstošos logus",
+ "automatic": "Automātiski izlaist"
},
"bookmarklet": "Grāmatzīmes sīklietotne",
"dataPreferences": {
@@ -161,9 +176,15 @@
"filters": "Filtrēt pēc",
"type": "Tips",
"uploadDate": "Augšupielādes datums",
- "duration": "Ilgums"
+ "duration": "Ilgums",
+ "sortBy": "Kārtot pēc"
},
"comments": "komentāri",
"login": "Autorizēties",
- "transcript": "Transkripcija"
+ "transcript": "Transkripcija",
+ "popularPageDisabled": "Administratori atspējojuši \"Populārs\" lapu",
+ "skip": "Izlaist",
+ "reply": "atbilde",
+ "contributors": "Dalībnieki, līdzautori, kas devuši savu artavu",
+ "loadMore": "Ielādēt vēl"
}
diff --git a/materialious/src/lib/i18n/locales/zh_Hant.json b/materialious/src/lib/i18n/locales/zh_Hant.json
index 37027b6a..efb1774d 100644
--- a/materialious/src/lib/i18n/locales/zh_Hant.json
+++ b/materialious/src/lib/i18n/locales/zh_Hant.json
@@ -1,4 +1,13 @@
{
"enabled": "啟用",
- "disabled": "停用"
+ "disabled": "停用",
+ "player": {
+ "controls": {
+ "language": "語言"
+ }
+ },
+ "layout": {
+ "interface": "介面",
+ "syncPartyWarning": "被邀請的使用者將會看到您的IP位址。"
+ }
}
diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts
index c2239271..49c559a2 100644
--- a/materialious/src/lib/misc.ts
+++ b/materialious/src/lib/misc.ts
@@ -3,7 +3,11 @@ import { resolve } from '$app/paths';
import he from 'he';
import type Peer from 'peerjs';
import { get } from 'svelte/store';
-import { interfaceAllowInsecureRequests, isAndroidTvStore } from './store';
+import {
+ interfaceAllowInsecureRequests,
+ interfaceAndroidUseNativeShare,
+ isAndroidTvStore
+} from './store';
import type {
Channel,
HashTag,
@@ -14,6 +18,9 @@ import type {
VideoBase
} from './api/model';
import { page } from '$app/state';
+import { Capacitor } from '@capacitor/core';
+import { Share } from '@capacitor/share';
+import { Clipboard } from '@capacitor/clipboard';
export function isVideoID(videoId: string): boolean {
const regExp = /^[a-zA-Z0-9_-]{11}$/;
@@ -46,16 +53,41 @@ export function removeWindowQueryFlag(key: string) {
}
let PeerInstance: typeof Peer;
-export async function peerJs(peerId: string): Promise
{
+export interface PeerInstance {
+ host: string;
+ path: string;
+ port: number;
+}
+
+export function determinePeerJsInstance(): PeerInstance {
+ return {
+ host: import.meta.env.VITE_DEFAULT_PEERJS_HOST || '0.peerjs.com',
+ path: import.meta.env.VITE_DEFAULT_PEERJS_PATH || '/',
+ port: import.meta.env.VITE_DEFAULT_PEERJS_PORT || 443
+ };
+}
+
+export async function peerJs(
+ id: string,
+ instance: PeerInstance = determinePeerJsInstance()
+): Promise {
// https://github.com/peers/peerjs/issues/819
if (typeof PeerInstance === 'undefined') {
PeerInstance = (await import('peerjs')).Peer;
}
- return new PeerInstance(peerId, {
- host: import.meta.env.VITE_DEFAULT_PEERJS_HOST || '0.peerjs.com',
- path: import.meta.env.VITE_DEFAULT_PEERJS_PATH || '/',
- port: import.meta.env.VITE_DEFAULT_PEERJS_PORT || 443
- });
+ return new PeerInstance(id, instance);
+}
+
+export async function shareURL(url: string) {
+ if (
+ Capacitor.getPlatform() === 'android' &&
+ (await Share.canShare()).value &&
+ get(interfaceAndroidUseNativeShare)
+ ) {
+ await Share.share({ url: url });
+ } else {
+ await Clipboard.write({ string: url });
+ }
}
export function ensureNoTrailingSlash(url: any): string {
diff --git a/materialious/src/routes/(app)/+layout.svelte b/materialious/src/routes/(app)/+layout.svelte
index 0ec6b776..2e8ee47c 100644
--- a/materialious/src/routes/(app)/+layout.svelte
+++ b/materialious/src/routes/(app)/+layout.svelte
@@ -253,10 +253,12 @@
>
-
- search
- {$_('searchPlaceholder')}
-
+ {#if $isAndroidTvStore}
+
+ search
+ {$_('searchPlaceholder')}
+
+ {/if}
{#each getPages() as navPage (navPage)}
{#if !navPage.requiresAuth || isLoggedIn}
(mobileSearchShow = false)} />
{:else}
- {#if !Capacitor.isNativePlatform()}
-