Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-2868] fix: Handle Hyper Mode toggling better. #6214

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions web/core/local-db/storage.sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ export class Storage {
this.workspaceSlug = "";
};

clearStorage = async () => {
clearStorage = async (force = false) => {
try {
await this.db.close();
await clearOPFS();
await this.db?.close();
await clearOPFS(force);
this.reset();
} catch (e) {
console.error("Error clearing sqlite sync storage", e);
Expand Down
10 changes: 5 additions & 5 deletions web/core/local-db/utils/load-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const syncLabels = async (currentLabels: any) => {
const currentIdList = currentLabels.map((label: any) => label.id);
const existingLabels = await persistence.db.exec("SELECT id FROM labels;");

const existingIdList = existingLabels.map((label: any) => label.id);
const existingIdList = existingLabels ? existingLabels.map((label: any) => label.id) : [];

const deletedIds = difference(existingIdList, currentIdList);

Expand Down Expand Up @@ -140,7 +140,7 @@ export const syncIssuesWithDeletedLabels = async (deletedLabelIds: string[]) =>
const syncModules = async (currentModules: any) => {
const currentIdList = currentModules.map((module: any) => module.id);
const existingModules = await persistence.db.exec("SELECT id FROM modules;");
const existingIdList = existingModules.map((module: any) => module.id);
const existingIdList = existingModules ? existingModules.map((module: any) => module.id) : [];
const deletedIds = difference(existingIdList, currentIdList);
await syncIssuesWithDeletedModules(deletedIds as string[]);
};
Expand All @@ -167,7 +167,7 @@ export const syncIssuesWithDeletedModules = async (deletedModuleIds: string[]) =
const syncCycles = async (currentCycles: any) => {
const currentIdList = currentCycles.map((cycle: any) => cycle.id);
const existingCycles = await persistence.db.exec("SELECT id FROM cycles;");
const existingIdList = existingCycles.map((cycle: any) => cycle.id);
const existingIdList = existingCycles ? existingCycles.map((cycle: any) => cycle.id) : [];
const deletedIds = difference(existingIdList, currentIdList);
await syncIssuesWithDeletedCycles(deletedIds as string[]);
};
Expand All @@ -194,7 +194,7 @@ export const syncIssuesWithDeletedCycles = async (deletedCycleIds: string[]) =>
const syncStates = async (currentStates: any) => {
const currentIdList = currentStates.map((state: any) => state.id);
const existingStates = await persistence.db.exec("SELECT id FROM states;");
const existingIdList = existingStates.map((state: any) => state.id);
const existingIdList = existingStates ? existingStates.map((state: any) => state.id) : [];
const deletedIds = difference(existingIdList, currentIdList);
await syncIssuesWithDeletedStates(deletedIds as string[]);
};
Expand All @@ -221,7 +221,7 @@ export const syncIssuesWithDeletedStates = async (deletedStateIds: string[]) =>
const syncMembers = async (currentMembers: any) => {
const currentIdList = currentMembers.map((member: any) => member.id);
const existingMembers = await persistence.db.exec("SELECT id FROM members;");
const existingIdList = existingMembers.map((member: any) => member.id);
const existingIdList = existingMembers ? existingMembers.map((member: any) => member.id) : [];
const deletedIds = difference(existingIdList, currentIdList);
await syncIssuesWithDeletedMembers(deletedIds as string[]);
};
Expand Down
52 changes: 38 additions & 14 deletions web/core/local-db/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,24 +160,48 @@ const parseSQLite3Error = (error: any) => {
return error;
};

export const clearOPFS = async () => {
const storageManager = window.navigator.storage;
const fileSystemDirectoryHandle = await storageManager.getDirectory();
export const isChrome = () => {
const userAgent = navigator.userAgent;
const isChrome = userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR");
return userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR");
};
Comment on lines +163 to +166
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using feature detection instead of user agent sniffing.

Browser detection through user agent strings is unreliable as they can be spoofed. Consider using feature detection instead.

-export const isChrome = () => {
-  const userAgent = navigator.userAgent;
-  return userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR");
-};
+export const isChrome = () => {
+  // Feature detection for Chrome-specific features
+  return !!(window.chrome && window.chrome.webstore === undefined && window.chrome.runtime);
+};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const isChrome = () => {
const userAgent = navigator.userAgent;
const isChrome = userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR");
return userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR");
};
export const isChrome = () => {
// Feature detection for Chrome-specific features
return !!(window.chrome && window.chrome.webstore === undefined && window.chrome.runtime);
};


export const clearOPFS = async (force = false) => {
const storageManager = window.navigator.storage;
const root = await storageManager.getDirectory();

if (isChrome) {
await (fileSystemDirectoryHandle as any).remove({ recursive: true });
if (force && isChrome()) {
await (root as any).remove({ recursive: true });
return;
}

const entries = await (fileSystemDirectoryHandle as any).entries();
for await (const entry of entries) {
const [name] = entry;
try {
await fileSystemDirectoryHandle.removeEntry(name);
} catch (e) {
console.log("Error", e);
// ts-ignore
for await (const entry of root.values()) {
if (entry.kind === "directory" && entry.name.startsWith(".ahp-")) {
// A lock with the same name as the directory protects it from
// being deleted.

if (force) {
// don't wait for the lock
try {
await root.removeEntry(entry.name, { recursive: true });
} catch (e) {
console.log(e);
}
} else {
await navigator.locks.request(entry.name, { ifAvailable: true }, async (lock) => {
if (lock) {
log?.(`Deleting temporary directory ${entry.name}`);
try {
await root.removeEntry(entry.name, { recursive: true });
} catch (e) {
console.log(e);
}
} else {
log?.(`Temporary directory ${entry.name} is in use`);
}
});
}
} else {
root.removeEntry(entry.name);
}
}
};
2 changes: 1 addition & 1 deletion web/core/store/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ export class UserStore implements IUserStore {
*/
signOut = async (): Promise<void> => {
await this.authService.signOut(API_BASE_URL);
await persistence.clearStorage();
await persistence.clearStorage(true);
this.store.resetOnSignOut();
};

Expand Down
Loading