feat(web): вкладка «Редактирование» с инструментом «Свет»
В правой панели фото появилась вкладка «Редактирование» с инструментом «Свет»: ползунки экспозиции, контраста, светов, теней, белых и чёрных и точечная кривая с выбором канала. Правки сохраняются автоматически, переключатель «Сброс» удаляет параметры правок и отредактированную версию фото. Редактирование неразрушающее: параметры хранятся в метаданных фото, а отредактированная версия рендерится в фоне отдельным объектом (edit, edit_thumb, edit_medium, edit_preview) рядом с исходными вариантами. Оригинал не меняется, скачивание отдаёт исходный файл. Сетка, просмотр и обложки альбомов показывают отредактированную версию, когда она отрендерена.
This commit is contained in:
@@ -145,6 +145,11 @@
|
||||
// insert an unseen photo here, or the grid would reflow.
|
||||
const photo = data as unknown as Photo;
|
||||
photos = photos.map((p) => (p.id === photo.id ? photo : p));
|
||||
// Обновлённое фото (например, отрендеренные правки) должно
|
||||
// попасть и в правую панель.
|
||||
if (selection.albumId === albumId && selection.has(photo.id)) {
|
||||
selection.replace(photo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'like.added': {
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
import { photoUpdates } from '$lib/stores/photo-updates.svelte';
|
||||
import { trash } from '$lib/stores/trash.svelte';
|
||||
import { viewerReturn } from '$lib/stores/viewer-return';
|
||||
import { auth } from '$lib/stores/auth.svelte';
|
||||
import { SSEClient } from '$lib/sse';
|
||||
import type { Album, Photo } from '$lib/types';
|
||||
|
||||
const albumId = $derived($page.params.id ?? '');
|
||||
@@ -55,6 +57,27 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Обновления альбома: отрендеренные правки приходят отдельным событием.
|
||||
let client: SSEClient | null = null;
|
||||
|
||||
$effect(() => {
|
||||
const id = albumId;
|
||||
if (!auth.access) return;
|
||||
client = new SSEClient({
|
||||
path: `/api/sse/albums/${id}`,
|
||||
onEvent: (ev) => {
|
||||
if (ev.type !== 'photo.updated') return;
|
||||
const updated = ev.data as unknown as Photo;
|
||||
photos = photos.map((p) => (p.id === updated.id ? updated : p));
|
||||
}
|
||||
});
|
||||
client.connect(auth.access);
|
||||
return () => {
|
||||
client?.close();
|
||||
client = null;
|
||||
};
|
||||
});
|
||||
|
||||
function close() {
|
||||
goto(`/albums/${albumId}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user