Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions mobile/openapi/lib/api/shared_links_api.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions open-api/immich-openapi-specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -10381,6 +10381,21 @@
"format": "uuid",
"type": "string"
}
},
{
"name": "id",
"required": false,
"in": "query",
"x-immich-history": [
{
"version": "v2.5.0",
"state": "Added"
}
],
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
Expand Down
6 changes: 4 additions & 2 deletions open-api/typescript-sdk/src/fetch-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4218,14 +4218,16 @@ export function lockSession({ id }: {
/**
* Retrieve all shared links
*/
export function getAllSharedLinks({ albumId }: {
export function getAllSharedLinks({ albumId, id }: {
albumId?: string;
id?: string;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: SharedLinkResponseDto[];
}>(`/shared-links${QS.query(QS.explode({
albumId
albumId,
id
}))}`, {
...opts
}));
Expand Down
5 changes: 5 additions & 0 deletions server/src/dtos/shared-link.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
import _ from 'lodash';
import { SharedLink } from 'src/database';
import { HistoryBuilder, Property } from 'src/decorators';
import { AlbumResponseDto, mapAlbumWithoutAssets } from 'src/dtos/album.dto';
import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
import { SharedLinkType } from 'src/enum';
Expand All @@ -10,6 +11,10 @@ import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } f
export class SharedLinkSearchDto {
@ValidateUUID({ optional: true })
albumId?: string;

@ValidateUUID({ optional: true })
@Property({ history: new HistoryBuilder().added('v2.5.0') })
id?: string;
}

export class SharedLinkCreateDto {
Expand Down
4 changes: 3 additions & 1 deletion server/src/repositories/shared-link.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SharedLinkTable } from 'src/schema/tables/shared-link.table';

export type SharedLinkSearchOptions = {
userId: string;
id?: string;
albumId?: string;
};

Expand Down Expand Up @@ -118,7 +119,7 @@ export class SharedLinkRepository {
}

@GenerateSql({ params: [{ userId: DummyValue.UUID, albumId: DummyValue.UUID }] })
getAll({ userId, albumId }: SharedLinkSearchOptions) {
getAll({ userId, id, albumId }: SharedLinkSearchOptions) {
return this.db
.selectFrom('shared_link')
.selectAll('shared_link')
Expand Down Expand Up @@ -176,6 +177,7 @@ export class SharedLinkRepository {
.select((eb) => eb.fn.toJson('album').$castTo<Album | null>().as('album'))
.where((eb) => eb.or([eb('shared_link.type', '=', SharedLinkType.Individual), eb('album.id', 'is not', null)]))
.$if(!!albumId, (eb) => eb.where('shared_link.albumId', '=', albumId!))
.$if(!!id, (eb) => eb.where('shared_link.id', '=', id!))
.orderBy('shared_link.createdAt', 'desc')
.distinctOn(['shared_link.createdAt'])
.execute();
Expand Down
4 changes: 2 additions & 2 deletions server/src/services/shared-link.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { getExternalDomain, OpenGraphTags } from 'src/utils/misc';

@Injectable()
export class SharedLinkService extends BaseService {
async getAll(auth: AuthDto, { albumId }: SharedLinkSearchDto): Promise<SharedLinkResponseDto[]> {
async getAll(auth: AuthDto, { id, albumId }: SharedLinkSearchDto): Promise<SharedLinkResponseDto[]> {
return this.sharedLinkRepository
.getAll({ userId: auth.user.id, albumId })
.getAll({ userId: auth.user.id, id, albumId })
.then((links) => links.map((link) => mapSharedLink(link)));
}

Expand Down
98 changes: 0 additions & 98 deletions web/src/lib/modals/SharedLinkUpdateModal.svelte

This file was deleted.

2 changes: 1 addition & 1 deletion web/src/lib/services/shared-link.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const getSharedLinkActions = ($t: MessageFormatter, sharedLink: SharedLin
const Edit: ActionItem = {
title: $t('edit_link'),
icon: mdiPencilOutline,
onAction: () => goto(`${AppRoute.SHARED_LINKS}/${sharedLink.id}`),
onAction: () => goto(`${AppRoute.SHARED_LINKS}/${sharedLink.id}/edit`),
};

const Delete: ActionItem = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
import SharedLinkCard from '$lib/components/sharedlinks-page/SharedLinkCard.svelte';
import { AppRoute } from '$lib/constants';
import GroupTab from '$lib/elements/GroupTab.svelte';
import SharedLinkUpdateModal from '$lib/modals/SharedLinkUpdateModal.svelte';
import { getAllSharedLinks, SharedLinkType, type SharedLinkResponseDto } from '@immich/sdk';
import { onMount } from 'svelte';
import { Container } from '@immich/ui';
import { onMount, type Snippet } from 'svelte';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
import type { LayoutData } from './$types';

type Props = {
data: PageData;
children?: Snippet;
data: LayoutData;
};

const { data }: Props = $props();
const { children, data }: Props = $props();

let sharedLinks: SharedLinkResponseDto[] = $state([]);
let sharedLink = $derived(sharedLinks.find(({ id }) => id === page.params.id));

const refresh = async () => {
sharedLinks = await getAllSharedLinks({});
Expand Down Expand Up @@ -80,7 +80,7 @@
</div>
{/snippet}

<div class="w-full max-w-3xl m-auto">
<Container center size="medium">
{#if sharedLinks.length === 0}
<div
class="flex place-content-center place-items-center rounded-lg bg-gray-100 dark:bg-immich-dark-gray dark:text-immich-gray p-12"
Expand All @@ -95,8 +95,6 @@
</div>
{/if}

{#if sharedLink}
<SharedLinkUpdateModal {sharedLink} onClose={() => goto(AppRoute.SHARED_LINKS)} />
{/if}
</div>
{@render children?.()}
</Container>
</UserPageLayout>
14 changes: 14 additions & 0 deletions web/src/routes/(user)/shared-links/(list)/+layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import type { LayoutLoad } from './$types';

export const load = (async ({ url }) => {
await authenticate(url);
const $t = await getFormatter();

return {
meta: {
title: $t('shared_links'),
},
};
}) satisfies LayoutLoad;
Empty file.
28 changes: 28 additions & 0 deletions web/src/routes/(user)/shared-links/(list)/[id]/+layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AppRoute, UUID_REGEX } from '$lib/constants';
import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import { getAllSharedLinks } from '@immich/sdk';
import { redirect } from '@sveltejs/kit';
import type { LayoutLoad } from './$types';

export const load = (async ({ params, url }) => {
await authenticate(url);

if (!UUID_REGEX.test(params.id)) {
redirect(302, AppRoute.SHARED_LINKS);
}

const [sharedLink] = await getAllSharedLinks({ id: params.id });
if (!sharedLink) {
redirect(302, AppRoute.SHARED_LINKS);
}

const $t = await getFormatter();

return {
sharedLink,
meta: {
title: $t('shared_links'),
},
};
}) satisfies LayoutLoad;
Loading
Loading