diff --git a/app/config.sh b/app/config.sh
index a9bbcff93f..43ecdc3f0b 100644
--- a/app/config.sh
+++ b/app/config.sh
@@ -45,8 +45,7 @@ S3_CI_ZIP_PATH="ci/client"
S3_DIST_PATH="client"
DEPLOY_HOST="deploy.zotero"
-DEPLOY_PATH="www/www-production/public/download/client/manifests"
-DEPLOY_CMD="ssh $DEPLOY_HOST update-site-files"
+DEPLOY_PATH="www/www-production/public/download/client"
BUILD_PLATFORMS=""
NUM_INCREMENTALS=6
diff --git a/app/scripts/8.0_release_build_and_deploy b/app/scripts/8.0_release_build_and_deploy
index dde18615c9..3f18495ce0 100755
--- a/app/scripts/8.0_release_build_and_deploy
+++ b/app/scripts/8.0_release_build_and_deploy
@@ -8,10 +8,20 @@ ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
CHANNEL="release"
BRANCH="8.0"
+BUILD_ONLY=0
if [ "`uname`" = "Darwin" ]; then
export SAFARI_APPEX="$ROOT_DIR/../safari-app-extension-builds/release/ZoteroSafariExtension.appex"
fi
+while getopts "b" opt; do
+ case $opt in
+ b)
+ BUILD_ONLY=1
+ ;;
+ esac
+ shift $((OPTIND-1)); OPTIND=1
+done
+
cd "$SCRIPT_DIR"
./check_requirements
@@ -26,4 +36,14 @@ function cleanup {
trap cleanup EXIT
./prepare_build -s "$source_dir" -o "$build_dir" -c $CHANNEL -m $hash
-./build_and_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL
+VERSION="`cat \"$build_dir/version\"`"
+./build_for_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL
+
+if [ $BUILD_ONLY -eq 1 ]; then
+ echo
+ echo "Build only -- skipping deploy."
+ echo "To deploy, run on the deploy server:"
+ echo " $DEPLOY_PATH/deploy $CHANNEL $VERSION $BUILD_PLATFORMS"
+else
+ ssh $DEPLOY_HOST "$DEPLOY_PATH/deploy" $CHANNEL "$VERSION" $BUILD_PLATFORMS
+fi
diff --git a/app/scripts/9.0_release_build_and_deploy b/app/scripts/9.0_release_build_and_deploy
new file mode 100755
index 0000000000..72c7b0db09
--- /dev/null
+++ b/app/scripts/9.0_release_build_and_deploy
@@ -0,0 +1,49 @@
+#!/bin/bash
+set -euo pipefail
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+APP_ROOT_DIR="$(dirname "$SCRIPT_DIR")"
+ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
+. "$APP_ROOT_DIR/config.sh"
+
+CHANNEL="release"
+BRANCH="9.0"
+BUILD_ONLY=0
+if [ "`uname`" = "Darwin" ]; then
+ export SAFARI_APPEX="$ROOT_DIR/../safari-app-extension-builds/release/ZoteroSafariExtension.appex"
+fi
+
+while getopts "b" opt; do
+ case $opt in
+ b)
+ BUILD_ONLY=1
+ ;;
+ esac
+ shift $((OPTIND-1)); OPTIND=1
+done
+
+cd "$SCRIPT_DIR"
+./check_requirements
+
+hash=`./get_repo_branch_hash $BRANCH`
+source_dir=`./get_commit_files $hash`
+build_dir=`mktemp -d`
+
+function cleanup {
+ rm -rf "$source_dir"
+ rm -rf "$build_dir"
+}
+trap cleanup EXIT
+
+./prepare_build -s "$source_dir" -o "$build_dir" -c $CHANNEL -m $hash
+VERSION="`cat \"$build_dir/version\"`"
+./build_for_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL
+
+if [ $BUILD_ONLY -eq 1 ]; then
+ echo
+ echo "Build only -- skipping deploy."
+ echo "To deploy, run on the deploy server:"
+ echo " $DEPLOY_PATH/deploy $CHANNEL $VERSION $BUILD_PLATFORMS"
+else
+ ssh $DEPLOY_HOST "$DEPLOY_PATH/deploy" $CHANNEL "$VERSION" $BUILD_PLATFORMS
+fi
diff --git a/app/scripts/beta_build_and_deploy b/app/scripts/beta_build_and_deploy
index 079d67fe79..92676beeee 100755
--- a/app/scripts/beta_build_and_deploy
+++ b/app/scripts/beta_build_and_deploy
@@ -27,4 +27,6 @@ function cleanup {
trap cleanup EXIT
./prepare_build -s "$source_dir" -o "$build_dir" -c $CHANNEL -m $hash
-./build_and_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL
+VERSION="`cat \"$build_dir/version\"`"
+./build_for_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL
+ssh $DEPLOY_HOST "$DEPLOY_PATH/deploy" $CHANNEL "$VERSION" $BUILD_PLATFORMS
diff --git a/app/scripts/build_and_deploy b/app/scripts/build_for_deploy
similarity index 79%
rename from app/scripts/build_and_deploy
rename to app/scripts/build_for_deploy
index e5bf235fb5..f61591f0cc 100755
--- a/app/scripts/build_and_deploy
+++ b/app/scripts/build_for_deploy
@@ -1,6 +1,7 @@
#!/bin/bash
#
-# Builds and deploys Zotero with full and incremental updates
+# Builds Zotero and uploads to S3 and deploy server, but does not make the build live.
+# To make the build live, run the deploy script on the deploy server (or via SSH).
#
set -euo pipefail
@@ -107,13 +108,23 @@ do
usage
;;
esac
-
+
echo
echo "Getting $platform_name incrementals"
INCREMENTALS="`\"$SCRIPT_DIR/manage_incrementals\" -c $CHANNEL -p ${PLATFORMS:i:1} -n $NUM_INCREMENTALS`"
+
+ # Fetch pinned incrementals from deploy server and merge
+ PINNED_FILE="$DEPLOY_PATH/manifests/$CHANNEL/pinned-incrementals-$platform"
+ PINNED=""
+ if ssh $DEPLOY_HOST "test -f $PINNED_FILE"; then
+ PINNED="`ssh $DEPLOY_HOST cat $PINNED_FILE`"
+ fi
+
+ # Combine and deduplicate
+ INCREMENTALS="`echo -e "$INCREMENTALS\n$PINNED" | sort -u | grep -v '^$'`"
echo "$INCREMENTALS"
echo
-
+
if [ -n "$INCREMENTALS" ]; then
for from in $INCREMENTALS; do
echo "Building incremental update for $platform_name from $from to $VERSION"
@@ -127,7 +138,7 @@ done
"$SCRIPT_DIR/upload_builds" $CHANNEL $VERSION
# Upload file lists and build info for each platform
-channel_deploy_path="$DEPLOY_PATH/$CHANNEL"
+channel_deploy_path="$DEPLOY_PATH/manifests/$CHANNEL"
mkdir "$TEMP_DIR/version_info"
chmod g+ws "$TEMP_DIR/version_info"
cp "$DIST_DIR"/files-* "$TEMP_DIR/version_info"
@@ -148,38 +159,9 @@ do
done
rsync -rv "$TEMP_DIR/version_info/" $DEPLOY_HOST:"$channel_deploy_path/$VERSION/"
-# Download updates JSON for each platform, update it, and reupload it
-for i in `seq 0 1 $((${#PLATFORMS}-1))`
-do
- case ${PLATFORMS:i:1} in
- m)
- architectures="mac"
- ;;
- w)
- architectures="win32 win-x64 win-arm64"
- ;;
- l)
- architectures="linux-i686 linux-x86_64 linux-arm64"
- ;;
- esac
-
- for arch in $architectures;
- do
- jsonfile="updates-$arch.json"
-
- scp $DEPLOY_HOST:"$channel_deploy_path/$jsonfile" "$TEMP_DIR/$jsonfile"
- "$SCRIPT_DIR/add_version_info" -f "$TEMP_DIR/$jsonfile" -v $VERSION -b $BUILD_ID
- scp "$TEMP_DIR/$jsonfile" $DEPLOY_HOST:"$channel_deploy_path/$jsonfile"
- done
-done
-
-# Add version to incremental lists
-echo
-for i in `seq 0 1 $((${#PLATFORMS}-1))`
-do
- "$SCRIPT_DIR/manage_incrementals" -c $CHANNEL -p ${PLATFORMS:i:1} -a $VERSION
-done
-
-$DEPLOY_CMD
-
rm -rf "$STAGE_DIR"/*
+
+echo
+echo "Build $VERSION uploaded successfully."
+echo "To deploy, run on the deploy server:"
+echo " ./deploy $CHANNEL $VERSION $PLATFORMS"
diff --git a/app/scripts/dev_build_and_deploy b/app/scripts/dev_build_and_deploy
index 7e9cca3006..0bc3cc01cd 100755
--- a/app/scripts/dev_build_and_deploy
+++ b/app/scripts/dev_build_and_deploy
@@ -24,4 +24,6 @@ function cleanup {
trap cleanup EXIT
./prepare_build -s "$source_dir" -o "$build_dir" -c $CHANNEL -m $hash
-./build_and_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL -i 1
+VERSION="`cat \"$build_dir/version\"`"
+./build_for_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL -i 1
+ssh $DEPLOY_HOST "$DEPLOY_PATH/deploy" $CHANNEL "$VERSION" $BUILD_PLATFORMS
diff --git a/app/scripts/manage_incrementals b/app/scripts/manage_incrementals
index a01382dfb9..0517c96a52 100755
--- a/app/scripts/manage_incrementals
+++ b/app/scripts/manage_incrementals
@@ -64,22 +64,19 @@ if [[ "$VERSION" ]] && [[ "$NUM_VERSIONS" ]]; then
usage
fi
-INCR_FILENAME="incrementals-$CHANNEL-$PLATFORM"
-S3_URL="s3://$S3_BUCKET/$S3_DIST_PATH/$CHANNEL/incrementals-$PLATFORM"
+INCR_FILENAME="incrementals-$PLATFORM"
+REMOTE_PATH="$DEPLOY_PATH/manifests/$CHANNEL/$INCR_FILENAME"
INCR_PATH="$DIST_DIR/$INCR_FILENAME"
-if [ "`uname -o 2> /dev/null`" = "Cygwin" ]; then
- INCR_PATH=$(cygpath -w "$INCR_PATH")
-fi
mkdir -p "$DIST_DIR"
-aws s3 cp $S3_URL "$INCR_PATH" >&2
+scp $DEPLOY_HOST:"$REMOTE_PATH" "$INCR_PATH" >&2
# Add version to file and reupload
if [ "$VERSION" ]; then
echo "Adding $VERSION to incrementals-$PLATFORM"
echo $VERSION >> "$INCR_PATH"
- aws s3 cp "$INCR_PATH" $S3_URL
+ scp "$INCR_PATH" $DEPLOY_HOST:"$REMOTE_PATH"
# Show last n versions
elif [ "$NUM_VERSIONS" -gt 0 ]; then
# TEMP: Don't include 6.0 versions
diff --git a/app/scripts/test_build_and_deploy b/app/scripts/test_build_and_deploy
index a2864e80bb..e2d8b2df11 100755
--- a/app/scripts/test_build_and_deploy
+++ b/app/scripts/test_build_and_deploy
@@ -24,4 +24,6 @@ function cleanup {
trap cleanup EXIT
./prepare_build -s "$source_dir" -o "$build_dir" -c $CHANNEL -m $hash
-./build_and_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL -i 1
+VERSION="`cat \"$build_dir/version\"`"
+./build_for_deploy -d "$build_dir" -p $BUILD_PLATFORMS -c $CHANNEL -i 1
+ssh $DEPLOY_HOST "$DEPLOY_PATH/deploy" $CHANNEL "$VERSION" $BUILD_PLATFORMS
diff --git a/chrome/content/zotero/collectionTree.jsx b/chrome/content/zotero/collectionTree.jsx
index 03c161b0fb..5a264f19c0 100644
--- a/chrome/content/zotero/collectionTree.jsx
+++ b/chrome/content/zotero/collectionTree.jsx
@@ -3022,14 +3022,16 @@ var CollectionTree = class CollectionTree extends LibraryTree {
// Recently Read
if (showRecentlyRead && this._isFilterEmpty()) {
- let s = new Zotero.Search();
- s.libraryID = libraryID;
- s.name = Zotero.getString('recently-read');
- s.addCondition('libraryID', 'is', libraryID);
- s.addCondition('lastRead', 'isInTheLast', '14 days');
- s.addCondition('includeParents', 'true');
rows.splice(row + 1 + newRows, 0,
- new Zotero.CollectionTreeRow(this, 'recentlyRead', s, level + 1));
+ new Zotero.CollectionTreeRow(this,
+ 'recentlyRead',
+ {
+ libraryID,
+ name: Zotero.getString('recently-read'),
+ },
+ level + 1
+ )
+ );
newRows++;
}
diff --git a/chrome/content/zotero/components/virtualized-table.jsx b/chrome/content/zotero/components/virtualized-table.jsx
index 5f833c417c..89a01191cc 100644
--- a/chrome/content/zotero/components/virtualized-table.jsx
+++ b/chrome/content/zotero/components/virtualized-table.jsx
@@ -1066,7 +1066,8 @@ class VirtualizedTable extends React.Component {
}
componentDidUpdate(prevProps) {
- if (this.props.id !== prevProps.id) {
+ if (this.props.id !== prevProps.id
+ || this.props.columns !== prevProps.columns) {
this._columns = new Columns(this);
this.forceUpdate();
}
diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx
index 95ec6b8d87..426fe4a56e 100644
--- a/chrome/content/zotero/itemTree.jsx
+++ b/chrome/content/zotero/itemTree.jsx
@@ -1125,7 +1125,7 @@ var ItemTree = class ItemTree extends LibraryTree {
window.ZoteroPane.loadURI(e.target.dataset.href);
}
if (e.target.dataset.action == 'open-sync-prefs') {
- Zotero.Utilities.Internal.openPreferences('zotero-prefpane-sync');
+ Zotero.Utilities.Internal.openPreferences('zotero-prefpane-account');
}
}}
className={"items-tree-message"}
@@ -1304,7 +1304,7 @@ var ItemTree = class ItemTree extends LibraryTree {
// Clear the quick search and tag selection and try again (once)
if (!noRecurse && window.ZoteroPane) {
let hasQuickSearch = !!this.collectionTreeRow.searchText;
- let hasTagFilters = this.collectionTreeRow.tags.size > 0;
+ let hasTagFilters = this.collectionTreeRow.tags?.size > 0;
if (hasQuickSearch || hasTagFilters) {
// Clear all searches set on the collection tree row directly on
// collectionTreeRow (vs using ZoteroPane functions) to avoid
@@ -3810,11 +3810,15 @@ var ItemTree = class ItemTree extends LibraryTree {
const visibilityGroup = this.collectionTreeRow.visibilityGroup;
const prefKey = this.id;
- if (this._columnsId == prefKey) {
+ // Include group status in cache key so groupLibrariesOnly columns
+ // are recalculated when switching between personal and group libraries
+ let cacheKey = prefKey
+ + (this.collectionTreeRow.isWithinGroup?.() ? '-group' : '');
+ if (this._columnsId == cacheKey) {
return this._columns;
}
-
- this._columnsId = prefKey;
+
+ this._columnsId = cacheKey;
this._columns = [];
let columnsSettings = this._getColumnPrefs();
@@ -3949,7 +3953,7 @@ var ItemTree = class ItemTree extends LibraryTree {
else if (span.hasAttribute('data-action')) {
if (span.getAttribute('data-action') == 'open-sync-prefs') {
span.onclick = () => {
- Zotero.Utilities.Internal.openPreferences('zotero-prefpane-sync');
+ Zotero.Utilities.Internal.openPreferences('zotero-prefpane-account');
};
}
}
diff --git a/chrome/content/zotero/preferences/librariesToSync.xhtml b/chrome/content/zotero/preferences/librariesToSync.xhtml
index f5466c5c8b..0e97de7ab5 100644
--- a/chrome/content/zotero/preferences/librariesToSync.xhtml
+++ b/chrome/content/zotero/preferences/librariesToSync.xhtml
@@ -47,7 +47,7 @@
-
+
diff --git a/chrome/content/zotero/preferences/preferences_sync.jsx b/chrome/content/zotero/preferences/preferences_account.jsx
similarity index 99%
rename from chrome/content/zotero/preferences/preferences_sync.jsx
rename to chrome/content/zotero/preferences/preferences_account.jsx
index 2dc15a58db..0e0119f982 100644
--- a/chrome/content/zotero/preferences/preferences_sync.jsx
+++ b/chrome/content/zotero/preferences/preferences_account.jsx
@@ -89,7 +89,7 @@ Zotero_Preferences.Sync = {
}
});
- document.getElementById('zotero-prefpane-sync').addEventListener('action', () => {
+ document.getElementById('zotero-prefpane-account').addEventListener('action', () => {
this._handlePendingAction();
});
// Auto-trigger login if opened with the 'logIn' action.
@@ -122,15 +122,13 @@ Zotero_Preferences.Sync = {
document.getElementById('sync-unauthorized').hidden = linked;
document.getElementById('account-linked').hidden = !linked;
+ document.getElementById('sync-settings-section').hidden = !loggedIn;
document.getElementById('sync-reset').hidden = !loggedIn;
// Toggle logged-in vs logged-out elements within the linked container
document.getElementById('account-log-out-button').hidden = !loggedIn;
document.querySelector('.account-logged-out-status').hidden = !loggedOutLinked;
document.getElementById('account-logged-out-actions').hidden = !loggedOutLinked;
- for (let elem of document.querySelectorAll('.sync-settings')) {
- elem.hidden = !loggedIn;
- }
let displayUsername = loggedIn ? username : linkedUsername;
document.getElementById('account-username').value = displayUsername;
diff --git a/chrome/content/zotero/preferences/preferences_sync.xhtml b/chrome/content/zotero/preferences/preferences_account.xhtml
similarity index 60%
rename from chrome/content/zotero/preferences/preferences_sync.xhtml
rename to chrome/content/zotero/preferences/preferences_account.xhtml
index 3bf398b625..d39eee40fa 100644
--- a/chrome/content/zotero/preferences/preferences_sync.xhtml
+++ b/chrome/content/zotero/preferences/preferences_account.xhtml
@@ -22,94 +22,16 @@
***** END LICENSE BLOCK *****
-->
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
@@ -119,10 +41,88 @@
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -137,7 +137,7 @@
oncommand="Zotero_Preferences.Sync.onStorageSettingsChange()"
native="true">
-
+
@@ -212,7 +212,7 @@
-
@@ -234,18 +234,15 @@
-
-
-
-
-
+
+
+
-
-
+
- &zotero.preferences.sync.reset;
+