- Detect navigation direction (forward/backward) via router beforeEach guard
- Store transition direction in Pinia for cross-component access
- Wrap ExplorerView content in a CSS grid transition wrapper so old and new
views overlap in the same grid cell during animation
- Add slide-forward/slide-backward transition classes with translate3d
for GPU-accelerated, simultaneous enter/leave without gaps
- Keep fixed-position search loader outside the transition
- Verify single queue: uploads append to upqueue and are processed
sequentially by one worker (parallel only within a single file).
- Before accepting a new batch, calculate total size minus existing
files that will be overwritten.
- Reject the whole batch if free space < net need + 512 MiB margin.
- Show a toast with human-readable needed vs available space.
- Add cista/util/diskspace.py with MIN_FREE_BYTES limit and cached
check_free_space() helper.
- Check available space in File.write() before ftruncate/write.
- Catch ENOSPC in File.write and re-raise as InsufficientStorageError.
- upload_file_chunk catches both proactive and ENOSPC errors and
returns HTTP 507 Insufficient Storage.
- Add tests for low-disk rejection and ENOSPC handling.
- Trim document extension list to common office formats only
(doc/docx/xls/xlsx/ppt/pptx/odt/ods/odp/rtf), removing txt/md/csv/html/xml/etc.
- Simplify Doc getters: merge guard clauses into single returns
(img, previewable, previewurl, ext).
- Simplify MediaPreview.preview() into single boolean expression.
- Use global FILE_TYPES instead of inline extension lists.
_get_image_dimensions now relies solely on pyvips header reading.
If pyvips cannot read the header the function returns None and the
caller encodes at full resolution rather than falling back to ffprobe.
Remove unused stdlib json import.
- Use ffmpeg CLI directly for HEIC/HEIF previews (bypassing pyvips which
cannot encode >8-bit AVIF on current system). ffmpeg handles tile
assembly, EXIF rotation, HDR metadata and ICC profiles automatically.
- pyvips remains primary for other image formats; ffmpeg is fallback.
- Simplify _get_image_dimensions() to use pyvips header read for all
formats including HEIC, with ffprobe as fallback.
- Move all imports to top of preview.py; remove lazy OnlyOffice import.
- Worker pool: add readiness handshake (\x01 byte), bounded idle wait
with PREVIEW_TIMEOUT, eager module import before signalling.
- Fix dispatch data check bug (was 'if data is not None' -> 'if data').
- Add logger.exception for unhandled preview/dispatch errors.
- EmojiFormatter now includes tracebacks for exception logs.
- Return 503 on preview timeouts instead of 504.
- Move OnlyOffice conversion out of worker subprocesses into async event loop
using httpx.AsyncClient with shared client and clean shutdown hook
- Add OOConversionManager with in-flight deduplication (asyncio.Future) and
configurable concurrency limit (OO_MAX_CONCURRENT=2)
- Add 10s total timeout for office previews via asyncio.wait_for
- Return 503 when OnlyOffice is unavailable, 504 on timeout
- Remove office handling from worker dispatch(); workers now only do
images, video, and PDFs
- Replace PNG tempfile bridge with framed binary input protocol on worker
stdin: (json_size)(data_size)(json)(raw_data)
- Add process_image_buffer() for in-memory AVIF conversion via pyvips
- Add office_previews to WS server message, cached every 30s from OO
availability check
- Frontend gates only office document previews on office_previews flag;
images, video, PDFs remain unconditional
- Change default OnlyOffice port from 8080 to 8988
Show 'Order [1] [2] [3]' keycaps to the right of the search bar
when the viewport is at least 800px wide. These visual hints
match the existing '/' search keycap style and correspond to
the existing keyboard shortcuts for sorting:
1 = name (alphabetical)
2 = modified (newest first)
3 = size (largest first)
Hints are hidden on narrow viewports and when text input fields are focused.
Benchmarks three preview pipelines across all sample documents:
- BMP → AVIF (via pyvips)
- PNG → AVIF (via pyvips) — selected for production
- PNG only (no compression)
Results confirm PNG → AVIF as the optimal path:
- ~30 ms AVIF encode overhead
- 2.1× size reduction vs raw PNG
- Slightly faster than BMP → AVIF
Replace Aspose.Words with OnlyOffice Document Server for generating
bitmap previews of office documents (Word, Excel, PowerPoint, etc.).
Backend:
- Add cista/onlyoffice.py conversion client
- Convert office docs directly to PNG via OnlyOffice, then AVIF via pyvips
- Make office previews optional based on OnlyOffice availability
- Remove Aspose.Words dependency and all related code
- Add spreadsheet and presentation format support
Frontend:
- Mark office files as previewable in Document.ts
- Add office extensions to MediaPreview.vue preview list
- Fix pre-existing @ts-ignore in HeaderMain.vue
Tests:
- Fix test_lrucache.py parameter name (open -> opener)
Also run ruff format across the codebase to satisfy linter checks.