Commit graph

1895 commits

Author SHA1 Message Date
Dan Stillman
74a3617e7e Fix full-text indexing failing silently after periodic vacuum or backup
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
vacuum() and the APFS-cloning offline backup path both close and
reopen the SQLite connection, which drops all ATTACHed databases --
including the in-memory "indexing" alias used for the fulltextWords
scratch table set up in Fulltext.init(). Once the connection is
reopened, indexing queries fail with "no such table:
indexing.fulltextWords", and indexItems()'s ignoreErrors path
routes the error to logError(), so indexing silently stops working
for the rest of the session.

Add an onConnect() hook on Zotero.DBConnection for per-connection
state that doesn't persist across reopens, and use it from
Fulltext.init() to re-attach the indexing DB on each reconnect.

Regression sources:

- 67288047f3 ("Use APFS cloning for file copies on macOS") flips
  online idle backups to offline-with-clone on APFS, so every idle
  backup interval (24h default) closes and reopens the connection.
  Affects Mac users on APFS.
- b27c4cb023 ("Enable SQLite WAL mode and add periodic VACUUM
  INTO") adds the vacuum path, which closes and reopens on the
  first idle period in a session that passes the freelist/time
  gates. Affects all users with sufficient DB churn, roughly once
  per 14 days.

https://forums.zotero.org/discussion/131576/debug-id-d848621212-indexing-of-pdfs-fail-zotero-9-0-3
https://forums.zotero.org/discussion/131718/possible-bug-regression-report-search-unusable-on-macos-zotero-9-0-3-with-large-library
(cherry picked from commit 70c4cadab1)
2026-05-22 11:00:03 -04:00
Dan Stillman
841efcb5c6 Don't mark group attachment as unsynced when opened
For group items, attachmentLastRead is stored in a synced setting in My
Library rather than on the item itself, but since we didn't pass
skipSyncedUpdate, the item was being marked as needing sync, resulting
in a permission-denied error in read-only libraries.

https://forums.zotero.org/discussion/131717/opening-pdf-in-read-only-group-library-triggers-permission-denied-on-sync
(cherry picked from commit d2631cc614)
2026-05-21 10:08:07 -04:00
abaevbog
b5517e92c1 citation dlg: sort libraries by cited count (#5925)
In list mode, sort libraries by the count of their items
cited in the current document, falling back to alphabetic sorting
when counts are equal, with "My Library" always getting
priority over other groups.

Fixes: #5924
(cherry picked from commit 8f44172342)
2026-05-21 10:07:52 -04:00
Dan Stillman
3c131037da Close advanced search window in collectionViewItemTree notify() test
The test opened an advanced search window but never closed it, which
likely caused the intermittent failures in the ZoteroPane focus() test
"should shift-tab across the zotero pane".

(cherry picked from commit 504447de41)
2026-05-21 10:06:05 -04:00
Abe Jellinek
de5bc7c5c5 cookieContextId -> userContextId 2026-05-05 09:51:04 -04:00
Abe Jellinek
5ebe8ea15f Add support for clearing challenge in browser during translation 2026-05-05 09:51:03 -04:00
Abe Jellinek
b8611db419 Remove CookieSandbox, add new utility for cookie isolation (#5853) 2026-05-05 09:49:42 -04:00
Abe Jellinek
08d43a512a Replace chai-as-promised assertions in server_connector tests
(cherry picked from commit 03d94060b4)
2026-04-30 12:18:49 -04:00
Abe Jellinek
33e6601a2e Server: Remove /connector/request endpoint
Never used.

(cherry picked from commit 13cb8d99b6)
2026-04-30 12:18:45 -04:00
Abe Jellinek
a50052a055 Server: Test new browser detection behavior
(cherry picked from commit 82b31574a8)
2026-04-30 12:18:42 -04:00
Tom Najdek
2d6268919b Fix tag paste to include existing field text at cursor position (#5873)
(cherry picked from commit 32e43cb8f1)
2026-04-21 12:20:55 -04:00
windingwind
e943914541 Fix removal logic for menu added by MenuManager (#5886)
Add the registered main key to menu class list so that they can be found when plugin is removed.
Add test for the fix.

(cherry picked from commit 55672ba933)
2026-04-21 12:14:04 -04:00
Dan Stillman
f82efc766d Fix Added/Modified By visibility when switching between library types
The `_getColumns()` column cache key didn't account for library type, so
switching between personal and group libraries reused cached columns
from the previous library type. This caused `groupLibrariesOnly` columns
(Added By, Modified By) to be missing in group libraries or incorrectly
shown in personal libraries.

Additionally, `VirtualizedTable.componentDidUpdate()` only recreated its
internal `Columns` object when the id prop changed, not when the columns
prop changed, so even with correct column rebuilding in `ItemTree`, the
table wouldn't pick up the new column list.

https://forums.zotero.org/discussion/130521/added-by-column-missing
2026-04-09 11:29:02 -04:00
Abe Jellinek
4b14ca9af4
Set Recently Read threshold relative to most recent item (#5878)
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
And persist cutoff within session
2026-04-07 14:10:18 -04:00
Dan Stillman
3f0de027a2 Auto-resolve lastRead sync conflicts by picking the most recent value 2026-04-07 10:29:25 -04:00
Dan Stillman
67288047f3 Use APFS cloning for file copies on macOS
Add Zotero.File.copyFile(), which uses clonefile() on APFS with a
fallback to IOUtils.copy(), and use it for all significant file copies.
APFS is detected and cached for each parent folder via
Zotero.File.isAPFS(), which uses statfs().

On APFS, all database backups now use the offline (close/clone/reopen)
path instead of the SQLite online backup API. Cloning is nearly
instant, and backup files share disk blocks via copy-on-write, saving
potentially gigabytes of space.

Closes #5330
2026-04-03 14:33:21 -04:00
Dan Stillman
d5ee350081 Disable snapshot saving in feed item translation itest
To try to fix intermittent CI errors
2026-04-03 09:58:47 -04:00
Dan Stillman
5a347f4be5 Update style test for NLM/Vancouver style changes 2026-04-02 16:11:47 -04:00
abaevbog
c6a95fd5b7
citation dlg: fix CI test breakage (#5870)
- prevent the focus handler from resetting the cached
items in search handler
- wait for search to finish after changing dialog type
in "should not display empty note child rows" test
2026-04-02 11:27:43 -04:00
abaevbog
6f5f221db0
citation dlg: no irrelevant child rows in itemTree (#5863)
Pass filterChildItems to itemTree from citationDialog
to filter out unwanted child rows before adding them
in toggleOpenState.

In annotations mode, do not add child notes and
attachments without annotations
In add-note mode, only keep child notes that have content
2026-04-01 14:05:40 -04:00
Bogdan Abaev
0e7ed13a43 citation dlg: variable min-width for list/library
- Allow different min-width for list vs library layouts.
In library mode, we need at least 1000px to have a functional
itemTree, especially when sidepane is present. But for list
mode, 1000px is very wide, so min-width should be 800px.
Increased min-height of itemTree from 200px to 400px
- When the dialog closes, store the width/height of
the current dialog's layout. Then, when the dialog opens
next time in that layout, set window's width/height based on last saved
params. That way, one can open a citation dialog in list
mode at 800px, then open annotations dialog (always library mode)
at 1000px, and then have the citation dialog in list mode open
again at its intended 800px.
- If one switches from library to list mode, add a smooth
window resizing animation to shrink diagonally from current width
to 800px. If one switches from list to library mode,
window smoothly resizes to 1000px min-width. This is
not applied to linux where win resizing behavior is a bit jumpy.
2026-03-31 14:53:11 -04:00
Tom Najdek
f3ecf285b3
Fix flakiness in "should shift-tab across the zotero pane" test 2026-03-31 01:38:28 +02:00
Tom Najdek
2ad4618efb
Exclude ©, ®, and ™ from emoji detection regex 2026-03-29 17:51:27 +02:00
Abe Jellinek
fb8389d654
Read Aloud: Persist last-read position in synced setting (#5860) 2026-03-27 15:22:02 -04:00
Dan Stillman
391e8497a6 Handle per-object 403 on settings upload and reset to remote version
If the server returns a write report with 403 for admin-only settings,
mark successful settings as synced and reset rejected settings to
their remote values by re-downloading from the server.

Needed for #5862
2026-03-26 15:54:28 -04:00
Dan Stillman
0e8b195c5a Add tests for image annotation placeholder in notes 2026-03-24 12:09:15 -04:00
Dan Stillman
322b764091 Show email addresses in sync settings
Fetch emails from /keys response and login session result, persist them
in the local database, and display them in the sync settings for both
logged-in and logged-out-but-linked states.

Also unify the separate logged-out-linked and logged-in containers into
a single layout that toggles elements based on login state.

Requires dataserver and stream-server changes
2026-03-24 12:09:08 -04:00
Dan Stillman
5ac56ae717 Fix removing from Recently Read in read-only group libraries 2026-03-24 11:51:37 -04:00
Dan Stillman
2522be0c17 Add test for removing group item from Recently Read on settings sync 2026-03-24 11:36:43 -04:00
Dan Stillman
a3909af5ab Clear lastRead in Item#fromJSON() when absent from API response
When the server returns an attachment without lastRead (because it was
cleared), fromJSON was not clearing the local value since it only
processes fields present in the JSON. Add explicit check after field
processing to clear lastRead when absent.
2026-03-24 11:36:43 -04:00
abaevbog
81591eb890
ItemTree: + expands all rows one level at a time (#5797)
On + keypress, expand the rows down one level, instead of
expanding all rows at once. If some rows are expanded
and some are collapsed, expand to the deepest level
currently visible.
E.g. if some regular items are already expanded,
expand only remaining collapsed regular items. If there
is a row with expanded attachments, expand all rows.

On - keypress, collapse the rows up one level to be consistent.

https://forums.zotero.org/discussion/129596/optional-annotations-in-item-list
https://forums.zotero.org/discussion/130365/expand-all-shift-in-zoteros-behavior-changed
2026-03-23 15:25:30 -04:00
Bogdan Abaev
6bec3c817e Citation dialog: allow to insert annotations (#5356) 2026-03-23 15:00:22 -04:00
abaevbog
5823247df9
itembox: fix lost focus on tab from invalid DOI (#5856)
Fix lost focus on tab from DOI field after it is updated
from a valid to an invalid value.

https://github.com/zotero/zotero/pull/5850#discussion_r2976238955
2026-03-23 13:43:23 -04:00
Dan Stillman
fd7cc84f6b Fix quicksearch in Recently Read to match parent items
Add includeParents to the Recently Read search so parent items are
included in the search scope alongside their child attachments.
2026-03-23 11:22:01 -04:00
Abe Jellinek
8af91b0147
Bump lastRead when reader is closed (#5852) 2026-03-21 13:41:54 -04:00
Dan Stillman
ba3c3a506f Add test for preserving synced on lastRead setting download 2026-03-20 17:03:23 -04:00
Dan Stillman
eb3a136ccd Use new batch setting deletion API endpoint
Use DELETE /settings?settingKey=key1,key2 instead of individual DELETE
per key, with batching matching uploadDeletionBatchSize.
2026-03-20 15:43:03 -04:00
Dan Stillman
98d911f6b1 Add "Switch Accounts" flow for logged-out-but-linked state
When a user logs out without removing local data, the sync pane now
shows a third UI state with the linked username, a "Log In" button
(constrained to the same account), and a "Switch Accounts…" button
that shows a hard confirmation dialog requiring the user to type
"remove local data" before proceeding. On confirmation, local data
is reset and the app restarts, reopening the account preferences.
2026-03-20 13:11:52 -04:00
Dan Stillman
35713fefd0 Upload setting deletions during sync
Deleted settings were written to syncDeleteLog but never uploaded. Add
dedicated setting deletion upload in _startUpload() using individual
DELETE requests per setting, since the API doesn't support batch setting
deletion.
2026-03-20 11:25:27 -04:00
Dan Stillman
3ebd26acc0 Fix saving lastRead in read-only library from synced setting
The same skipEditCheck fix from 5dc9705294 but for the synced setting
handler, which updates lastRead when a lastRead setting arrives via
sync for a group attachment.
2026-03-20 11:25:27 -04:00
Dan Stillman
1d31ed2508 Fix sync runner test for updated login error button text 2026-03-19 15:48:16 -04:00
Dan Stillman
1502214b5d Web-based login flow
Replaces the login form with a "Log In" button that creates a dataserver
login session and opens the website for logging in. The client polls for
session completion every few seconds and also watches for a notification
from the streaming server.
2026-03-19 15:07:53 -04:00
Dan Stillman
1fad46f983 Disable OA PDF lookups in feed item translation test
Avoid external network requests during test that may have been a source
of intermittent CI failures.
2026-03-19 11:04:22 -04:00
Dan Stillman
489a46564f
Add "Remove from Recently Read" (#5847)
- Non-force delete clears `lastRead` on all child attachments (with
  prompt), force delete moves to trash (matching collection behavior)
- Re-run search on item modify in Recently Read view so items disappear
  when lastRead is cleared (also handles sync changes)
2026-03-19 10:30:18 -04:00
Dan Stillman
aaed7ddfc0 Add Added By and Modified By columns for group libraries
- Add columns as options in item tree, visible only in group libraries
- Fall back to createdByUserID for Modified By when lastModifiedByUserID
  is not set
- Update lastModifiedByUserID on local saves when dateModified changes
- Fix backfill in _updateGroupItemUsers() to process all batches
- Update formatColumnName() to support Fluent string keys

Closes #233
2026-03-18 23:19:11 -04:00
Abe Jellinek
34039991f8
Track attachment last-read time, add Recently Read virtual collection (#2854)
Track when attachments are last opened or read, storing a `lastRead` Unix timestamp on the attachment. For user library items, `lastRead` syncs as an attachment property in item JSON. For group library items, it syncs via a per-user synced setting (like `lastPageIndex`).

- Add `lastRead` column to `itemAttachments`
- Add `AttachmentReadObserver` to update `lastRead` on file open and page change (throttled to 5 min for page changes)
- Add "Recently Read" virtual collection (items read in last 14 days, sorted by `lastRead` descending)
- Add `lastRead` search condition with date operators
- Add `lastRead` item tree column with new `dependsOnChildren` property for parent item aggregation
- Add `getItemLastRead()` to return max `lastRead` across child attachments

Also:

- Generalize collection tree SCSS to support universal (context-fill) icons alongside themed icons

---------

Co-authored-by: Dan Stillman <dstillman@zotero.org>
2026-03-17 13:52:00 -04:00
Tom Najdek
fa476245fe
Fix "Rename from Parent" button sometimes not appearing (#5835)
After editing the parent item, switching back to the attachment item before the parent item's save completes creates a race condition between the save and the attachment render.

Moved item pane tests related to file renaming to a separate describe() block.
2026-03-11 14:39:37 -04:00
Tom Najdek
518e7d22a0 Fix a flaky test on CI 2026-03-11 14:35:39 -04:00
Tom Najdek
3328557d00 Revert "Temporarily disable attachment-pane tests due to test failures"
This reverts commit 810626e458.
2026-03-11 14:35:39 -04:00
Tom Najdek
259abb15f5 Revert "Temporarily disable attachments-pane tests due to test failures"
This reverts commit 3d09df1419.
2026-03-11 14:35:39 -04:00