mirror of
https://github.com/zen-browser/components.git
synced 2025-07-10 02:35:28 +02:00
feat: Add workspace ordering and changes tracking
This commit introduces workspace ordering and a new mechanism for tracking changes to workspaces. **Changes:** - **Workspace Ordering:** Workspaces can now be ordered using a `position` field. This allows for user-defined ordering of workspaces, improving usability. - **Changes Tracking:** A new `zen_workspaces_changes` table is added to track changes to workspaces. This allows for more efficient sync operations and improved error handling. **Benefits:** - **Improved Workspace Management:** Users can now customize the order of their workspaces. - **More Efficient Sync:** Changes tracking enables faster and more accurate synchronization of workspaces across devices. - **Enhanced Error Handling:** Changes tracking helps to identify and resolve conflicts during sync. **Notes:** - This change requires deleting the zen_workspaces table in places db
This commit is contained in:
parent
1c7bc5c501
commit
0d161326ef
3 changed files with 535 additions and 211 deletions
|
@ -6,6 +6,7 @@ var ZenWorkspacesStorage = {
|
|||
|
||||
async _ensureTable() {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage._ensureTable', async (db) => {
|
||||
// Create the main workspaces table if it doesn't exist
|
||||
await db.execute(`
|
||||
CREATE TABLE IF NOT EXISTS zen_workspaces (
|
||||
id INTEGER PRIMARY KEY,
|
||||
|
@ -14,11 +15,22 @@ var ZenWorkspacesStorage = {
|
|||
icon TEXT,
|
||||
is_default INTEGER NOT NULL DEFAULT 0,
|
||||
container_id INTEGER,
|
||||
position INTEGER NOT NULL DEFAULT 0,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
updated_at INTEGER NOT NULL,
|
||||
used INTEGER NOT NULL DEFAULT 0
|
||||
)
|
||||
`);
|
||||
|
||||
// Create the changes tracking table if it doesn't exist
|
||||
await db.execute(`
|
||||
CREATE TABLE IF NOT EXISTS zen_workspaces_changes (
|
||||
uuid TEXT PRIMARY KEY,
|
||||
timestamp INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
});
|
||||
|
||||
await this._migrateWorkspacesFromJSON();
|
||||
},
|
||||
|
||||
|
@ -46,22 +58,60 @@ var ZenWorkspacesStorage = {
|
|||
await db.execute(`UPDATE zen_workspaces SET is_default = 0 WHERE uuid != :uuid`, { uuid: workspace.uuid });
|
||||
}
|
||||
|
||||
// Then insert or replace the workspace
|
||||
// Get the current maximum position
|
||||
const maxOrderResult = await db.execute(`SELECT MAX("position") as max_position FROM zen_workspaces`);
|
||||
const maxOrder = maxOrderResult[0].getResultByName('max_position') || 0;
|
||||
|
||||
let newOrder;
|
||||
|
||||
if ('position' in workspace && workspace.position !== null && Number.isInteger(workspace.position)) {
|
||||
// If position is provided, check if it's already occupied
|
||||
const occupiedOrderResult = await db.execute(`
|
||||
SELECT uuid FROM zen_workspaces WHERE "position" = :position AND uuid != :uuid
|
||||
`, { position: workspace.position, uuid: workspace.uuid });
|
||||
|
||||
if (occupiedOrderResult.length > 0) {
|
||||
// If the position is occupied, shift the positions of subsequent workspaces
|
||||
await db.execute(`
|
||||
UPDATE zen_workspaces
|
||||
SET "position" = "position" + 1
|
||||
WHERE "position" >= :position AND uuid != :uuid
|
||||
`, { position: workspace.position, uuid: workspace.uuid });
|
||||
}
|
||||
|
||||
newOrder = workspace.position;
|
||||
} else {
|
||||
// If no position is provided, set it to the last position
|
||||
newOrder = maxOrder + 1;
|
||||
}
|
||||
|
||||
// Insert or replace the workspace
|
||||
await db.executeCached(`
|
||||
INSERT OR REPLACE INTO zen_workspaces (
|
||||
uuid, name, icon, is_default, container_id, created_at, updated_at
|
||||
INSERT OR REPLACE INTO zen_workspaces (
|
||||
uuid, name, icon, is_default, container_id, created_at, updated_at, "position"
|
||||
) VALUES (
|
||||
:uuid, :name, :icon, :is_default, :container_id,
|
||||
COALESCE((SELECT created_at FROM zen_workspaces WHERE uuid = :uuid), :now),
|
||||
:now
|
||||
:now,
|
||||
:position
|
||||
)
|
||||
`, {
|
||||
`, {
|
||||
uuid: workspace.uuid,
|
||||
name: workspace.name,
|
||||
icon: workspace.icon || null,
|
||||
is_default: workspace.default ? 1 : 0,
|
||||
container_id: workspace.containerTabId || null,
|
||||
now
|
||||
now,
|
||||
position: newOrder
|
||||
});
|
||||
|
||||
// Record the change in the changes tracking table
|
||||
await db.execute(`
|
||||
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
|
||||
VALUES (:uuid, :timestamp)
|
||||
`, {
|
||||
uuid: workspace.uuid,
|
||||
timestamp: Math.floor(now / 1000) // Unix timestamp in seconds
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -78,6 +128,7 @@ var ZenWorkspacesStorage = {
|
|||
icon: row.getResultByName('icon'),
|
||||
default: !!row.getResultByName('is_default'),
|
||||
containerTabId: row.getResultByName('container_id'),
|
||||
position: row.getResultByName('position'),
|
||||
}));
|
||||
},
|
||||
|
||||
|
@ -89,14 +140,122 @@ var ZenWorkspacesStorage = {
|
|||
`,
|
||||
{ uuid }
|
||||
);
|
||||
|
||||
// Record the removal as a change
|
||||
const now = Date.now();
|
||||
await db.execute(`
|
||||
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
|
||||
VALUES (:uuid, :timestamp)
|
||||
`, {
|
||||
uuid,
|
||||
timestamp: Math.floor(now / 1000)
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async wipeAllWorkspaces() {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.wipeAllWorkspaces', async (db) => {
|
||||
await db.execute(`DELETE FROM zen_workspaces`);
|
||||
await db.execute(`DELETE FROM zen_workspaces_changes`);
|
||||
});
|
||||
},
|
||||
|
||||
async setDefaultWorkspace(uuid) {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.setDefaultWorkspace', async (db) => {
|
||||
await db.executeTransaction(async function () {
|
||||
const now = Date.now();
|
||||
// Unset the default flag for all other workspaces
|
||||
await db.execute(`UPDATE zen_workspaces SET is_default = 0`);
|
||||
// Set the default flag for the specified workspace
|
||||
await db.execute(`UPDATE zen_workspaces SET is_default = 1 WHERE uuid = :uuid`, { uuid });
|
||||
// Record the change for the specified workspace
|
||||
await db.execute(`
|
||||
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
|
||||
VALUES (:uuid, :timestamp)
|
||||
`, {
|
||||
uuid,
|
||||
timestamp: Math.floor(now / 1000)
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async markChanged(uuid) {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.markChanged', async (db) => {
|
||||
const now = Date.now();
|
||||
await db.execute(`
|
||||
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
|
||||
VALUES (:uuid, :timestamp)
|
||||
`, {
|
||||
uuid,
|
||||
timestamp: Math.floor(now / 1000)
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async getChangedIDs() {
|
||||
const db = await PlacesUtils.promiseDBConnection();
|
||||
const rows = await db.execute(`
|
||||
SELECT uuid, timestamp FROM zen_workspaces_changes
|
||||
`);
|
||||
const changes = {};
|
||||
for (const row of rows) {
|
||||
changes[row.getResultByName('uuid')] = row.getResultByName('timestamp');
|
||||
}
|
||||
return changes;
|
||||
},
|
||||
|
||||
async clearChangedIDs() {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.clearChangedIDs', async (db) => {
|
||||
await db.execute(`DELETE FROM zen_workspaces_changes`);
|
||||
});
|
||||
},
|
||||
|
||||
async updateWorkspaceOrder(uuid, newOrder) {
|
||||
await PlacesUtils.withConnectionWrapper('ZenWorkspacesStorage.updateWorkspaceOrder', async (db) => {
|
||||
await db.executeTransaction(async function () {
|
||||
// Get the current position of the workspace
|
||||
const currentOrderResult = await db.execute(`
|
||||
SELECT "position" FROM zen_workspaces WHERE uuid = :uuid
|
||||
`, { uuid });
|
||||
const currentOrder = currentOrderResult[0].getResultByName('position');
|
||||
|
||||
if (currentOrder === newOrder) {
|
||||
return; // No change needed
|
||||
}
|
||||
|
||||
if (newOrder > currentOrder) {
|
||||
// Moving down: decrement position of workspaces between old and new positions
|
||||
await db.execute(`
|
||||
UPDATE zen_workspaces
|
||||
SET "position" = "position" - 1
|
||||
WHERE "position" > :currentOrder AND "position" <= :newOrder
|
||||
`, { currentOrder, newOrder });
|
||||
} else {
|
||||
// Moving up: increment position of workspaces between new and old positions
|
||||
await db.execute(`
|
||||
UPDATE zen_workspaces
|
||||
SET "position" = "position" + 1
|
||||
WHERE "position" >= :newOrder AND "position" < :currentOrder
|
||||
`, { currentOrder, newOrder });
|
||||
}
|
||||
|
||||
// Set the new position for the workspace
|
||||
await db.execute(`
|
||||
UPDATE zen_workspaces
|
||||
SET "position" = :newOrder
|
||||
WHERE uuid = :uuid
|
||||
`, { uuid, newOrder });
|
||||
|
||||
// Mark the workspace as changed
|
||||
const now = Date.now();
|
||||
await db.execute(`
|
||||
INSERT OR REPLACE INTO zen_workspaces_changes (uuid, timestamp)
|
||||
VALUES (:uuid, :timestamp)
|
||||
`, {
|
||||
uuid,
|
||||
timestamp: Math.floor(now / 1000)
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue