API responses now include file_url and thumbnail_url fields. When S3_PUBLIC_BASE_URL is configured, these point to the CDN domain; when unset, they fall back to the existing API proxy paths so local dev requires no additional setup. UI updated to use response URL fields directly instead of constructing proxy URLs client-side. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
import { Observable } from 'rxjs';
|
|
|
|
export interface ImageRecord {
|
|
id: string;
|
|
hash: string;
|
|
filename: string;
|
|
mime_type: string;
|
|
size_bytes: number;
|
|
width: number;
|
|
height: number;
|
|
storage_key: string;
|
|
thumbnail_key: string | null;
|
|
file_url: string;
|
|
thumbnail_url: string | null;
|
|
created_at: string;
|
|
tags: string[];
|
|
duplicate?: boolean;
|
|
}
|
|
|
|
export interface ImageListResponse {
|
|
items: ImageRecord[];
|
|
total: number;
|
|
limit: number;
|
|
offset: number;
|
|
}
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class ImageService {
|
|
private readonly base = '/api/v1';
|
|
|
|
constructor(private http: HttpClient) {}
|
|
|
|
upload(file: File, tags: string[]): Observable<ImageRecord> {
|
|
const form = new FormData();
|
|
form.append('file', file);
|
|
if (tags.length) {
|
|
form.append('tags', tags.join(','));
|
|
}
|
|
return this.http.post<ImageRecord>(`${this.base}/images`, form);
|
|
}
|
|
|
|
list(tagFilter: string[] = [], limit = 50, offset = 0): Observable<ImageListResponse> {
|
|
let params = new HttpParams().set('limit', limit).set('offset', offset);
|
|
if (tagFilter.length) {
|
|
params = params.set('tags', tagFilter.join(','));
|
|
}
|
|
return this.http.get<ImageListResponse>(`${this.base}/images`, { params });
|
|
}
|
|
|
|
get(id: string): Observable<ImageRecord> {
|
|
return this.http.get<ImageRecord>(`${this.base}/images/${id}`);
|
|
}
|
|
|
|
updateTags(id: string, tags: string[]): Observable<ImageRecord> {
|
|
return this.http.patch<ImageRecord>(`${this.base}/images/${id}/tags`, { tags });
|
|
}
|
|
|
|
delete(id: string): Observable<void> {
|
|
return this.http.delete<void>(`${this.base}/images/${id}`);
|
|
}
|
|
}
|