mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	refactor(client,server): rebrand to CPU arch warnings
This commit is contained in:
		| @@ -129,7 +129,7 @@ export type CommandMappings = { | ||||
|     openAboutDialog: CommandData; | ||||
|     hideFloatingButtons: {}; | ||||
|     hideLeftPane: CommandData; | ||||
|     showRosettaWarning: CommandData; | ||||
|     showCpuArchWarning: CommandData; | ||||
|     showLeftPane: CommandData; | ||||
|     hoistNote: CommandData & { noteId: string }; | ||||
|     leaveProtectedSession: CommandData; | ||||
|   | ||||
| @@ -1,6 +1,11 @@ | ||||
| import server from "../services/server"; | ||||
| import Component from "./component"; | ||||
|  | ||||
| // TODO: Deduplicate. | ||||
| interface CpuArchResponse { | ||||
|     isCpuArchMismatch: boolean; | ||||
| } | ||||
|  | ||||
| export class StartupChecks extends Component { | ||||
|  | ||||
|     constructor() { | ||||
| @@ -11,10 +16,10 @@ export class StartupChecks extends Component { | ||||
|     async checkRosetta2Warning() { | ||||
|         try { | ||||
|             // Check if running under Rosetta 2 by calling the server | ||||
|             const response = await server.get("system-info/rosetta-check") as { isRunningUnderRosetta2: boolean }; | ||||
|             if (response.isRunningUnderRosetta2) { | ||||
|             const response = await server.get("system-checks") as CpuArchResponse; | ||||
|             if (response.isCpuArchMismatch) { | ||||
|                 // Trigger the Rosetta 2 warning dialog | ||||
|                 this.triggerCommand("showRosettaWarning", {}); | ||||
|                 this.triggerCommand("showCpuArchWarning", {}); | ||||
|             } | ||||
|         } catch (error) { | ||||
|             console.warn("Could not check Rosetta 2 status:", error); | ||||
|   | ||||
| @@ -21,7 +21,7 @@ import ConfirmDialog from "../widgets/dialogs/confirm.js"; | ||||
| import RevisionsDialog from "../widgets/dialogs/revisions.js"; | ||||
| import DeleteNotesDialog from "../widgets/dialogs/delete_notes.js"; | ||||
| import InfoDialog from "../widgets/dialogs/info.js"; | ||||
| import RosettaWarningDialog from "../widgets/dialogs/rosetta_warning.js"; | ||||
| import IncorrectCpuArchDialog from "../widgets/dialogs/incorrect_cpu_arch.js"; | ||||
|  | ||||
| export function applyModals(rootContainer: RootContainer) { | ||||
|     rootContainer | ||||
| @@ -46,5 +46,5 @@ export function applyModals(rootContainer: RootContainer) { | ||||
|         .child(new InfoDialog()) | ||||
|         .child(new ConfirmDialog()) | ||||
|         .child(new PromptDialog()) | ||||
|         .child(new RosettaWarningDialog()) | ||||
|         .child(new IncorrectCpuArchDialog()) | ||||
| } | ||||
|   | ||||
| @@ -1919,7 +1919,7 @@ | ||||
|     "word_wrapping": "Word wrapping", | ||||
|     "color-scheme": "Color scheme" | ||||
|   }, | ||||
|   "rosetta_warning": { | ||||
|   "cpu_arch_warning": { | ||||
|     "title": "Performance Warning: Running Under Rosetta 2", | ||||
|     "message": "TriliumNext is currently running under Rosetta 2 translation, which means you're using the Intel (x64) version on an Apple Silicon Mac.", | ||||
|     "performance_impact": "This will significantly impact performance and battery life.", | ||||
|   | ||||
| @@ -10,31 +10,31 @@ const TPL = /*html*/` | ||||
|             <div class="modal-header text-white"> | ||||
|                 <h4 class="modal-title"> | ||||
|                     <i class="bx bx-error-circle"></i> | ||||
|                     <span>${t("rosetta_warning.title")}</span> | ||||
|                     <span>${t("cpu_arch_warning.title")}</span> | ||||
|                 </h4> | ||||
|                 <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button> | ||||
|             </div> | ||||
|             <div class="modal-body"> | ||||
|                 <div class="alert alert-warning mb-3"> | ||||
|                     <strong>⚠️ ${t("rosetta_warning.performance_impact")}</strong><br> | ||||
|                     ${t("rosetta_warning.message")} | ||||
|                     <strong>⚠️ ${t("cpu_arch_warning.performance_impact")}</strong><br> | ||||
|                     ${t("cpu_arch_warning.message")} | ||||
|                 </div> | ||||
| 
 | ||||
|                 <p class="mb-3"> | ||||
|                     <strong>Recommendation:</strong> ${t("rosetta_warning.recommendation")} | ||||
|                     <strong>Recommendation:</strong> ${t("cpu_arch_warning.recommendation")} | ||||
|                 </p> | ||||
| 
 | ||||
|                 <div class="d-flex justify-content-between align-items-center"> | ||||
|                     <div> | ||||
|                         <button class="download-correct-version-button btn btn-primary btn-lg me-2"> | ||||
|                             <i class="bx bx-download"></i> | ||||
|                             <span>${t("rosetta_warning.download_link")}</span> | ||||
|                             <span>${t("cpu_arch_warning.download_link")}</span> | ||||
|                         </button> | ||||
|                         <button class="continue-anyway-button btn btn-secondary" data-bs-dismiss="modal">${t("rosetta_warning.continue_anyway")}</button> | ||||
|                         <button class="continue-anyway-button btn btn-secondary" data-bs-dismiss="modal">${t("cpu_arch_warning.continue_anyway")}</button> | ||||
|                     </div> | ||||
|                     <div class="form-check"> | ||||
|                         <input class="form-check-input" type="checkbox" id="dontShowAgain"> | ||||
|                         <label class="form-check-label" for="dontShowAgain">${t("rosetta_warning.dont_show_again")}</label> | ||||
|                         <label class="form-check-label" for="dontShowAgain">${t("cpu_arch_warning.dont_show_again")}</label> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
| @@ -45,13 +45,11 @@ const TPL = /*html*/` | ||||
| export default class RosettaWarningDialog extends BasicWidget { | ||||
|     private modal!: Modal; | ||||
|     private $downloadButton!: JQuery<HTMLElement>; | ||||
|     private $continueButton!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.modal = Modal.getOrCreateInstance(this.$widget[0]); | ||||
|         this.$downloadButton = this.$widget.find(".download-correct-version-button"); | ||||
|         this.$continueButton = this.$widget.find(".continue-anyway-button"); | ||||
| 
 | ||||
|         this.$downloadButton.on("click", () => { | ||||
|             // Open the releases page where users can download the correct version
 | ||||
| @@ -69,7 +67,7 @@ export default class RosettaWarningDialog extends BasicWidget { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     showRosettaWarningEvent() { | ||||
|     showCpuArchWarningEvent() { | ||||
|         this.modal.show(); | ||||
|     } | ||||
| } | ||||
| @@ -1,12 +1,39 @@ | ||||
| import { isRunningUnderRosetta2 } from "../../services/utils.js"; | ||||
| import type { Request, Response } from "express"; | ||||
| import { execSync } from "child_process"; | ||||
| import { isMac } from "../../services/utils"; | ||||
|  | ||||
| function rosettaCheck(req: Request, res: Response) { | ||||
| function systemChecks() { | ||||
|     return { | ||||
|         isRunningUnderRosetta2: isRunningUnderRosetta2() | ||||
|         isCpuArchMismatch: isRunningUnderRosetta2() | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     rosettaCheck | ||||
| /** | ||||
|  * Detects if the application is running under Rosetta 2 translation on Apple Silicon. | ||||
|  * This happens when an x64 version of the app is run on an M1/M2/M3 Mac. | ||||
|  * Uses the macOS sysctl.proc_translated to properly detect translation. | ||||
|  * @returns true if running under Rosetta 2, false otherwise | ||||
|  */ | ||||
| export const isRunningUnderRosetta2 = () => { | ||||
|     if (!isMac) return false; | ||||
|  | ||||
|     try { | ||||
|         // Use child_process to check sysctl.proc_translated | ||||
|         // This is the proper way to detect Rosetta 2 translation | ||||
|         const result = execSync("sysctl -n sysctl.proc_translated 2>/dev/null", { | ||||
|             encoding: "utf8", | ||||
|             timeout: 1000 | ||||
|         }).trim(); | ||||
|  | ||||
|         // 1 means the process is being translated by Rosetta 2 | ||||
|         // 0 means native execution | ||||
|         // If the sysctl doesn't exist (on Intel Macs), this will return empty/error | ||||
|         return result === "1"; | ||||
|     } catch (error) { | ||||
|         // If sysctl fails or doesn't exist (Intel Macs), not running under Rosetta 2 | ||||
|         return false; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| export default { | ||||
|     systemChecks | ||||
| }; | ||||
|   | ||||
| @@ -239,7 +239,7 @@ function register(app: express.Application) { | ||||
|     apiRoute(PST, "/api/recent-notes", recentNotesRoute.addRecentNote); | ||||
|     apiRoute(GET, "/api/app-info", appInfoRoute.getAppInfo); | ||||
|     apiRoute(GET, "/api/metrics", metricsRoute.getMetrics); | ||||
|     apiRoute(GET, "/api/system-info/rosetta-check", systemInfoRoute.rosettaCheck); | ||||
|     apiRoute(GET, "/api/system-checks", systemInfoRoute.systemChecks); | ||||
|  | ||||
|     // docker health check | ||||
|     route(GET, "/api/health-check", [], () => ({ status: "ok" }), apiResultHandler); | ||||
|   | ||||
| @@ -23,34 +23,6 @@ export const isElectron = !!process.versions["electron"]; | ||||
|  | ||||
| export const isDev = !!(process.env.TRILIUM_ENV && process.env.TRILIUM_ENV === "dev"); | ||||
|  | ||||
| /** | ||||
|  * Detects if the application is running under Rosetta 2 translation on Apple Silicon. | ||||
|  * This happens when an x64 version of the app is run on an M1/M2/M3 Mac. | ||||
|  * Uses the macOS sysctl.proc_translated to properly detect translation. | ||||
|  * @returns true if running under Rosetta 2, false otherwise | ||||
|  */ | ||||
| export const isRunningUnderRosetta2 = () => { | ||||
|     if (!isMac) return false; | ||||
|  | ||||
|     try { | ||||
|         // Use child_process to check sysctl.proc_translated | ||||
|         // This is the proper way to detect Rosetta 2 translation | ||||
|         const { execSync } = require("child_process"); | ||||
|         const result = execSync("sysctl -n sysctl.proc_translated 2>/dev/null", { | ||||
|             encoding: "utf8", | ||||
|             timeout: 1000 | ||||
|         }).trim(); | ||||
|  | ||||
|         // 1 means the process is being translated by Rosetta 2 | ||||
|         // 0 means native execution | ||||
|         // If the sysctl doesn't exist (on Intel Macs), this will return empty/error | ||||
|         return result === "1"; | ||||
|     } catch (error) { | ||||
|         // If sysctl fails or doesn't exist (Intel Macs), not running under Rosetta 2 | ||||
|         return false; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| export function newEntityId() { | ||||
|     return randomString(12); | ||||
| } | ||||
| @@ -423,7 +395,6 @@ export default { | ||||
|     isElectron, | ||||
|     isEmptyOrWhitespace, | ||||
|     isMac, | ||||
|     isRunningUnderRosetta2, | ||||
|     isStringNote, | ||||
|     isWindows, | ||||
|     md5, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user