fix(photos): убрать мигание предпросмотра и задержку сброса правок
- фото и photo.updated несут edit_pending: рендер сохранённых правок ещё идёт - клиент держит предпросмотр, пока серверная версия не загружена и не декодирована, поэтому оригинал не мелькает при подмене - сброс возвратом контролов в значения по умолчанию виден сразу, не через 10 с - Viewer берёт URL из актуального объекта (SSE), fresh остаётся фолбэком - попутно исправлен порядок чтения tags и album_title в ListTrash
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { Photo } from './types';
|
||||
import { computeViewerSource, editPendingOf } from './viewer-source';
|
||||
|
||||
const BASE = {
|
||||
originalUrl: '/orig.jpg',
|
||||
previewUrl: '/preview.jpg',
|
||||
editUrl: '/edit.jpg',
|
||||
editPreviewUrl: '/edit-preview.jpg'
|
||||
};
|
||||
|
||||
describe('computeViewerSource', () => {
|
||||
it('shows the server render when it matches the saved edits', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: false,
|
||||
dirty: false,
|
||||
editPending: false,
|
||||
localParamsEmpty: false,
|
||||
...BASE
|
||||
});
|
||||
expect(src.useBase).toBe(false);
|
||||
expect(src.serverSrc).toBe('/edit-preview.jpg');
|
||||
expect(src.baseSrc).toBe('/preview.jpg');
|
||||
});
|
||||
|
||||
it('uses the full-size variants in zoom', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: true,
|
||||
dirty: false,
|
||||
editPending: false,
|
||||
localParamsEmpty: false,
|
||||
...BASE
|
||||
});
|
||||
expect(src.serverSrc).toBe('/edit.jpg');
|
||||
expect(src.baseSrc).toBe('/orig.jpg');
|
||||
});
|
||||
|
||||
it('keeps the client preview while local edits are unsaved', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: true,
|
||||
dirty: true,
|
||||
editPending: false,
|
||||
localParamsEmpty: false,
|
||||
...BASE
|
||||
});
|
||||
expect(src.useBase).toBe(true);
|
||||
expect(src.drawCanvas).toBe(true);
|
||||
expect(src.baseSrc).toBe('/orig.jpg');
|
||||
});
|
||||
|
||||
it('shows the base version immediately when the edits are reset to defaults', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: true,
|
||||
dirty: true,
|
||||
editPending: false,
|
||||
localParamsEmpty: true,
|
||||
...BASE
|
||||
});
|
||||
expect(src.useBase).toBe(true);
|
||||
expect(src.drawCanvas).toBe(false);
|
||||
expect(src.baseSrc).toBe('/orig.jpg');
|
||||
});
|
||||
|
||||
it('ignores a stale server render while the saved edits are still rendering', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: false,
|
||||
dirty: false,
|
||||
editPending: true,
|
||||
localParamsEmpty: false,
|
||||
...BASE
|
||||
});
|
||||
expect(src.useBase).toBe(true);
|
||||
expect(src.drawCanvas).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps the client preview when a second edit is pending over an old render', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: true,
|
||||
dirty: false,
|
||||
editPending: true,
|
||||
localParamsEmpty: false,
|
||||
...BASE
|
||||
});
|
||||
expect(src.useBase).toBe(true);
|
||||
expect(src.drawCanvas).toBe(true);
|
||||
expect(src.baseSrc).toBe('/orig.jpg');
|
||||
});
|
||||
|
||||
it('falls back to the base version when there is no edit render', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: false,
|
||||
dirty: false,
|
||||
editPending: false,
|
||||
localParamsEmpty: true,
|
||||
originalUrl: '/orig.jpg',
|
||||
previewUrl: '/preview.jpg'
|
||||
});
|
||||
expect(src.useBase).toBe(true);
|
||||
expect(src.drawCanvas).toBe(false);
|
||||
expect(src.serverSrc).toBe('/preview.jpg');
|
||||
});
|
||||
|
||||
it('prefers the full-size base when zoomed without a preview', () => {
|
||||
const src = computeViewerSource({
|
||||
zoomed: true,
|
||||
dirty: false,
|
||||
editPending: false,
|
||||
localParamsEmpty: true,
|
||||
originalUrl: '/orig.jpg'
|
||||
});
|
||||
expect(src.baseSrc).toBe('/orig.jpg');
|
||||
expect(src.serverSrc).toBe('/orig.jpg');
|
||||
});
|
||||
|
||||
it('treats the old backend without edit_pending as a finished render', () => {
|
||||
expect(editPendingOf(undefined)).toBe(false);
|
||||
expect(editPendingOf({ id: 'p' } as Photo)).toBe(false);
|
||||
expect(editPendingOf({ id: 'p', edit_pending: true } as Photo)).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user