Compare commits

...

1 commit

Author SHA1 Message Date
martabal
2c8bc9bccf
feat(web): loop videos 2023-11-04 00:28:06 +01:00
8 changed files with 66 additions and 5 deletions

View file

@ -23,6 +23,7 @@
import { createEventDispatcher } from 'svelte';
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
import { shouldLoopVideo } from '$lib/stores/assets.store';
export let asset: AssetResponseDto;
export let showCopyButton: boolean;
@ -36,7 +37,14 @@
$: isOwner = asset.ownerId === $page.data.user?.id;
type MenuItemEvent = 'addToAlbum' | 'addToSharedAlbum' | 'asProfileImage' | 'runJob' | 'playSlideShow' | 'unstack';
type MenuItemEvent =
| 'addToAlbum'
| 'addToSharedAlbum'
| 'asProfileImage'
| 'runJob'
| 'playSlideShow'
| 'unstack'
| 'loopVideo';
const dispatch = createEventDispatcher<{
goBack: void;
@ -53,6 +61,7 @@
runJob: AssetJobName;
playSlideShow: void;
unstack: void;
loopVideo: void;
}>();
let contextMenuPosition = { x: 0, y: 0 };
@ -168,7 +177,9 @@
{/if}
<MenuOption on:click={() => onMenuClick('addToAlbum')} text="Add to Album" />
<MenuOption on:click={() => onMenuClick('addToSharedAlbum')} text="Add to Shared Album" />
{#if asset.type === AssetTypeEnum.Video}
<MenuOption on:click={() => onMenuClick('loopVideo')} text="Loop video" checked={$shouldLoopVideo} />
{/if}
{#if isOwner}
<MenuOption
on:click={() => dispatch('toggleArchive')}

View file

@ -23,12 +23,12 @@
import { ProjectionType } from '$lib/constants';
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
import ProfileImageCropper from '../shared-components/profile-image-cropper.svelte';
import { isShowDetail } from '$lib/stores/preferences.store';
import { isShowDetail, loopVideoSetting } from '$lib/stores/preferences.store';
import { addAssetsToAlbum, downloadFile, getAssetType } from '$lib/utils/asset-utils';
import NavigationArea from './navigation-area.svelte';
import { browser } from '$app/environment';
import { handleError } from '$lib/utils/handle-error';
import type { AssetStore } from '$lib/stores/assets.store';
import { changeShouldLoopVideo, type AssetStore, shouldLoopVideo } from '$lib/stores/assets.store';
import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { SlideshowHistory } from '$lib/utils/slideshow-history';
@ -96,6 +96,8 @@
let isLiked: ActivityResponseDto | null = null;
let numberOfComments: number;
$: asset.id && asset.type === AssetTypeEnum.Video && changeShouldLoopVideo($loopVideoSetting);
$: {
if (asset.stackCount && asset.stack) {
$stackAssetsStore = asset.stack;
@ -590,6 +592,7 @@
on:runJob={({ detail: job }) => handleRunJob(job)}
on:playSlideShow={() => ($slideshowState = SlideshowState.PlaySlideshow)}
on:unstack={handleUnstack}
on:loopVideo={() => changeShouldLoopVideo(!$shouldLoopVideo)}
/>
</div>
{/if}

View file

@ -5,6 +5,7 @@
import { videoViewerVolume } from '$lib/stores/preferences.store';
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
import { handleError } from '$lib/utils/handle-error';
import { shouldLoopVideo } from '$lib/stores/assets.store';
export let assetId: string;
@ -31,6 +32,7 @@
autoplay
playsinline
controls
loop={$shouldLoopVideo}
class="h-full object-contain"
on:canplay={handleCanPlay}
on:ended={() => dispatch('onVideoEnded')}

View file

@ -1,6 +1,10 @@
<script>
import Icon from '$lib/components/elements/icon.svelte';
import { mdiCheck } from '@mdi/js';
export let text = '';
export let subtitle = '';
export let checked = false;
</script>
<button
@ -9,7 +13,16 @@
role="menuitem"
>
{#if text}
<div class="flex">
<div class="w-full">
{text}
</div>
{#if checked}
<div>
<Icon path={mdiCheck} />
</div>
{/if}
</div>
{:else}
<slot />
{/if}

View file

@ -0,0 +1,19 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import SettingSwitch from '../admin-page/settings/setting-switch.svelte';
import { loopVideoSetting } from '$lib/stores/preferences.store';
</script>
<section class="my-4">
<div in:fade={{ duration: 500 }}>
<div class="ml-4 mt-4 flex flex-col gap-4">
<div class="ml-4">
<SettingSwitch
title="Loop videos"
subtitle="Enable automatically loop videos."
bind:checked={$loopVideoSetting}
/>
</div>
</div>
</div>
</section>

View file

@ -13,6 +13,7 @@
import SidebarSettings from './sidebar-settings.svelte';
import UserAPIKeyList from './user-api-key-list.svelte';
import UserProfileSettings from './user-profile-settings.svelte';
import AssetSettings from './asset-settings.svelte';
export let user: UserResponseDto;
@ -67,3 +68,7 @@
<SettingAccordion title="Sidebar" subtitle="Manage sidebar settings">
<SidebarSettings />
</SettingAccordion>
<SettingAccordion title="Viewing experience" subtitle="Manage the browsing experience">
<AssetSettings />
</SettingAccordion>

View file

@ -415,3 +415,9 @@ export class AssetStore {
this.store$.update(() => this);
}
}
export const shouldLoopVideo = writable<boolean>();
export const changeShouldLoopVideo = (value: boolean) => {
shouldLoopVideo.set(value);
};

View file

@ -67,3 +67,5 @@ export const albumViewSettings = persisted<AlbumViewSettings>('album-view-settin
sortDesc: true,
view: AlbumViewMode.Cover,
});
export const loopVideoSetting = persisted<boolean>('loop-video', false, {});