123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import { api, AddAssetsResponseDto, AssetResponseDto } from '@api';
- import {
- notificationController,
- NotificationType
- } from '$lib/components/shared-components/notification/notification';
- import { downloadAssets } from '$lib/stores/download';
- export const addAssetsToAlbum = async (
- albumId: string,
- assetIds: Array<string>,
- key: string | undefined = undefined
- ): Promise<AddAssetsResponseDto> =>
- api.albumApi
- .addAssetsToAlbum({ id: albumId, addAssetsDto: { assetIds }, key })
- .then(({ data: dto }) => {
- if (dto.successfullyAdded > 0) {
- // This might be 0 if the user tries to add an asset that is already in the album
- notificationController.show({
- message: `Added ${dto.successfullyAdded} to ${dto.album?.albumName}`,
- type: NotificationType.Info
- });
- }
- return dto;
- });
- export async function bulkDownload(
- fileName: string,
- assets: AssetResponseDto[],
- onDone?: () => void,
- key?: string
- ) {
- const assetIds = assets.map((asset) => asset.id);
- try {
- // let skip = 0;
- let count = 0;
- let done = false;
- while (!done) {
- count++;
- const downloadFileName = fileName + `${count === 1 ? '' : count}.zip`;
- downloadAssets.set({ [downloadFileName]: 0 });
- let total = 0;
- const { data, status, headers } = await api.assetApi.downloadFiles(
- { downloadFilesDto: { assetIds }, key },
- {
- responseType: 'blob',
- onDownloadProgress: function (progressEvent) {
- const request = this as XMLHttpRequest;
- if (!total) {
- total = Number(request.getResponseHeader('X-Immich-Content-Length-Hint')) || 0;
- }
- if (total) {
- const current = progressEvent.loaded;
- downloadAssets.set({ [downloadFileName]: Math.floor((current / total) * 100) });
- }
- }
- }
- );
- const isNotComplete = headers['x-immich-archive-complete'] === 'false';
- const fileCount = Number(headers['x-immich-archive-file-count']) || 0;
- if (isNotComplete && fileCount > 0) {
- // skip += fileCount;
- } else {
- onDone?.();
- done = true;
- }
- if (!(data instanceof Blob)) {
- return;
- }
- if (status === 201) {
- const fileUrl = URL.createObjectURL(data);
- const anchor = document.createElement('a');
- anchor.href = fileUrl;
- anchor.download = downloadFileName;
- document.body.appendChild(anchor);
- anchor.click();
- document.body.removeChild(anchor);
- URL.revokeObjectURL(fileUrl);
- // Remove item from download list
- setTimeout(() => {
- downloadAssets.set({});
- }, 2000);
- }
- }
- } catch (e) {
- console.error('Error downloading file ', e);
- notificationController.show({
- type: NotificationType.Error,
- message: 'Error downloading file, check console for more details.'
- });
- }
- }
- /**
- * Returns the lowercase filename extension without a dot (.) and
- * an empty string when not found.
- */
- export function getFilenameExtension(filename: string): string {
- const lastIndex = Math.max(0, filename.lastIndexOf('.'));
- const startIndex = (lastIndex || Infinity) + 1;
- return filename.slice(startIndex).toLowerCase();
- }
- /**
- * Returns the filename of an asset including file extension
- */
- export function getAssetFilename(asset: AssetResponseDto): string {
- const fileExtension = getFilenameExtension(asset.originalPath);
- return `${asset.originalFileName}.${fileExtension}`;
- }
- /**
- * Returns the MIME type of the file and an empty string when not found.
- */
- export function getFileMimeType(file: File): string {
- const mimeTypes: Record<string, string> = {
- '3gp': 'video/3gpp',
- arw: 'image/x-sony-arw',
- dng: 'image/dng',
- heic: 'image/heic',
- heif: 'image/heif',
- insp: 'image/jpeg',
- insv: 'video/mp4',
- nef: 'image/x-nikon-nef',
- raf: 'image/x-fuji-raf',
- srw: 'image/x-samsung-srw'
- };
- // Return the MIME type determined by the browser or the MIME type based on the file extension.
- return file.type || (mimeTypes[getFilenameExtension(file.name)] ?? '');
- }
- /**
- * Returns aspect ratio for the asset
- */
- export function getAssetRatio(asset: AssetResponseDto) {
- let height = asset.exifInfo?.exifImageHeight || 235;
- let width = asset.exifInfo?.exifImageWidth || 235;
- const orientation = Number(asset.exifInfo?.orientation);
- if (orientation) {
- if (orientation == 6 || orientation == -90) {
- [width, height] = [height, width];
- }
- }
- return { width, height };
- }
|