Releases: fukuyori/Spindle
Releases · fukuyori/Spindle
Release list
0.7.3
[0.7.1] - 2026-07-28
Fixed
- Glossary terms now reliably reach the model. The glossary is sent inside
the user-turn task statement as well as the system prompt (translation-tuned
models weigh the former), reworded per task (translation vs. summary), and
emitted as one terse line instead of an instruction paragraph. The term list
is capped relative to the text length so a large glossary can no longer
drown a short paragraph and derail the translation. - Glossary matching misses fewer occurrences. Terms whose edges are CJK
characters match inside unspaced Japanese/Chinese prose (the word-boundary
guard no longer applies there), and English entries also match simple
plural/possessive forms ("Caesars", "Caesar's"). - Blocks that are exactly one glossary term skip the model. Headings such
as a bare person's name are rendered directly with the glossary target — in
page translation, selection translation, and EPUB export — instead of
risking a model round-trip mangling the mandated form.
0.7.0
[0.7.0] - 2026-07-19
Added
- Bilingual UI (Japanese / English). All menu, toolbar, dialog, and status
strings are now translatable. The UI language follows the system locale
(Japanese system → Japanese UI, anything else → English) and can be forced
via the new 表示 → 言語 / Language menu (applied after restart). Source
strings remain Japanese; the English catalog lives ini18n/spindle_en.ts
(refresh with theupdate_translationsCMake target, compiled into the
binary by lrelease at build time).
0.6.6
[0.6.6] - 2026-07-19
Fixed
- Facing pages meet cleanly at the spine. Each page of a spread now
edge-aligns toward the center instead of centering in its own half, the 2px
seam between the two views is gone, and the page-fit measurement no longer
loses the width of the pre-fit scrollbar — which had left a theme-colored
strip at the spine. - Page turns can no longer leave pages unscaled. Navigating quickly could
occasionally skip the reader-script injection, showing the raw page at
natural size with scrollbars. The injected-script collections are now only
rewritten when their content actually changes, and every finished load
verifies the fixed-layout fit, re-injecting the script if it never ran. - Backward navigation keeps the established spread pairing. Spread pairs
are anchored at the front of the book, so stepping back from a lone final
page rejoins the canonical pairs instead of shifting every spread by one. - Arrow keys follow the reading direction on fixed-layout pages. In
right-bound books ← advances and → goes back, matching the edge-click
mapping.
0.6.5
[0.6.5] - 2026-07-18
Changed
- The selection-translation popup closes on any click outside it. Clicks
landing on the reading view (a native child window invisible to the popup's
mouse grab) previously left the popup open; only clicking outside the app
window or pressing Escape dismissed it.
Fixed
- Selection translation works in fixed-layout books. The facing-page
spread view was created after the web channel was wired up, so selections on
the companion page could never reach the app — no menu appeared. The
companion page now connects to the bridge; selecting text there opens the
text-action menu (翻訳 / 要約 / コピー / Web で検索). Highlight colors and
notes are offered only on the primary page, where the selection can be
anchored to the current chapter.
0.6.3
[0.6.3] - 2026-07-18
Added
- Fixed-layout EPUBs can be read as facing-page spreads. The new
表示 → 固定レイアウトを見開き表示 option is enabled by default and honors
the book's left/right page-progression direction pluspage-spread-*
placement metadata. Clicking the outer 15% of either page also turns the
spread in the corresponding physical direction. The first spine page is
always treated as a cover and shown alone. Binding direction can be set to
automatic, right-bound, or left-bound; automatic uses right binding for
vertical writing and otherwise follows the EPUB.
Fixed
- Fixed-layout arrow navigation turns the page on the first key press.
Left/Right are intercepted before Chromium can use the first press to
horizontally scroll an oversized page. The complete fixed page is fitted to
the reading pane while retaining its authored aspect ratio. Books that omit
rendition:layoutare also recognized when every spine document is exactly
one image page with no surrounding text. - Single-image chapters now always open fitted to the reading pane. The
source image's aspect ratio determines whether its width or height meets the
window edge, independently of the retained text zoom. Image zoom and mouse
drag panning now use the image's actual bounds, avoiding scrollable empty
space on the non-overflowing axis. - Book-search results now jump to the selected occurrence. Repeated matches
in the same chapter use their stored text offsets instead of always opening
Chromium's first match. Pressing Enter in the search field opens the first
result immediately.
0.6.2
[0.6.2] - 2026-07-15
Added
- Configurable line wrapping. 表示 > 折り返し設定… can keep text fitted to
the window or limit each line to a chosen 10–120 character measure (initially
40). The setting is saved across launches and also works with vertical writing.
0.6.1
[0.6.1] - 2026-07-14
Fixed
- Glossary extraction no longer times out when a model keeps generating
malformed JSON. Responses now use a strict schema and a bounded output
length, so a runaway model cannot occupy Ollama until the five-minute
request timeout.
0.6.0
[0.6.0] - 2026-07-14
Added
- Glossary generation (用語集を生成). 翻訳 > 用語集を生成… extracts proper
nouns and recurring terms from the current chapter or the whole book with
Ollama (JSON-forced output, summary model) and writes their target-language
wordings into<book>.glossary.json, merging with any existing entries
(existing ones win). Extracted terms are kept only if they actually occur in
the scanned text; progress dialog with cancel (cancel keeps the terms found
so far), and the updated glossary applies to translations and summaries
immediately.
0.5.2
[0.5.2] - 2026-07-12
Added
- Audio-file export (章を音声ファイルへ書き出し). The 読み上げ menu can
render the current chapter to a single audio file using the same voices and
原文/訳文 rule as playback, with a progress dialog and cancel. Blocks
synthesized by different engines/sample rates (VOICEVOX 24 kHz, Piper
22.05 kHz, OS voices) are resampled into one stream with a 300 ms pause
between paragraphs. OS voices are used via QTextToSpeech's synthesize
capability where the engine supports it; VOICEVOX and Piper always support
export. WAV (16-bit mono) is written directly; MP3 / M4A are encoded
through ffmpeg (auto-detected on PATH, or set 読み上げ > 音声設定 >
ffmpeg) — MP3 at ~130 kbps VBR (-q:a 4), M4A as 96 kbps AAC.
[0.5.1] - 2026-07-12
Added
- Local AI voices for read-aloud: VOICEVOX and Piper. Besides the OS
voices, the voice pickers list the speakers of a running
VOICEVOX server (VOICEVOX: 四国めたん (ノーマル), Japanese) and the.onnxvoice models of a local
Piper install (Piper: en_US-lessac-medium, multi-language). Picking a prefixed voice routes that
language to that engine — so e.g. Japanese can be spoken by VOICEVOX while
English in the same book falls back to an OS voice. The VOICEVOX endpoint
(defaulthttp://localhost:50021) and the Piper executable / voices folder
are set in 読み上げ > 音声設定. Speech rate maps to VOICEVOXspeedScale/
Piper--length_scale; synthesized audio plays through Qt Multimedia (the
engines are built only when that module is present).
[0.5.0] - 2026-07-12
Added
- Read-aloud (読み上げ). The current chapter can be spoken block by block
with the OS speech voices (Qt TextToSpeech; WinRT/SAPI on Windows,
AVSpeechSynthesizer on macOS, speech-dispatcher on Linux). Reading follows
the translation display mode — 原文 and 対訳 read the source text, 訳文
reads the translation (falling back to the source where none is cached
yet) — with the voice matched to the spoken language. The spoken paragraph
is tinted and auto-scrolled into view,
<ruby>text is spoken as its<rt>reading instead of base + furigana
concatenated, reading starts from the paragraph currently on screen, and the
chapter end can auto-advance into the next chapter (読み上げ menu toggle).
Speech rate and a per-language voice are configurable in 読み上げ > 音声設定;
play/pause/stop live on the toolbar and in the new 読み上げ menu
(Ctrl+Shift+S toggles). Builds without Qt TextToSpeech still compile, with
the actions reporting that no speech engine is available.
0.4.5
[0.4.5] - 2026-07-12
Added
- Bare-text chapters are now translatable. Some EPUBs (often converted
ones, e.g. Aozora/Gutenberg conversions) carry chapter prose as bare text
directly inside<div>/<body>, separated by<br/><br/>instead of
<p>elements. Such text had no block structure, so translation,
highlighting, search jumps, and Kindle-note matching only saw the headings.
Chapters are now normalized on load: each run of bare inline text becomes a
synthetic paragraph (split at 2+ consecutive<br>, spacing preserved),
consistently across the reading view, sidecar caches, and translated-EPUB
export. - Wrong-language translations are caught. When the model answers in a
language whose script clearly doesn't match the target (e.g. Chinese
returned for a Japanese target), the request is retried once with a
stronger instruction; if it still doesn't comply the paragraph shows an
error instead of caching the wrong text.
Fixed
- Chinese ⇄ Japanese translation reliability. The translation prompt
told the model to return text "already in the target language" unchanged,
which made kanji-heavy Japanese pass through untranslated with a Chinese
target (and vice versa) — and the untranslated result was then cached.
The prompt now states the task in the user turn in a form that
translation-tuned models (e.g. TranslateGemma) also follow, and no longer
offers the pass-through escape hatch. - Reasoning models' chain of thought leaked into translations. Content
ending with a</think>marker (e.g. Qwen3 with thinking nominally
disabled) now has everything before the marker stripped.