(If deleting a group, don't select the header or separator before it.)
This will appear much less frequently, since non-conflicting field changes on both sides can be resolved automatically, but genuine field conflicts still require manual conflict resolution. The merge pane is no longer editable, since the itembox code to do that is async and can't run in a modal window, but it's not really necessary, particularly with conflicts happening less frequently. TODO: - Remote item deletions - File conflicts - Maybe handle some edge cases where the conflicted items fail to save
I don't think these were triggered by any client code, but I found them while porting code to the server.
There's a lot more to do, and this isn't ready for actual usage, but the basic functionality is mostly in place and has decent test coverage. It can successfully upgrade a library last used with classic syncing and pull down changes via the API. Uploading mostly works but is currently disabled for safety until it has better test coverage. Downloaded JSON is first saved to a cache table, which is then used to populate other tables and later for generating PATCH requests and automatically resolving conflicts (since it shows what was changed locally and what was changed remotely). Objects with unmet dependencies or unknown fields are skipped for now but don't block the rest of the sync. Some of the bigger remaining to-dos: - Tests for uploading - Re-do the preferences to get an API key - File sync integration - Full-text syncing integration - Manual conflict resolution (though this already includes much smarter conflict handling that automatically resolves many conflicts)
And add a bit more debugging info to other messages
And use it in resetDB() test support function, mainly to allow skipBundledFiles for resetDB calls. Translator installation and initialization can take a long time, but tests that need a clean DB don't necessarily rely on translators. Without this, running resetDB() in beforeEach() for many tests is prohibitively slow.
…sync() Instead of a promise-yielding generator
Previously, if .synced was already true, setting it to true and saving would result in .synced == false unless skipSyncedUpdate was passed. Now the value assigned to .synced is always used on the next save. If the value hasn't changed and no other values have changed, a save will be a no-op.
The default items cause problems with conflict resolution for existing users (and not syncing them or ignoring conflicts for them is kind of weird), and they require remote changes for new databases. I do like there not being a completely empty library, but I think it's probably better just to display a virtual welcome message with a link to the Quick Start Guide somewhere else, such as in the right-hand pane. (A new installation also opens the start page on zotero.org.)