mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(server, web): Album's options (#4870)
* feat: disable activity * fix: disable reactions * fix: tests * fix: tests * fix: tests * pr feedback * pr feedback * chore: styling & wording * refactor component --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
ace0a5911c
commit
9d01885b58
29 changed files with 293 additions and 24 deletions
76
web/src/lib/components/album-page/album-options.svelte
Normal file
76
web/src/lib/components/album-page/album-options.svelte
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<script lang="ts">
|
||||
import { mdiClose, mdiPlus } from '@mdi/js';
|
||||
import SettingSwitch from '../admin-page/settings/setting-switch.svelte';
|
||||
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
|
||||
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
|
||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { AlbumResponseDto, UserResponseDto } from '../../../api/open-api';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let album: AlbumResponseDto;
|
||||
export let user: UserResponseDto;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
close: void;
|
||||
toggleEnableActivity: void;
|
||||
showSelectSharedUser: void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<FullScreenModal on:clickOutside={() => dispatch('close')}>
|
||||
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden p-2 md:p-0">
|
||||
<div
|
||||
class="w-[550px] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||
>
|
||||
<div class="px-2 pt-2">
|
||||
<div class="flex items-center">
|
||||
<h1 class="px-4 w-full self-center font-medium text-immich-primary dark:text-immich-dark-primary">Options</h1>
|
||||
<div>
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" items-center justify-center p-4">
|
||||
<div class="py-2">
|
||||
<h2 class="text-gray text-sm mb-3">SHARING</h2>
|
||||
<div class="p-2">
|
||||
<SettingSwitch
|
||||
title="Comments & likes"
|
||||
subtitle="Let others respond"
|
||||
checked={album.isActivityEnabled}
|
||||
on:toggle={() => dispatch('toggleEnableActivity')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<div class="text-gray text-sm mb-3">PEOPLE</div>
|
||||
<div class="p-2">
|
||||
<button class="flex items-center gap-2" on:click={() => dispatch('showSelectSharedUser')}>
|
||||
<div class="rounded-full w-10 h-10 border border-gray-500 flex items-center justify-center">
|
||||
<div><Icon path={mdiPlus} size="25" /></div>
|
||||
</div>
|
||||
<div>Invite People</div>
|
||||
</button>
|
||||
<div class="flex items-center gap-2 py-2 mt-2">
|
||||
<div>
|
||||
<UserAvatar {user} size="md" />
|
||||
</div>
|
||||
<div class="w-full">{`${user.firstName} ${user.lastName}`}</div>
|
||||
<div>Owner</div>
|
||||
</div>
|
||||
{#each album.sharedUsers as user (user.id)}
|
||||
<div class="flex items-center gap-2 py-2">
|
||||
<div>
|
||||
<UserAvatar {user} size="md" />
|
||||
</div>
|
||||
<div class="w-full">{`${user.firstName} ${user.lastName}`}</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FullScreenModal>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
export let isLiked: ActivityResponseDto | null;
|
||||
export let numberOfComments: number | undefined;
|
||||
export let isShowActivity: boolean | undefined;
|
||||
export let disabled: boolean;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
<div
|
||||
class="w-full h-14 flex p-4 text-white items-center justify-center rounded-full gap-4 bg-immich-dark-bg bg-opacity-60"
|
||||
>
|
||||
<button on:click={() => dispatch('favorite')}>
|
||||
<button class={disabled ? 'cursor-not-allowed' : ''} on:click={() => dispatch('favorite')} {disabled}>
|
||||
<!-- svelte-ignore missing-declaration -->
|
||||
<div class="items-center justify-center">
|
||||
<Icon path={isLiked ? mdiHeart : mdiHeartOutline} size={24} />
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
export let albumId: string;
|
||||
export let assetType: AssetTypeEnum | undefined = undefined;
|
||||
export let albumOwnerId: string;
|
||||
export let disabled: boolean;
|
||||
|
||||
let textArea: HTMLTextAreaElement;
|
||||
let innerHeight: number;
|
||||
|
|
@ -280,12 +281,15 @@
|
|||
<form class="flex w-full max-h-56 gap-1" on:submit|preventDefault={() => handleSendComment()}>
|
||||
<div class="flex w-full items-center gap-4">
|
||||
<textarea
|
||||
{disabled}
|
||||
bind:this={textArea}
|
||||
bind:value={message}
|
||||
placeholder="Say something"
|
||||
placeholder={disabled ? 'Comments are disabled' : 'Say something'}
|
||||
on:input={autoGrow}
|
||||
on:keypress={handleEnter}
|
||||
class="h-[18px] w-full max-h-56 pr-2 items-center overflow-y-auto leading-4 outline-none resize-none bg-gray-200"
|
||||
class="h-[18px] {disabled
|
||||
? 'cursor-not-allowed'
|
||||
: ''} w-full max-h-56 pr-2 items-center overflow-y-auto leading-4 outline-none resize-none bg-gray-200"
|
||||
/>
|
||||
</div>
|
||||
{#if isSendingMessage}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if (album && !album.isActivityEnabled && numberOfComments === 0) {
|
||||
isShowActivity = false;
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddComment = () => {
|
||||
numberOfComments++;
|
||||
updateNumberOfComments(1);
|
||||
|
|
@ -115,7 +121,7 @@
|
|||
};
|
||||
|
||||
const handleFavorite = async () => {
|
||||
if (album) {
|
||||
if (album && album.isActivityEnabled) {
|
||||
try {
|
||||
if (isLiked) {
|
||||
const activityId = isLiked.id;
|
||||
|
|
@ -661,9 +667,10 @@
|
|||
on:onVideoStarted={handleVideoStarted}
|
||||
/>
|
||||
{/if}
|
||||
{#if $slideshowState === SlideshowState.None && isShared}
|
||||
{#if $slideshowState === SlideshowState.None && isShared && ((album && album.isActivityEnabled) || numberOfComments > 0)}
|
||||
<div class="z-[9999] absolute bottom-0 right-0 mb-6 mr-6 justify-self-end">
|
||||
<ActivityStatus
|
||||
disabled={!album?.isActivityEnabled}
|
||||
{isLiked}
|
||||
{numberOfComments}
|
||||
{isShowActivity}
|
||||
|
|
@ -744,6 +751,7 @@
|
|||
>
|
||||
<ActivityViewer
|
||||
{user}
|
||||
disabled={!album.isActivityEnabled}
|
||||
assetType={asset.type}
|
||||
albumOwnerId={album.ownerId}
|
||||
albumId={album.id}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue