refactor(web): use new open api client (#7097)
* refactor(web): use new open api client * refactor: remove activity api * refactor: trash, oauth, and partner apis * refactor: job api * refactor: face, library, system config * refactor: user api * refactor: album api
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { api } from '@api';
|
||||
import { getAllAlbums } from '@immich/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async () => {
|
||||
await authenticate();
|
||||
const { data: albums } = await api.albumApi.getAllAlbums();
|
||||
const albums = await getAllAlbums({});
|
||||
|
||||
return {
|
||||
albums,
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { afterNavigate, goto } from '$app/navigation';
|
||||
import AlbumOptions from '$lib/components/album-page/album-options.svelte';
|
||||
import ShareInfoModal from '$lib/components/album-page/share-info-modal.svelte';
|
||||
import UserSelectionModal from '$lib/components/album-page/user-selection-modal.svelte';
|
||||
import ActivityStatus from '$lib/components/asset-viewer/activity-status.svelte';
|
||||
import ActivityViewer from '$lib/components/asset-viewer/activity-viewer.svelte';
|
||||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import AddToAlbum from '$lib/components/photos-page/actions/add-to-album.svelte';
|
||||
import ArchiveAction from '$lib/components/photos-page/actions/archive-action.svelte';
|
||||
import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte';
|
||||
import ChangeLocation from '$lib/components/photos-page/actions/change-location-action.svelte';
|
||||
import CreateSharedLink from '$lib/components/photos-page/actions/create-shared-link.svelte';
|
||||
import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte';
|
||||
import DownloadAction from '$lib/components/photos-page/actions/download-action.svelte';
|
||||
import FavoriteAction from '$lib/components/photos-page/actions/favorite-action.svelte';
|
||||
import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte';
|
||||
import ChangeLocation from '$lib/components/photos-page/actions/change-location-action.svelte';
|
||||
import RemoveFromAlbum from '$lib/components/photos-page/actions/remove-from-album.svelte';
|
||||
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
|
||||
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
|
||||
@@ -26,40 +30,47 @@
|
||||
NotificationType,
|
||||
notificationController,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
|
||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import { AppRoute, dateFormats } from '$lib/constants';
|
||||
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
|
||||
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { downloadArchive } from '$lib/utils/asset-utils';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { type ActivityResponseDto, ReactionLevel, ReactionType, type UserResponseDto, api } from '@api';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { autoGrowHeight } from '$lib/utils/autogrow';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { getContextMenuPosition } from '$lib/utils/context-menu';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { ReactionLevel, ReactionType, type ActivityResponseDto, type UserResponseDto } from '@api';
|
||||
import {
|
||||
addAssetsToAlbum,
|
||||
addUsersToAlbum,
|
||||
createActivity,
|
||||
deleteActivity,
|
||||
deleteAlbum,
|
||||
getActivities,
|
||||
getActivityStatistics,
|
||||
getAlbumInfo,
|
||||
updateAlbumInfo,
|
||||
} from '@immich/sdk';
|
||||
import {
|
||||
mdiPlus,
|
||||
mdiDotsVertical,
|
||||
mdiArrowLeft,
|
||||
mdiDeleteOutline,
|
||||
mdiDotsVertical,
|
||||
mdiFileImagePlusOutline,
|
||||
mdiFolderDownloadOutline,
|
||||
mdiLink,
|
||||
mdiPlus,
|
||||
mdiShareVariantOutline,
|
||||
mdiDeleteOutline,
|
||||
} from '@mdi/js';
|
||||
import { onMount } from 'svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
import ActivityViewer from '$lib/components/asset-viewer/activity-viewer.svelte';
|
||||
import ActivityStatus from '$lib/components/asset-viewer/activity-status.svelte';
|
||||
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
|
||||
import AlbumOptions from '$lib/components/album-page/album-options.svelte';
|
||||
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { autoGrowHeight } from '$lib/utils/autogrow';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -141,13 +152,12 @@
|
||||
|
||||
const handleToggleEnableActivity = async () => {
|
||||
try {
|
||||
const { data } = await api.albumApi.updateAlbumInfo({
|
||||
album = await updateAlbumInfo({
|
||||
id: album.id,
|
||||
updateAlbumDto: {
|
||||
isActivityEnabled: !album.isActivityEnabled,
|
||||
},
|
||||
});
|
||||
album = data;
|
||||
notificationController.show({
|
||||
type: NotificationType.Info,
|
||||
message: `Activity is ${album.isActivityEnabled ? 'enabled' : 'disabled'}`,
|
||||
@@ -161,14 +171,13 @@
|
||||
try {
|
||||
if (isLiked) {
|
||||
const activityId = isLiked.id;
|
||||
await api.activityApi.deleteActivity({ id: activityId });
|
||||
await deleteActivity({ id: activityId });
|
||||
reactions = reactions.filter((reaction) => reaction.id !== activityId);
|
||||
isLiked = null;
|
||||
} else {
|
||||
const { data } = await api.activityApi.createActivity({
|
||||
isLiked = await createActivity({
|
||||
activityCreateDto: { albumId: album.id, type: ReactionType.Like },
|
||||
});
|
||||
isLiked = data;
|
||||
reactions = [...reactions, isLiked];
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -179,10 +188,10 @@
|
||||
const getFavorite = async () => {
|
||||
if ($user) {
|
||||
try {
|
||||
const { data } = await api.activityApi.getActivities({
|
||||
const data = await getActivities({
|
||||
userId: $user.id,
|
||||
albumId: album.id,
|
||||
type: ReactionType.Like,
|
||||
$type: ReactionType.Like,
|
||||
level: ReactionLevel.Album,
|
||||
});
|
||||
if (data.length > 0) {
|
||||
@@ -196,8 +205,8 @@
|
||||
|
||||
const getNumberOfComments = async () => {
|
||||
try {
|
||||
const { data } = await api.activityApi.getActivityStatistics({ albumId: album.id });
|
||||
setNumberOfComments(data.comments);
|
||||
const { comments } = await getActivityStatistics({ albumId: album.id });
|
||||
setNumberOfComments(comments);
|
||||
} catch (error) {
|
||||
handleError(error, "Can't get number of comments");
|
||||
}
|
||||
@@ -269,8 +278,7 @@
|
||||
};
|
||||
|
||||
const refreshAlbum = async () => {
|
||||
const { data } = await api.albumApi.getAlbumInfo({ id: album.id, withoutAssets: true });
|
||||
album = data;
|
||||
album = await getAlbumInfo({ id: album.id, withoutAssets: true });
|
||||
};
|
||||
|
||||
const getDateRange = () => {
|
||||
@@ -302,7 +310,7 @@
|
||||
const assetIds = [...$timelineSelected].map((asset) => asset.id);
|
||||
|
||||
try {
|
||||
const { data: results } = await api.albumApi.addAssetsToAlbum({
|
||||
const results = await addAssetsToAlbum({
|
||||
id: album.id,
|
||||
bulkIdsDto: { ids: assetIds },
|
||||
});
|
||||
@@ -346,15 +354,13 @@
|
||||
|
||||
const handleAddUsers = async (users: UserResponseDto[]) => {
|
||||
try {
|
||||
const { data } = await api.albumApi.addUsersToAlbum({
|
||||
album = await addUsersToAlbum({
|
||||
id: album.id,
|
||||
addUsersDto: {
|
||||
sharedUserIds: [...users].map(({ id }) => id),
|
||||
},
|
||||
});
|
||||
|
||||
album = data;
|
||||
|
||||
viewMode = ViewMode.VIEW;
|
||||
} catch (error) {
|
||||
handleError(error, 'Error adding users to album');
|
||||
@@ -381,7 +387,7 @@
|
||||
|
||||
const handleRemoveAlbum = async () => {
|
||||
try {
|
||||
await api.albumApi.deleteAlbum({ id: album.id });
|
||||
await deleteAlbum({ id: album.id });
|
||||
goto(backUrl);
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to delete album');
|
||||
@@ -399,7 +405,7 @@
|
||||
assetInteractionStore.clearMultiselect();
|
||||
|
||||
try {
|
||||
await api.albumApi.updateAlbumInfo({
|
||||
await updateAlbumInfo({
|
||||
id: album.id,
|
||||
updateAlbumDto: {
|
||||
albumThumbnailAssetId: assetId,
|
||||
@@ -418,7 +424,7 @@
|
||||
}
|
||||
|
||||
try {
|
||||
await api.albumApi.updateAlbumInfo({
|
||||
await updateAlbumInfo({
|
||||
id: album.id,
|
||||
updateAlbumDto: {
|
||||
albumName: album.albumName,
|
||||
@@ -436,7 +442,7 @@
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await api.albumApi.updateAlbumInfo({
|
||||
await updateAlbumInfo({
|
||||
id: album.id,
|
||||
updateAlbumDto: {
|
||||
description,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { api } from '@api';
|
||||
import { getAlbumInfo } from '@immich/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
await authenticate();
|
||||
const { data: album } = await api.albumApi.getAlbumInfo({ id: params.albumId, withoutAssets: true });
|
||||
const album = await getAlbumInfo({ id: params.albumId, withoutAssets: true });
|
||||
|
||||
return {
|
||||
album,
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification';
|
||||
import { api, type CreateAlbumDto } from '@api';
|
||||
import { albumFactory } from '@test-data';
|
||||
import { get } from 'svelte/store';
|
||||
import { useAlbums } from '../albums.bloc';
|
||||
import type { MockedObject } from 'vitest';
|
||||
|
||||
vi.mock('@api');
|
||||
|
||||
const apiMock: MockedObject<typeof api> = api as MockedObject<typeof api>;
|
||||
|
||||
describe('Albums BLoC', () => {
|
||||
let sut: ReturnType<typeof useAlbums>;
|
||||
const _albums = albumFactory.buildList(5);
|
||||
|
||||
beforeEach(() => {
|
||||
sut = useAlbums({ albums: [..._albums] });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
const notifications = get(notificationController.notificationList);
|
||||
|
||||
for (const notification of notifications) {
|
||||
notificationController.removeNotificationById(notification.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('inits with provided albums', () => {
|
||||
const albums = get(sut.albums);
|
||||
expect(albums.length).toEqual(5);
|
||||
expect(albums).toEqual(_albums);
|
||||
});
|
||||
|
||||
it('loads albums from the server', async () => {
|
||||
// TODO: this method currently deletes albums with no assets and albumName === '' which might not be the best approach
|
||||
const loadedAlbums = [..._albums, albumFactory.build({ id: 'new_loaded_uuid' })];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// TODO: there needs to be a more robust mock of the @api to avoid mockResolvedValueOnce ts error
|
||||
// this is a workaround to make ts checks not fail but the test will pass as expected
|
||||
apiMock.albumApi.getAllAlbums.mockResolvedValueOnce({
|
||||
data: loadedAlbums,
|
||||
config: {},
|
||||
headers: {},
|
||||
status: 200,
|
||||
statusText: '',
|
||||
});
|
||||
|
||||
await sut.loadAlbums();
|
||||
const albums = get(sut.albums);
|
||||
|
||||
expect(apiMock.albumApi.getAllAlbums).toHaveBeenCalledTimes(1);
|
||||
expect(albums).toEqual(loadedAlbums);
|
||||
});
|
||||
|
||||
it('shows error message when it fails loading albums', async () => {
|
||||
// TODO: implement APIProblem interface in the server
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// TODO: there needs to be a more robust mock of the @api to avoid mockResolvedValueOnce ts error
|
||||
// this is a workaround to make ts checks not fail but the test will pass as expected
|
||||
apiMock.albumApi.getAllAlbums.mockRejectedValueOnce({});
|
||||
|
||||
expect(get(notificationController.notificationList)).toHaveLength(0);
|
||||
await sut.loadAlbums();
|
||||
const albums = get(sut.albums);
|
||||
const notifications = get(notificationController.notificationList);
|
||||
|
||||
expect(apiMock.albumApi.getAllAlbums).toHaveBeenCalledTimes(2);
|
||||
expect(albums).toEqual(_albums);
|
||||
expect(notifications).toHaveLength(1);
|
||||
expect(notifications[0].type).toEqual(NotificationType.Error);
|
||||
});
|
||||
|
||||
it('creates a new album', async () => {
|
||||
const payload: CreateAlbumDto = {
|
||||
albumName: '',
|
||||
};
|
||||
|
||||
const returnedAlbum = albumFactory.build();
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// TODO: there needs to be a more robust mock of the @api to avoid mockResolvedValueOnce ts error
|
||||
// this is a workaround to make ts checks not fail but the test will pass as expected
|
||||
apiMock.albumApi.createAlbum.mockResolvedValueOnce({
|
||||
data: returnedAlbum,
|
||||
config: {},
|
||||
headers: {},
|
||||
status: 200,
|
||||
statusText: '',
|
||||
});
|
||||
|
||||
const newAlbum = await sut.createAlbum();
|
||||
|
||||
expect(apiMock.albumApi.createAlbum).toHaveBeenCalledTimes(1);
|
||||
expect(apiMock.albumApi.createAlbum).toHaveBeenCalledWith({ createAlbumDto: payload });
|
||||
expect(newAlbum).toEqual(returnedAlbum);
|
||||
});
|
||||
|
||||
it('shows error message when it fails creating an album', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// TODO: there needs to be a more robust mock of the @api to avoid mockResolvedValueOnce ts error
|
||||
// this is a workaround to make ts checks not fail but the test will pass as expected
|
||||
apiMock.albumApi.createAlbum.mockRejectedValueOnce({});
|
||||
|
||||
const newAlbum = await sut.createAlbum();
|
||||
const notifications = get(notificationController.notificationList);
|
||||
|
||||
expect(apiMock.albumApi.createAlbum).toHaveBeenCalledTimes(2);
|
||||
expect(newAlbum).not.toBeDefined();
|
||||
expect(notifications).toHaveLength(1);
|
||||
expect(notifications[0].type).toEqual(NotificationType.Error);
|
||||
});
|
||||
|
||||
it('selects an album and deletes it', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// TODO: there needs to be a more robust mock of the @api to avoid mockResolvedValueOnce ts error
|
||||
// this is a workaround to make ts checks not fail but the test will pass as expected
|
||||
apiMock.albumApi.deleteAlbum.mockResolvedValueOnce({
|
||||
data: undefined,
|
||||
config: {},
|
||||
headers: {},
|
||||
status: 200,
|
||||
statusText: '',
|
||||
});
|
||||
|
||||
const albumToDelete = get(sut.albums)[2]; // delete third album
|
||||
const albumToDeleteId = albumToDelete.id;
|
||||
const contextMenuCoords = { x: 100, y: 150 };
|
||||
|
||||
expect(get(sut.isShowContextMenu)).toBe(false);
|
||||
sut.showAlbumContextMenu(contextMenuCoords, albumToDelete);
|
||||
expect(get(sut.contextMenuPosition)).toEqual(contextMenuCoords);
|
||||
expect(get(sut.isShowContextMenu)).toBe(true);
|
||||
expect(get(sut.contextMenuTargetAlbum)).toEqual(albumToDelete);
|
||||
|
||||
await sut.deleteAlbum(albumToDelete);
|
||||
const updatedAlbums = get(sut.albums);
|
||||
|
||||
expect(apiMock.albumApi.deleteAlbum).toHaveBeenCalledTimes(1);
|
||||
expect(apiMock.albumApi.deleteAlbum).toHaveBeenCalledWith({ id: albumToDeleteId });
|
||||
expect(updatedAlbums).toHaveLength(4);
|
||||
expect(updatedAlbums).not.toContain(albumToDelete);
|
||||
});
|
||||
|
||||
it('closes album context menu, deselecting album', () => {
|
||||
const albumToDelete = get(sut.albums)[2]; // delete third album
|
||||
sut.showAlbumContextMenu({ x: 100, y: 150 }, albumToDelete);
|
||||
|
||||
expect(get(sut.isShowContextMenu)).toBe(true);
|
||||
|
||||
sut.closeAlbumContextMenu();
|
||||
expect(get(sut.isShowContextMenu)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { OnShowContextMenuDetail } from '$lib/components/album-page/album-card';
|
||||
import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification';
|
||||
import { type AlbumResponseDto, api } from '@api';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { createAlbum, deleteAlbum, getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
||||
import { derived, get, writable } from 'svelte/store';
|
||||
|
||||
type AlbumsProperties = { albums: AlbumResponseDto[] };
|
||||
@@ -13,14 +14,14 @@ export const useAlbums = (properties: AlbumsProperties) => {
|
||||
|
||||
async function loadAlbums(): Promise<void> {
|
||||
try {
|
||||
const { data } = await api.albumApi.getAllAlbums();
|
||||
const data = await getAllAlbums({});
|
||||
albums.set(data);
|
||||
|
||||
// Delete album that has no photos and is named ''
|
||||
for (const album of data) {
|
||||
if (album.albumName === '' && album.assetCount === 0) {
|
||||
setTimeout(async () => {
|
||||
await deleteAlbum(album);
|
||||
await handleDeleteAlbum(album);
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
@@ -32,30 +33,17 @@ export const useAlbums = (properties: AlbumsProperties) => {
|
||||
}
|
||||
}
|
||||
|
||||
async function createAlbum(): Promise<AlbumResponseDto | undefined> {
|
||||
async function handleCreateAlbum(): Promise<AlbumResponseDto | undefined> {
|
||||
try {
|
||||
const { data: newAlbum } = await api.albumApi.createAlbum({
|
||||
createAlbumDto: {
|
||||
albumName: '',
|
||||
},
|
||||
});
|
||||
|
||||
return newAlbum;
|
||||
} catch {
|
||||
notificationController.show({
|
||||
message: 'Error creating album',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
return await createAlbum({ createAlbumDto: { albumName: '' } });
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to create album');
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteAlbum(albumToDelete: AlbumResponseDto): Promise<void> {
|
||||
await api.albumApi.deleteAlbum({ id: albumToDelete.id });
|
||||
albums.set(
|
||||
get(albums).filter(({ id }) => {
|
||||
return id !== albumToDelete.id;
|
||||
}),
|
||||
);
|
||||
async function handleDeleteAlbum(albumToDelete: AlbumResponseDto): Promise<void> {
|
||||
await deleteAlbum({ id: albumToDelete.id });
|
||||
albums.set(get(albums).filter(({ id }) => id !== albumToDelete.id));
|
||||
}
|
||||
|
||||
async function showAlbumContextMenu(
|
||||
@@ -80,8 +68,8 @@ export const useAlbums = (properties: AlbumsProperties) => {
|
||||
contextMenuPosition,
|
||||
contextMenuTargetAlbum,
|
||||
loadAlbums,
|
||||
createAlbum,
|
||||
deleteAlbum,
|
||||
createAlbum: handleCreateAlbum,
|
||||
deleteAlbum: handleDeleteAlbum,
|
||||
showAlbumContextMenu,
|
||||
closeAlbumContextMenu,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { api } from '@api';
|
||||
import { getUserById } from '@immich/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
await authenticate();
|
||||
|
||||
const { data: partner } = await api.userApi.getUserById({ id: params.userId });
|
||||
const partner = await getUserById({ id: params.userId });
|
||||
|
||||
return {
|
||||
partner,
|
||||
|
||||
@@ -3,38 +3,25 @@
|
||||
import empty2Url from '$lib/assets/empty-2.svg';
|
||||
import AlbumCard from '$lib/components/album-page/album-card.svelte';
|
||||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import {
|
||||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { api } from '@api';
|
||||
import { flip } from 'svelte/animate';
|
||||
import type { PageData } from './$types';
|
||||
import { createAlbum } from '@immich/sdk';
|
||||
import { mdiLink, mdiPlusBoxOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { handleError } from '../../../lib/utils/handle-error';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
const createSharedAlbum = async () => {
|
||||
try {
|
||||
const { data: newAlbum } = await api.albumApi.createAlbum({
|
||||
createAlbumDto: {
|
||||
albumName: '',
|
||||
},
|
||||
});
|
||||
|
||||
const newAlbum = await createAlbum({ createAlbumDto: { albumName: '' } });
|
||||
goto(`${AppRoute.ALBUMS}/${newAlbum.id}`);
|
||||
} catch (error) {
|
||||
notificationController.show({
|
||||
message: 'Error creating album, check console for more details',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
|
||||
console.log('Error [createAlbum]', error);
|
||||
handleError(error, 'Unable to create album');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { api } from '@api';
|
||||
import { getAllAlbums, getPartners } from '@immich/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async () => {
|
||||
await authenticate();
|
||||
const { data: sharedAlbums } = await api.albumApi.getAllAlbums({ shared: true });
|
||||
const { data: partners } = await api.partnerApi.getPartners({ direction: 'shared-with' });
|
||||
const sharedAlbums = await getAllAlbums({ shared: true });
|
||||
const partners = await getPartners({ direction: 'shared-with' });
|
||||
|
||||
return {
|
||||
sharedAlbums,
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import empty3Url from '$lib/assets/empty-3.svg';
|
||||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte';
|
||||
import RestoreAssets from '$lib/components/photos-page/actions/restore-assets.svelte';
|
||||
import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
|
||||
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
|
||||
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import {
|
||||
NotificationType,
|
||||
notificationController,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { api } from '@api';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
|
||||
import { goto } from '$app/navigation';
|
||||
import empty3Url from '$lib/assets/empty-3.svg';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { mdiDeleteOutline, mdiHistory } from '@mdi/js';
|
||||
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
|
||||
import { AssetStore } from '$lib/stores/assets.store';
|
||||
import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { emptyTrash, restoreTrash } from '@immich/sdk';
|
||||
import { mdiDeleteOutline, mdiHistory } from '@mdi/js';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
const handleEmptyTrash = async () => {
|
||||
isShowEmptyConfirmation = false;
|
||||
try {
|
||||
await api.trashApi.emptyTrash();
|
||||
await emptyTrash();
|
||||
|
||||
notificationController.show({
|
||||
message: `Empty trash initiated. Refresh the page to see the changes`,
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
const handleRestoreTrash = async () => {
|
||||
try {
|
||||
await api.trashApi.restoreTrash();
|
||||
await restoreTrash();
|
||||
|
||||
notificationController.show({
|
||||
message: `Restore trash initiated. Refresh the page to see the changes`,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { api } from '@api';
|
||||
import { getApiKeys, getAuthDevices } from '@immich/sdk';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load = (async () => {
|
||||
await authenticate();
|
||||
|
||||
const { data: keys } = await api.keyApi.getApiKeys();
|
||||
const { data: devices } = await api.authenticationApi.getAuthDevices();
|
||||
const keys = await getApiKeys();
|
||||
const devices = await getAuthDevices();
|
||||
|
||||
return {
|
||||
keys,
|
||||
|
||||
Reference in New Issue
Block a user