asset-utils.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { api, AddAssetsResponseDto, AssetResponseDto } from '@api';
  2. import {
  3. notificationController,
  4. NotificationType
  5. } from '$lib/components/shared-components/notification/notification';
  6. import { downloadAssets } from '$lib/stores/download';
  7. export const addAssetsToAlbum = async (
  8. albumId: string,
  9. assetIds: Array<string>,
  10. key: string | undefined = undefined
  11. ): Promise<AddAssetsResponseDto> =>
  12. api.albumApi
  13. .addAssetsToAlbum(albumId, { assetIds }, { params: { key } })
  14. .then(({ data: dto }) => {
  15. if (dto.successfullyAdded > 0) {
  16. // This might be 0 if the user tries to add an asset that is already in the album
  17. notificationController.show({
  18. message: `Added ${dto.successfullyAdded} to ${dto.album?.albumName}`,
  19. type: NotificationType.Info
  20. });
  21. }
  22. return dto;
  23. });
  24. export async function bulkDownload(
  25. fileName: string,
  26. assets: AssetResponseDto[],
  27. onDone: () => void,
  28. key?: string
  29. ) {
  30. const assetIds = assets.map((asset) => asset.id);
  31. try {
  32. // let skip = 0;
  33. let count = 0;
  34. let done = false;
  35. while (!done) {
  36. count++;
  37. const downloadFileName = fileName + `${count === 1 ? '' : count}.zip`;
  38. downloadAssets.set({ [downloadFileName]: 0 });
  39. let total = 0;
  40. const { data, status, headers } = await api.assetApi.downloadFiles(
  41. { assetIds },
  42. {
  43. params: { key },
  44. responseType: 'blob',
  45. onDownloadProgress: function (progressEvent) {
  46. const request = this as XMLHttpRequest;
  47. if (!total) {
  48. total = Number(request.getResponseHeader('X-Immich-Content-Length-Hint')) || 0;
  49. }
  50. if (total) {
  51. const current = progressEvent.loaded;
  52. downloadAssets.set({ [downloadFileName]: Math.floor((current / total) * 100) });
  53. }
  54. }
  55. }
  56. );
  57. const isNotComplete = headers['x-immich-archive-complete'] === 'false';
  58. const fileCount = Number(headers['x-immich-archive-file-count']) || 0;
  59. if (isNotComplete && fileCount > 0) {
  60. // skip += fileCount;
  61. } else {
  62. onDone();
  63. done = true;
  64. }
  65. if (!(data instanceof Blob)) {
  66. return;
  67. }
  68. if (status === 201) {
  69. const fileUrl = URL.createObjectURL(data);
  70. const anchor = document.createElement('a');
  71. anchor.href = fileUrl;
  72. anchor.download = downloadFileName;
  73. document.body.appendChild(anchor);
  74. anchor.click();
  75. document.body.removeChild(anchor);
  76. URL.revokeObjectURL(fileUrl);
  77. // Remove item from download list
  78. setTimeout(() => {
  79. downloadAssets.set({});
  80. }, 2000);
  81. }
  82. }
  83. } catch (e) {
  84. console.error('Error downloading file ', e);
  85. notificationController.show({
  86. type: NotificationType.Error,
  87. message: 'Error downloading file, check console for more details.'
  88. });
  89. }
  90. }