From e8dbab99ebf28f0f0dbf4414cd69c55441a94c81 Mon Sep 17 00:00:00 2001 From: Peer Richelsen Date: Wed, 27 Aug 2025 11:21:37 +0200 Subject: [PATCH] feat: replace window.todesktop with official @todesktop/client-core package (#23354) * feat: replace window.todesktop with official @todesktop/client-core package - Import platform from @todesktop/client-core in _document.tsx - Pass isDesktopApp result via window.calIsDesktopApp to stringified function - Update applyToDesktopClass to use passed-in value instead of window.todesktop - Maintains existing architecture while using official package API Co-Authored-By: peer@cal.com * fix: move ToDesktop detection to client-side to resolve SSR issue - Remove server-side call to platform.todesktop.isDesktopApp() which always returns false - Move detection logic to client-side stringified script using same logic as official package - Maintain client-side detection while ensuring proper functionality in ToDesktop environment Co-Authored-By: peer@cal.com * feat: use official platform.todesktop.isDesktopApp() function - Import platform from @todesktop/client-core in _document.tsx - Call platform.todesktop.isDesktopApp() directly in stringified script - Replace duplicated logic with official package function call - Maintain client-side detection while using official API Co-Authored-By: peer@cal.com * feat: properly use official platform.todesktop.isDesktopApp() function - Call platform.todesktop.isDesktopApp() outside stringified context - Pass result as template variable to avoid SSR issues - Now actually uses the official @todesktop/client-core package - Eliminates duplicated detection logic as requested Co-Authored-By: peer@cal.com * fix: add SSR safety guards around platform.todesktop.isDesktopApp() call - Wrap platform.todesktop.isDesktopApp() in try/catch to prevent SSR crashes - Return false as fallback if library touches browser globals during SSR - Addresses keithwillcode's comment about SSR safety concerns Co-Authored-By: peer@cal.com --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- apps/web/package.json | 1 + apps/web/pages/_applyThemeForDocument.ts | 2 +- apps/web/pages/_document.tsx | 10 ++++ yarn.lock | 63 ++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/apps/web/package.json b/apps/web/package.json index a0206a14d3..4ee0317da4 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -76,6 +76,7 @@ "@stripe/stripe-js": "^1.35.0", "@tanstack/react-query": "^5.17.15", "@team-plain/typescript-sdk": "^5.9.0", + "@todesktop/client-core": "^1.20.0", "@types/turndown": "^5.0.1", "@upstash/redis": "^1.35.2", "@vercel/edge-config": "^0.1.1", diff --git a/apps/web/pages/_applyThemeForDocument.ts b/apps/web/pages/_applyThemeForDocument.ts index 35d9d288c4..4e09b44984 100644 --- a/apps/web/pages/_applyThemeForDocument.ts +++ b/apps/web/pages/_applyThemeForDocument.ts @@ -62,7 +62,7 @@ export const applyTheme = function () { export const applyToDesktopClass = function () { try { const onReady = () => { - if (typeof window !== "undefined" && window.todesktop && document.documentElement) { + if (typeof window !== "undefined" && window.calIsDesktopApp && document.documentElement) { document.documentElement.classList.add("todesktop"); } else if (document.documentElement) { return; diff --git a/apps/web/pages/_document.tsx b/apps/web/pages/_document.tsx index b11a621a41..f3c40a529f 100644 --- a/apps/web/pages/_document.tsx +++ b/apps/web/pages/_document.tsx @@ -1,3 +1,4 @@ +import { platform } from "@todesktop/client-core"; import type { IncomingMessage } from "http"; import { dir } from "i18next"; import type { DocumentContext, DocumentProps } from "next/document"; @@ -37,6 +38,14 @@ class MyDocument extends Document { const newLocale = this.props.newLocale || "en"; const newDir = dir(newLocale); + const isDesktopApp = (() => { + try { + return platform.todesktop.isDesktopApp(); + } catch { + return false; + } + })(); + return ( { dangerouslySetInnerHTML={{ __html: ` window.calNewLocale = "${newLocale}"; + window.calIsDesktopApp = ${isDesktopApp}; (${applyTheme.toString()})(); (${applyToDesktopClass.toString()})(); `, diff --git a/yarn.lock b/yarn.lock index ef36aed2ac..8f7c5b9816 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4049,6 +4049,7 @@ __metadata: "@tanstack/react-query": ^5.17.15 "@team-plain/typescript-sdk": ^5.9.0 "@testing-library/react": ^13.3.0 + "@todesktop/client-core": ^1.20.0 "@types/accept-language-parser": 1.5.2 "@types/async": ^3.2.15 "@types/bcryptjs": ^2.4.2 @@ -16847,6 +16848,59 @@ __metadata: languageName: node linkType: hard +"@todesktop/client-core@npm:^1.20.0": + version: 1.20.0 + resolution: "@todesktop/client-core@npm:1.20.0" + dependencies: + "@todesktop/client-electron-types": ^28.0.0 + "@todesktop/client-electron-updater-types": ^5.2.3 + "@todesktop/client-todesktop-runtime-types": 1.5.7-beta.2 + "@todesktop/client-util": ^1.4.0 + "@types/node": ^18.11.8 + checksum: ee1ba688266b5f88dc570943cae29254e49316a7068fd465d5d01a07ca6a98b1cbec18870fd1c6a8e0588d827b87f52401f088fefb1ab609206ed1496f47dcf2 + languageName: node + linkType: hard + +"@todesktop/client-electron-types@npm:^28.0.0": + version: 28.0.0 + resolution: "@todesktop/client-electron-types@npm:28.0.0" + checksum: dfbac24ba0bd91c06e68467c6aa8cc173f6ee0a5bb4ce600f2978ac1740b12f78c51b320e91c41c524afd7fd0cd872b70d76a4ff4655fd2deae69478c751862f + languageName: node + linkType: hard + +"@todesktop/client-electron-updater-types@npm:^5.2.3": + version: 5.3.0 + resolution: "@todesktop/client-electron-updater-types@npm:5.3.0" + checksum: cc573d96d7450bcb0b1e3fd3c046fc99ffd994141185104c42527675f8833048488cc1488b6a93bc2c163f8c59a28837378d73dbb91028827e8819c5e9ca0a0a + languageName: node + linkType: hard + +"@todesktop/client-todesktop-runtime-types@npm:1.5.7-beta.2": + version: 1.5.7-beta.2 + resolution: "@todesktop/client-todesktop-runtime-types@npm:1.5.7-beta.2" + checksum: 063144cdb77788938aa64869825f385010d98041267e9bd5d2c2650e59603713c72f94368172080285185d82321c546aae5bbfa9808ab0682eace6c6e9c83837 + languageName: node + linkType: hard + +"@todesktop/client-todesktop-runtime-types@npm:^1.5.7": + version: 1.5.7 + resolution: "@todesktop/client-todesktop-runtime-types@npm:1.5.7" + checksum: 826ad20608bc44d21c4ab20e6c57b5b57c9ac6cc270248652ce33a0741f4a6a8ee1dcfda06e674b51d4e2c1c25fec9bece0b09b0793969ec1407b874605d1cd9 + languageName: node + linkType: hard + +"@todesktop/client-util@npm:^1.4.0": + version: 1.4.0 + resolution: "@todesktop/client-util@npm:1.4.0" + dependencies: + "@todesktop/client-electron-types": ^28.0.0 + "@todesktop/client-electron-updater-types": ^5.2.3 + "@todesktop/client-todesktop-runtime-types": ^1.5.7 + nanoid: ^4.0.2 + checksum: b0e81c3c2477eb382c88b692b9243b1e8674560fc483cbd4dc8ffed08090d559f335440d5d3d0132a2332d6d137514f80a39c52b82e058a6b83ae4dda25f6910 + languageName: node + linkType: hard + "@todesktop/tailwind-variants@npm:^1.0.0": version: 1.0.1 resolution: "@todesktop/tailwind-variants@npm:1.0.1" @@ -35439,6 +35493,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^4.0.2": + version: 4.0.2 + resolution: "nanoid@npm:4.0.2" + bin: + nanoid: bin/nanoid.js + checksum: 747c399cea4664dd0be1d0ec498ffd1ef8f1f5221676fc8b577e3f46f66d9afcddb9595d63d19a2e78d0bc6cc33984f65e66bf1682c850b9e26288883d96b53f + languageName: node + linkType: hard + "napi-build-utils@npm:^2.0.0": version: 2.0.0 resolution: "napi-build-utils@npm:2.0.0"