Detail page now has a "Copy URL" button that copies the image's direct file URL to the clipboard. A toast service (BehaviorSubject-backed, auto-dismissing after 3s) confirms success or failure. ToastComponent is registered at the app root and available to all future features. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.3 KiB
1.3 KiB
Contract: ToastService
Location: ui/src/app/services/toast.service.ts
Provided in: root (singleton)
Interface
interface Toast {
message: string;
type: 'success' | 'error';
}
class ToastService {
// Observable — emits a Toast when one is active, null when none.
readonly current$: Observable<Toast | null>;
// Show a toast. Replaces any currently-visible toast.
// duration defaults to 3000ms.
show(message: string, type?: 'success' | 'error', duration?: number): void;
}
Behaviour
show()emits the toast immediately oncurrent$.- After
durationms, emitsnullto dismiss. - Calling
show()again before the timer expires resets the timer (new toast replaces old). typedefaults to'success'.durationdefaults to3000.
Usage Example
// In any component:
constructor(private toast: ToastService) {}
async copyUrl() {
try {
await navigator.clipboard.writeText(url);
this.toast.show('URL copied!');
} catch {
this.toast.show('Failed to copy URL', 'error');
}
}
Consumer: ToastComponent
ToastComponent subscribes to current$ via the async pipe and renders/hides based on the emitted value. It is placed once in AppComponent and is always present in the DOM.