148 lines
5.1 KiB
TypeScript
148 lines
5.1 KiB
TypeScript
import { inject, Injectable } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { firstValueFrom, map, tap } from 'rxjs';
|
|
import { EndpointService } from './EndpointService';
|
|
import { ImageView } from '../models/ImageView.model';
|
|
import { SliceView } from '../models/SliceView.model';
|
|
import { QueryParams } from '../models/Query.model';
|
|
import { QueryClient, QueryOptions, queryOptions } from '@tanstack/angular-query-experimental';
|
|
import { ImageViewWithBlobUrl } from '../client-models/ImageViewWithBlobUrl';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class ImageService {
|
|
public static ImageProps = [
|
|
'id',
|
|
'created',
|
|
'modified',
|
|
'userFilename',
|
|
'mimeType',
|
|
'alt',
|
|
'caption',
|
|
'objectName',
|
|
'height',
|
|
'width',
|
|
'owner',
|
|
'viewers',
|
|
] as const;
|
|
|
|
private readonly httpClient = inject(HttpClient);
|
|
private readonly endpointService = inject(EndpointService);
|
|
private readonly queryClient = inject(QueryClient);
|
|
|
|
public getOwnedImages(queryParams?: QueryParams<typeof ImageService.ImageProps>): Promise<SliceView<ImageView>> {
|
|
return firstValueFrom(
|
|
this.httpClient.get<SliceView<ImageView>>(this.endpointService.getUrl('images', [], queryParams)),
|
|
);
|
|
}
|
|
|
|
public getImageViewWithBlobUrl(imageView: ImageView): Promise<ImageViewWithBlobUrl> {
|
|
return firstValueFrom(
|
|
this.httpClient
|
|
.get(this.endpointService.getUrl('images', [imageView.owner.username, imageView.filename]), {
|
|
responseType: 'blob',
|
|
})
|
|
.pipe(
|
|
map((blob) => URL.createObjectURL(blob)),
|
|
map(
|
|
(blobUrl) =>
|
|
({
|
|
...imageView,
|
|
blobUrl,
|
|
}) satisfies ImageViewWithBlobUrl,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
public getImage(
|
|
imageView: ImageView,
|
|
): QueryOptions<ImageViewWithBlobUrl, Error, ImageViewWithBlobUrl, [string, string, string]> {
|
|
return queryOptions({
|
|
queryKey: ['image-views-with-blob-urls', imageView.owner.username, imageView.filename],
|
|
queryFn: () => this.getImageViewWithBlobUrl(imageView),
|
|
});
|
|
}
|
|
|
|
public uploadImage(
|
|
image: File,
|
|
filename?: string,
|
|
alt?: string,
|
|
caption?: string,
|
|
isPublic?: boolean,
|
|
): Promise<ImageView> {
|
|
const formData = new FormData();
|
|
formData.append('image', image);
|
|
formData.append('filename', filename ?? image.name);
|
|
if (alt) {
|
|
formData.append('alt', alt);
|
|
}
|
|
if (caption) {
|
|
formData.append('caption', caption);
|
|
}
|
|
if (isPublic !== undefined) {
|
|
formData.append('isPublic', isPublic.toString());
|
|
}
|
|
|
|
return firstValueFrom(
|
|
this.httpClient.post<ImageView>(this.endpointService.getUrl('images'), formData).pipe(
|
|
tap(async () => {
|
|
await this.queryClient.invalidateQueries({
|
|
queryKey: ['image-views'],
|
|
});
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
public imageExists(username: string, filename: string): Promise<boolean> {
|
|
return firstValueFrom(
|
|
this.httpClient
|
|
.get<{ exists: boolean }>(this.endpointService.getUrl('images', [username, filename, 'exists']))
|
|
.pipe(map((view) => view.exists)),
|
|
);
|
|
}
|
|
|
|
public deleteImage(username: string, filename: string): Promise<void> {
|
|
return firstValueFrom(
|
|
this.httpClient.delete<void>(this.endpointService.getUrl('images', [username, filename])).pipe(
|
|
tap(async () => {
|
|
await this.queryClient.refetchQueries({
|
|
queryKey: ['image-views', username, filename],
|
|
});
|
|
await this.queryClient.refetchQueries({
|
|
queryKey: ['image-views-with-blob-urls', username, filename],
|
|
});
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
public updateImage(
|
|
username: string,
|
|
filename: string,
|
|
data: {
|
|
alt?: string | null;
|
|
caption?: string | null;
|
|
isPublic?: boolean | null;
|
|
viewersToAdd?: string[] | null;
|
|
viewersToRemove?: string[] | null;
|
|
clearAllViewers?: boolean | null;
|
|
},
|
|
): Promise<ImageView> {
|
|
return firstValueFrom(
|
|
this.httpClient.put<ImageView>(this.endpointService.getUrl('images', [username, filename]), data).pipe(
|
|
tap(async () => {
|
|
await this.queryClient.refetchQueries({
|
|
queryKey: ['image-views', username, filename],
|
|
});
|
|
await this.queryClient.refetchQueries({
|
|
queryKey: ['image-views-with-blob-urls', username, filename],
|
|
});
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
}
|