diff --git a/materialious/src/lib/components/Share.svelte b/materialious/src/lib/components/Share.svelte new file mode 100644 index 00000000..21358f6d --- /dev/null +++ b/materialious/src/lib/components/Share.svelte @@ -0,0 +1,85 @@ + + + diff --git a/materialious/src/lib/components/ShareVideo.svelte b/materialious/src/lib/components/ShareVideo.svelte deleted file mode 100644 index d82cefda..00000000 --- a/materialious/src/lib/components/ShareVideo.svelte +++ /dev/null @@ -1,79 +0,0 @@ - - - - {#if currentTime !== undefined} -
  • - -
    {$_('player.share.includeTimestamp')}
    -
  • -
    - {/if} - - - -
    diff --git a/materialious/src/lib/components/player/settings/CaptionSettings.svelte b/materialious/src/lib/components/player/settings/CaptionSettings.svelte index 512cc532..fe2408e2 100644 --- a/materialious/src/lib/components/player/settings/CaptionSettings.svelte +++ b/materialious/src/lib/components/player/settings/CaptionSettings.svelte @@ -16,7 +16,7 @@ {#if playerTextTracks && playerTextTracks.length > 0 && !video.liveNow} + + + + + +
    +
    + + +
    + + {#each playlist.videos as playlistVideo, index (index)} +
    + {#key playlistVideo.videoId} + + {/key} +
    + {/each} + diff --git a/materialious/src/lib/components/watch/Transcript.svelte b/materialious/src/lib/components/watch/Transcript.svelte index 12d79c2f..988f600f 100644 --- a/materialious/src/lib/components/watch/Transcript.svelte +++ b/materialious/src/lib/components/watch/Transcript.svelte @@ -86,7 +86,7 @@
    {$_('transcript')}
    -
    +
    (playerElement.currentTime = cue.startTime)} - class:secondary-container={currentTime >= cue.startTime && currentTime <= cue.endTime} + class:surface-container-highest={currentTime >= cue.startTime && + currentTime <= cue.endTime} >

    {videoLength(cue.startTime)}

    {decodeHtmlCharCodes(cue.text.replace(/<[^>]+>/g, ''))}

    diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json index ece771ef..aa7730c1 100644 --- a/materialious/src/lib/i18n/locales/en.json +++ b/materialious/src/lib/i18n/locales/en.json @@ -126,9 +126,7 @@ "chapters": "Chapters", "share": { "title": "Share", - "materialiousLink": "Copy Materialious link", - "invidiousRedirect": "Copy Invidious redirect link", - "youtubeLink": "Copy Youtube link", + "copyXLink": "Copy {{linkType}} link", "includeTimestamp": "Timestamped", "copiedSuccess": "Copied to clipboard" }, diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts index 02edcb0c..514afc79 100644 --- a/materialious/src/lib/misc.ts +++ b/materialious/src/lib/misc.ts @@ -33,6 +33,8 @@ import { Clipboard } from '@capacitor/clipboard'; import { isOwnBackend } from './shared'; import { Browser } from '@capacitor/browser'; import { clearFeedYTjs } from './api/youtubejs/subscriptions'; +import { addToast } from './components/Toast.svelte'; +import { _ } from './i18n'; export function getPublicEnv(envName: string): string | undefined { return env[`PUBLIC_${envName}`] ?? import.meta.env[`VITE_${envName}`]; @@ -114,6 +116,12 @@ export async function shareURL(url: string) { } else { await Clipboard.write({ string: url }); } + + addToast({ + data: { + text: get(_)('player.share.copiedSuccess') + } + }); } export function ensureNoTrailingSlash(url: any): string { diff --git a/materialious/src/lib/player/index.ts b/materialious/src/lib/player/index.ts index 4dc41653..cbc0d380 100644 --- a/materialious/src/lib/player/index.ts +++ b/materialious/src/lib/player/index.ts @@ -6,6 +6,7 @@ import { playerDefaultLanguage, playerDefaultQualityStore, playerPlaylistHistory, + playerState, playlistSettingsStore, syncPartyConnectionsStore } from '$lib/store'; @@ -34,6 +35,8 @@ export const playbackRates = [ export const playerDoubleTapSeek = 10.0; export function goToPreviousVideo(playlistId: string | null) { + playerState.set(undefined); + const previousVideos = get(playerPlaylistHistory); if (previousVideos.length > 1) { goto( @@ -47,6 +50,8 @@ export function goToPreviousVideo(playlistId: string | null) { } export async function goToNextVideo(video: VideoPlay, playlistId: string | null) { + playerState.set(undefined); + const isAndroidTv = get(isAndroidTvStore); if (!playlistId) { diff --git a/materialious/src/routes/(app)/channel/[slug]/+page.svelte b/materialious/src/routes/(app)/channel/[slug]/+page.svelte index 0a00c71b..fc5b5af1 100644 --- a/materialious/src/routes/(app)/channel/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/channel/[slug]/+page.svelte @@ -14,6 +14,8 @@ import { onMount } from 'svelte'; import { page } from '$app/state'; import { isYTBackend } from '$lib/misc'; + import Share from '$lib/components/Share.svelte'; + import { resolve } from '$app/paths'; let tab: ChannelContentTypes = $state('videos'); @@ -108,37 +110,29 @@

    {#if !$isAndroidTvStore} - + {/if}
    diff --git a/materialious/src/routes/(app)/playlist/[slug]/+page.svelte b/materialious/src/routes/(app)/playlist/[slug]/+page.svelte index 853e6602..75cb074c 100644 --- a/materialious/src/routes/(app)/playlist/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/playlist/[slug]/+page.svelte @@ -3,10 +3,10 @@ import { unsafeRandomItem } from '$lib/misc'; import { cleanNumber } from '$lib/numbers'; import { isAndroidTvStore, playlistSettingsStore } from '$lib/store'; - import { Clipboard } from '@capacitor/clipboard'; - import { Capacitor } from '@capacitor/core'; import { _ } from '$lib/i18n'; import ItemsList from '$lib/components/layout/ItemsList.svelte'; + import Share from '$lib/components/Share.svelte'; + import { page } from '$app/state'; let { data } = $props(); @@ -44,7 +44,7 @@ playlistSettingsStore.set({ [data.playlist.info.playlistId]: { shuffle: true, loop: false } })} - class="button circle extra no-margin border" + class="button circle extra no-margin surface-container-highest" > shuffle
    @@ -68,36 +68,29 @@
    {#if !$isAndroidTvStore} - + {/if}
    diff --git a/materialious/src/routes/(app)/watch/[slug]/+page.svelte b/materialious/src/routes/(app)/watch/[slug]/+page.svelte index a3cd4841..3ad73442 100644 --- a/materialious/src/routes/(app)/watch/[slug]/+page.svelte +++ b/materialious/src/routes/(app)/watch/[slug]/+page.svelte @@ -7,7 +7,6 @@ removePlaylistVideo } from '$lib/api/index'; import type { Comments, PlaylistPage } from '$lib/api/model'; - import ShareVideo from '$lib/components/ShareVideo.svelte'; import Thumbnail from '$lib/components/thumbnail/VideoThumbnail.svelte'; import Transcript from '$lib/components/watch/Transcript.svelte'; import { getBestThumbnail } from '$lib/images'; @@ -42,6 +41,8 @@ import { humanizeSeconds, relativeTimestamp } from '$lib/time'; import { getWatchDetails } from '$lib/watch'; import { page } from '$app/state'; + import Share from '$lib/components/Share.svelte'; + import Playlist from '$lib/components/watch/Playlist.svelte'; let { data = $bindable() } = $props(); @@ -55,9 +56,6 @@ let personalPlaylists: PlaylistPage[] | null = $state(null); data.streamed.personalPlaylists?.then((streamPlaylists) => (personalPlaylists = streamPlaylists)); - let loopPlaylist: boolean = $state(false); - let shufflePlaylist: boolean = $state(false); - playertheatreModeIsActive.set(get(playerTheatreModeByDefaultStore)); let pauseTimerSeconds: number = $state(-1); @@ -84,14 +82,6 @@ } }); - playlistSettingsStore.subscribe((playlistSetting) => { - if (!data.playlistId) return; - if (data.playlistId in playlistSetting) { - loopPlaylist = playlistSetting[data.playlistId].loop; - shufflePlaylist = playlistSetting[data.playlistId].shuffle; - } - }); - function playerSyncEvents(conn: DataConnection) { if (playerElement) { conn.send({ @@ -449,15 +439,44 @@ {$_('transcript')} - + Math.round(playerCurrentTime) + } + }, + { + type: 'invidious', + path: `/watch?=${data.video.videoId}`, + param: { + key: 'v', + value: () => Math.round(playerCurrentTime) + } + }, + { + type: 'invidious redirect', + path: `/watch?=${data.video.videoId}`, + param: { + key: 'v', + value: () => Math.round(playerCurrentTime) + } + }, + { + type: 'youtube', + path: `/watch?=${data.video.videoId}`, + param: { + key: 'v', + value: () => Math.round(playerCurrentTime) + } + } + ]} + iconOnly={true} + /> {#if personalPlaylists && personalPlaylists.length > 0} - - - - - -
    -
    -
    - -
    - - {#each $playlistCacheStore[data.playlistId].videos as playlistVideo (playlistVideo.videoId)} -
    - {#key playlistVideo.videoId} - - {/key} -
    - {/each} - + {:else if data.video.recommendedVideos} {#each data.video.recommendedVideos as recommendedVideo (recommendedVideo.videoId)}