>;
constructor() {
- if (!runningInBrowser() || !runningInElectron()) {
+ if (!haveWindow() || !isElectron()) {
return;
}
diff --git a/web/apps/photos/src/utils/ui/index.tsx b/web/apps/photos/src/utils/ui/index.tsx
index 1b938fb03..75b0cd23d 100644
--- a/web/apps/photos/src/utils/ui/index.tsx
+++ b/web/apps/photos/src/utils/ui/index.tsx
@@ -1,16 +1,16 @@
-import { DialogBoxAttributes } from "@ente/shared/components/DialogBox/types";
-import AutoAwesomeOutlinedIcon from "@mui/icons-material/AutoAwesomeOutlined";
-import { t } from "i18next";
-import { downloadApp } from "utils/common";
-
import { logoutUser } from "@ente/accounts/services/user";
+import { DialogBoxAttributes } from "@ente/shared/components/DialogBox/types";
import ElectronAPIs from "@ente/shared/electron";
import { AppUpdateInfo } from "@ente/shared/electron/types";
+import AutoAwesomeOutlinedIcon from "@mui/icons-material/AutoAwesomeOutlined";
import InfoOutlined from "@mui/icons-material/InfoRounded";
import { Link } from "@mui/material";
import { OPEN_STREET_MAP_LINK } from "components/Sidebar/EnableMap";
+import { t } from "i18next";
import { Trans } from "react-i18next";
import { Subscription } from "types/billing";
+import { openLink } from "utils/common";
+
export const getDownloadAppMessage = (): DialogBoxAttributes => {
return {
title: t("DOWNLOAD_APP"),
@@ -27,6 +27,8 @@ export const getDownloadAppMessage = (): DialogBoxAttributes => {
};
};
+const downloadApp = () => openLink("https://ente.io/download/desktop", true);
+
export const getTrashFilesMessage = (
deleteFileHelper,
): DialogBoxAttributes => ({
diff --git a/web/apps/photos/src/utils/upload/isCanvasBlocked.ts b/web/apps/photos/src/utils/upload/isCanvasBlocked.ts
deleted file mode 100644
index e9f9b5abe..000000000
--- a/web/apps/photos/src/utils/upload/isCanvasBlocked.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Canvas Blocker &
-// Firefox privacy.resistFingerprinting Detector.
-// (c) 2018 // JOHN OZBAY // CRYPT.EE
-// MIT License
-
-// Credits: https://github.com/johnozbay/canvas-block-detector/blob/master/isCanvasBlocked.js
-
-//
-export function isCanvasBlocked() {
- // create a 1px image data
- let blocked = false;
- const canvas = document.createElement("canvas");
- const ctx = canvas.getContext("2d");
-
- // some blockers just return an undefined ctx. So let's check that first.
- if (ctx) {
- const imageData = ctx.createImageData(1, 1);
- const originalImageData = imageData.data;
-
- // set pixels to RGB 128
- originalImageData[0] = 128;
- originalImageData[1] = 128;
- originalImageData[2] = 128;
- originalImageData[3] = 255;
-
- // set this to canvas
- ctx.putImageData(imageData, 1, 1);
-
- try {
- // now get the data back from canvas.
- const checkData = ctx.getImageData(1, 1, 1, 1).data;
-
- // If this is firefox, and privacy.resistFingerprinting is enabled,
- // OR a browser extension blocking the canvas,
- // This will return RGB all white (255,255,255) instead of the (128,128,128) we put.
-
- // so let's check the R and G to see if they're 255 or 128 (matching what we've initially set)
- if (
- originalImageData[0] !== checkData[0] &&
- originalImageData[1] !== checkData[1]
- ) {
- blocked = true;
- }
- } catch (error) {
- // some extensions will return getImageData null. this is to account for that.
- blocked = true;
- }
- } else {
- blocked = true;
- }
- return blocked;
-}
diff --git a/web/packages/next/env.ts b/web/packages/next/env.ts
index 8e66e7fd9..ea145d892 100644
--- a/web/packages/next/env.ts
+++ b/web/packages/next/env.ts
@@ -10,3 +10,28 @@
* all other commands.
*/
export const isDevBuild = process.env.NODE_ENV === "development";
+
+/**
+ * `true` if we're running in the default global context (aka the main thread)
+ * of a web browser.
+ *
+ * In particular, this is `false` when we're running in a Web Worker,
+ * irrespecitve of whether the worker is running in a Node.js context or a web
+ * browser context.
+ *
+ * > We can be running in a browser context either if the user has the page open
+ * in a web browser, or if we're the renderer process of an Electron app.
+ *
+ * Note that this cannot be a constant, otherwise it'll get inlined during SSR
+ * with the wrong value.
+ */
+export const haveWindow = () => typeof window !== "undefined";
+
+/**
+ * Return true if we are running in a [Web
+ * Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)
+ *
+ * Note that this cannot be a constant, otherwise it'll get inlined during SSR
+ * with the wrong value.
+ */
+export const inWorker = () => typeof importScripts === "function";
diff --git a/web/packages/next/locales/en-US/translation.json b/web/packages/next/locales/en-US/translation.json
index 29469cd0f..5fdb380d5 100644
--- a/web/packages/next/locales/en-US/translation.json
+++ b/web/packages/next/locales/en-US/translation.json
@@ -168,6 +168,7 @@
"UPDATE_PAYMENT_METHOD": "Update payment method",
"MONTHLY": "Monthly",
"YEARLY": "Yearly",
+ "update_subscription_title": "Confirm plan change",
"UPDATE_SUBSCRIPTION_MESSAGE": "Are you sure you want to change your plan?",
"UPDATE_SUBSCRIPTION": "Change plan",
"CANCEL_SUBSCRIPTION": "Cancel subscription",
@@ -421,8 +422,6 @@
"ENTER_TWO_FACTOR_OTP": "Enter the 6-digit code from your authenticator app.",
"CREATE_ACCOUNT": "Create account",
"COPIED": "Copied",
- "CANVAS_BLOCKED_TITLE": "Unable to generate thumbnail",
- "CANVAS_BLOCKED_MESSAGE": "It looks like your browser has disabled access to canvas, which is necessary to generate thumbnails for your photos
Please enable access to your browser's canvas, or check out our desktop app
",
"WATCH_FOLDERS": "Watch folders",
"UPGRADE_NOW": "Upgrade now",
"RENEW_NOW": "Renew now",
diff --git a/web/packages/next/package.json b/web/packages/next/package.json
index f0bbe8544..f5a325f14 100644
--- a/web/packages/next/package.json
+++ b/web/packages/next/package.json
@@ -10,6 +10,7 @@
"get-user-locale": "^2.3",
"i18next": "^23.10",
"i18next-resources-to-backend": "^1.2.0",
+ "is-electron": "^2.2",
"next": "^14.1",
"react": "^18",
"react-dom": "^18",
diff --git a/web/packages/next/tsconfig.json b/web/packages/next/tsconfig.json
index f29c34811..10fe5229c 100644
--- a/web/packages/next/tsconfig.json
+++ b/web/packages/next/tsconfig.json
@@ -1,5 +1,9 @@
{
"extends": "@/build-config/tsconfig-typecheck.json",
+ "compilerOptions": {
+ /* Also indicate expectation of a WebWorker runtime */
+ "lib": ["ESnext", "DOM", "DOM.Iterable", "WebWorker"]
+ },
/* Typecheck all files with the given extensions (here or in subfolders) */
"include": ["**/*.ts", "**/*.tsx"]
}
diff --git a/web/packages/shared/constants/urls.ts b/web/packages/shared/constants/urls.ts
index 747e1fa22..89d5faa16 100644
--- a/web/packages/shared/constants/urls.ts
+++ b/web/packages/shared/constants/urls.ts
@@ -1,21 +1,5 @@
export const ENTE_WEBSITE_LINK = "https://ente.io";
-export const ML_BLOG_LINK = "https://ente.io/blog/desktop-ml-beta";
-
-export const FACE_SEARCH_PRIVACY_POLICY_LINK =
- "https://ente.io/privacy#8-biometric-information-privacy-policy";
-
export const SUPPORT_EMAIL = "support@ente.io";
-export const APP_DOWNLOAD_URL = "https://ente.io/download/desktop";
-
-export const FEEDBACK_EMAIL = "feedback@ente.io";
-
export const DELETE_ACCOUNT_EMAIL = "account-deletion@ente.io";
-
-export const WEB_ROADMAP_URL = "https://github.com/ente-io/ente/discussions";
-
-export const DESKTOP_ROADMAP_URL =
- "https://github.com/ente-io/ente/discussions";
-
-export const CITIES_URL = "https://static.ente.io/world_cities.json";
diff --git a/web/packages/shared/electron/service.ts b/web/packages/shared/electron/service.ts
index 0484b0746..f926d20b2 100644
--- a/web/packages/shared/electron/service.ts
+++ b/web/packages/shared/electron/service.ts
@@ -1,4 +1,4 @@
-import { runningInWorker } from "@ente/shared/platform";
+import { inWorker } from "@/next/env";
import * as Comlink from "comlink";
import { wrap } from "comlink";
import { ElectronAPIsType } from "./types";
@@ -17,7 +17,7 @@ class WorkerSafeElectronServiceImpl implements LimitedElectronAPIs {
this.ready = this.init();
}
private async init() {
- if (runningInWorker()) {
+ if (inWorker()) {
const workerSafeElectronClient =
wrap(self);
diff --git a/web/packages/shared/error/index.ts b/web/packages/shared/error/index.ts
index 3d3309379..6ed4c7486 100644
--- a/web/packages/shared/error/index.ts
+++ b/web/packages/shared/error/index.ts
@@ -70,7 +70,6 @@ export const CustomError = {
EXPORT_STOPPED: "export stopped",
NO_EXPORT_FOLDER_SELECTED: "no export folder selected",
EXPORT_FOLDER_DOES_NOT_EXIST: "export folder does not exist",
- NO_INTERNET_CONNECTION: "no internet connection",
AUTH_KEY_NOT_FOUND: "auth key not found",
EXIF_DATA_NOT_FOUND: "exif data not found",
SELECT_FOLDER_ABORTED: "select folder aborted",
diff --git a/web/packages/shared/platform/index.ts b/web/packages/shared/platform/index.ts
deleted file mode 100644
index a7a63dd6f..000000000
--- a/web/packages/shared/platform/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import isElectron from "is-electron";
-
-export function runningInBrowser() {
- return typeof window !== "undefined";
-}
-
-export function runningInWorker() {
- return typeof importScripts === "function";
-}
-
-export function runningInElectron() {
- return isElectron();
-}
diff --git a/web/packages/shared/storage/localForage/index.ts b/web/packages/shared/storage/localForage/index.ts
index 9ddf80d99..a3bb4442d 100644
--- a/web/packages/shared/storage/localForage/index.ts
+++ b/web/packages/shared/storage/localForage/index.ts
@@ -1,8 +1,8 @@
-import { runningInBrowser } from "../../platform";
+import { haveWindow } from "@/next/env";
import localForage from "localforage";
-if (runningInBrowser()) {
+if (haveWindow()) {
localForage.config({
name: "ente-files",
version: 1.0,
diff --git a/web/packages/utils/package.json b/web/packages/utils/package.json
index bfe78b5f7..930e3aa44 100644
--- a/web/packages/utils/package.json
+++ b/web/packages/utils/package.json
@@ -3,7 +3,6 @@
"version": "0.0.0",
"private": true,
"dependencies": {
- "is-electron": "^2.2",
"libsodium-wrappers": "0.7.9",
"yup": "^1.4"
},