Skip to content

Commit

Permalink
notion-app-enhanced: fix infinite loading
Browse files Browse the repository at this point in the history
fixes upstream issues that cause the app to be unable to load, see
notion-enhancer/notion-enhancer#812
notion-enhancer/notion-repackaged#116
  • Loading branch information
L1Z3 authored and eliandoran committed Jul 26, 2024
1 parent a7c8db4 commit 0732606
Show file tree
Hide file tree
Showing 2 changed files with 282 additions and 4 deletions.
21 changes: 17 additions & 4 deletions pkgs/applications/office/notion-app-enhanced/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ appimageTools, lib, fetchurl }:
{ appimageTools, lib, fetchurl, asar, dos2unix }:
let
pname = "notion-app-enhanced";
version = "2.0.18-1";
Expand All @@ -8,9 +8,22 @@ let
sha256 = "sha256-SqeMnoMzxxaViJ3NPccj3kyMc1xvXWULM6hQIDZySWY=";
};

appimageContents = appimageTools.extract { inherit pname version src; };
in appimageTools.wrapType2 {
inherit pname version src;
appimageContents = appimageTools.extract {
inherit pname version src;
postExtract = ''
# fix https://github.com/notion-enhancer/notion-enhancer/issues/812
${asar}/bin/asar extract $out/resources/app.asar app
${dos2unix}/bin/dos2unix app/renderer/preload.js
patch app/renderer/preload.js ${./notion-infinite-load-fix.patch}
${dos2unix}/bin/unix2dos app/renderer/preload.js
${asar}/bin/asar pack app $out/resources/app.asar
'';
};
# wrapAppImage instead of wrapType2 to avoid re-extracting the AppImage
in appimageTools.wrapAppImage {
inherit pname version;

src = appimageContents;

extraInstallCommands = ''
install -m 444 -D ${appimageContents}/${pname}.desktop -t $out/share/applications
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
--- app/renderer/preload.js
+++ app/renderer/preload.js
@@ -1,4 +1,262 @@
"use strict";
+(function __polyfill_2() {
+ function getClientHints(navigator) {
+ let { userAgent } = navigator;
+ let mobile, platform = '', platformVersion = '', architecture = '', bitness = '', model = '', uaFullVersion = '', fullVersionList = [];
+ let platformInfo = userAgent;
+ let found = false;
+ let versionInfo = userAgent.replace(/\(([^)]+)\)?/g, ($0, $1) => {
+ if (!found) {
+ platformInfo = $1;
+ found = true;
+ }
+ return '';
+ });
+ let items = versionInfo.match(/(\S+)\/(\S+)/g);
+ let webview = false;
+ // detect mobile
+ mobile = userAgent.indexOf('Mobile') !== -1;
+ let m;
+ let m2;
+ // detect platform
+ if ((m = /Windows NT (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
+ platform = 'Windows';
+ // see https://docs.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11
+ let nt2win = {
+ '6.1': '0.1', // win-7
+ '6.2': '0.2', // win-8
+ '6.3': '0.3', // win-8.1
+ '10.0': '10.0', // win-10
+ '11.0': '13.0', // win-11
+ };
+ let ver = nt2win[m[1]];
+ if (ver)
+ platformVersion = padVersion(ver, 3);
+ if ((m2 = /\b(WOW64|Win64|x64)\b/.exec(platformInfo)) !== null) {
+ architecture = 'x86';
+ bitness = '64';
+ }
+ } else if ((m = /Android (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
+ platform = 'Android';
+ platformVersion = padVersion(m[1]);
+ if ((m2 = /Linux (\w+)/.exec(navigator.platform)) !== null) {
+ if (m2[1]) {
+ m2 = parseArch(m2[1]);
+ architecture = m2[0];
+ bitness = m2[1];
+ }
+ }
+ } else if ((m = /(iPhone|iPod touch); CPU iPhone OS (\d+(_\d+)*)/.exec(platformInfo)) !== null) {
+ // see special notes at https://www.whatismybrowser.com/guides/the-latest-user-agent/safari
+ platform = 'iOS';
+ platformVersion = padVersion(m[2].replace(/_/g, '.'));
+ } else if ((m = /(iPad); CPU OS (\d+(_\d+)*)/.exec(platformInfo)) !== null) {
+ platform = 'iOS';
+ platformVersion = padVersion(m[2].replace(/_/g, '.'));
+ } else if ((m = /Macintosh; (Intel|\w+) Mac OS X (\d+(_\d+)*)/.exec(platformInfo)) !== null) {
+ platform = 'macOS';
+ platformVersion = padVersion(m[2].replace(/_/g, '.'));
+ } else if ((m = /Linux/.exec(platformInfo)) !== null) {
+ platform = 'Linux';
+ platformVersion = '';
+ // TODO
+ } else if ((m = /CrOS (\w+) (\d+(\.\d+)*)/.exec(platformInfo)) !== null) {
+ platform = 'Chrome OS';
+ platformVersion = padVersion(m[2]);
+ m2 = parseArch(m[1]);
+ architecture = m2[0];
+ bitness = m2[1];
+ }
+ if (!platform) {
+ platform = 'Unknown';
+ }
+ // detect fullVersionList / brands
+ let notABrand = { brand: ' Not;A Brand', version: '99.0.0.0' };
+ if ((m = /Chrome\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null && navigator.vendor === 'Google Inc.') {
+ fullVersionList.push({ brand: 'Chromium', version: padVersion(m[1], 4) });
+ if ((m2 = /(Edge?)\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null) {
+ let identBrandMap = {
+ 'Edge': 'Microsoft Edge',
+ 'Edg': 'Microsoft Edge',
+ };
+ let brand = identBrandMap[m[1]];
+ fullVersionList.push({ brand: brand, version: padVersion(m2[2], 4) });
+ } else {
+ fullVersionList.push({ brand: 'Google Chrome', version: padVersion(m[1], 4) });
+ }
+ if (/\bwv\b/.exec(platformInfo)) {
+ webview = true;
+ }
+ } else if ((m = /AppleWebKit\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null && navigator.vendor === 'Apple Computer, Inc.') {
+ fullVersionList.push({ brand: 'WebKit', version: padVersion(m[1]) });
+ if (platform === 'iOS' && (m2 = /(CriOS|EdgiOS|FxiOS|Version)\/(\d+(\.\d+)*)/.exec(versionInfo)) != null) {
+ let identBrandMap = { // no
+ 'CriOS': 'Google Chrome',
+ 'EdgiOS': 'Microsoft Edge',
+ 'FxiOS': 'Mozilla Firefox',
+ 'Version': 'Apple Safari',
+ };
+ let brand = identBrandMap[m2[1]];
+ fullVersionList.push({ brand, version: padVersion(m2[2]) });
+ if (items.findIndex((s) => s.startsWith('Safari/')) === -1) {
+ webview = true;
+ }
+ }
+ } else if ((m = /Firefox\/(\d+(\.\d+)*)/.exec(versionInfo)) !== null) {
+ fullVersionList.push({ brand: 'Firefox', version: padVersion(m[1]) });
+ } else if ((m = /(MSIE |rv:)(\d+\.\d+)/.exec(platformInfo)) !== null) {
+ fullVersionList.push({ brand: 'Internet Explorer', version: padVersion(m[2]) });
+ } else {
+ fullVersionList.push(notABrand);
+ }
+ uaFullVersion = fullVersionList.length > 0 ? fullVersionList[fullVersionList.length - 1] : '';
+ let brands = fullVersionList.map((b) => {
+ let pos = b.version.indexOf('.');
+ let version = pos === -1 ? b.version : b.version.slice(0, pos);
+ return { brand: b.brand, version };
+ });
+ // TODO detect architecture, bitness and model
+ return {
+ mobile,
+ platform,
+ brands,
+ platformVersion,
+ architecture,
+ bitness,
+ model,
+ uaFullVersion,
+ fullVersionList,
+ webview
+ };
+ }
+
+ function parseArch(arch) {
+ switch (arch) {
+ case 'x86_64':
+ case 'x64':
+ return ['x86', '64'];
+ case 'x86_32':
+ case 'x86':
+ return ['x86', ''];
+ case 'armv6l':
+ case 'armv7l':
+ case 'armv8l':
+ return [arch, ''];
+ case 'aarch64':
+ return ['arm', '64'];
+ default:
+ return ['', ''];
+ }
+ }
+ function padVersion(ver, minSegs = 3) {
+ let parts = ver.split('.');
+ let len = parts.length;
+ if (len < minSegs) {
+ for (let i = 0, lenToPad = minSegs - len; i < lenToPad; i += 1) {
+ parts.push('0');
+ }
+ return parts.join('.');
+ }
+ return ver;
+ }
+
+ class NavigatorUAData {
+ constructor() {
+ this._ch = getClientHints(navigator);
+ Object.defineProperties(this, {
+ _ch: { enumerable: false },
+ });
+ }
+ get mobile() {
+ return this._ch.mobile;
+ }
+ get platform() {
+ return this._ch.platform;
+ }
+ get brands() {
+ return this._ch.brands;
+ }
+ getHighEntropyValues(hints) {
+ return new Promise((resolve, reject) => {
+ if (!Array.isArray(hints)) {
+ throw new TypeError('argument hints is not an array');
+ }
+ let hintSet = new Set(hints);
+ let data = this._ch;
+ let obj = {
+ mobile: data.mobile,
+ platform: data.platform,
+ brands: data.brands,
+ };
+ if (hintSet.has('architecture'))
+ obj.architecture = data.architecture;
+ if (hintSet.has('bitness'))
+ obj.bitness = data.bitness;
+ if (hintSet.has('model'))
+ obj.model = data.model;
+ if (hintSet.has('platformVersion'))
+ obj.platformVersion = data.platformVersion;
+ if (hintSet.has('uaFullVersion'))
+ obj.uaFullVersion = data.uaFullVersion;
+ if (hintSet.has('fullVersionList'))
+ obj.fullVersionList = data.fullVersionList;
+ resolve(obj);
+ });
+ }
+ toJSON() {
+ let data = this._ch;
+ return {
+ mobile: data.mobile,
+ brands: data.brands,
+ };
+ }
+ }
+ Object.defineProperty(NavigatorUAData.prototype, Symbol.toStringTag, {
+ enumerable: false,
+ configurable: true,
+ writable: false,
+ value: 'NavigatorUAData'
+ });
+
+ function ponyfill() {
+ return new NavigatorUAData(navigator);
+ }
+ function polyfill() {
+ console.log("Try polyfill . . .");
+
+ // When Notion , no need https?
+ const ____use_https = false;
+
+ if (
+ (!____use_https || location.protocol === 'https:')
+ && !navigator.userAgentData
+ ) {
+ console.log("Here,begin userAgentData polyfill . . .")
+ let userAgentData = new NavigatorUAData(navigator);
+ Object.defineProperty(Navigator.prototype, 'userAgentData', {
+ enumerable: true,
+ configurable: true,
+ get: function getUseAgentData() {
+ return userAgentData;
+ }
+ });
+ Object.defineProperty(window, 'NavigatorUAData', {
+ enumerable: false,
+ configurable: true,
+ writable: true,
+ value: NavigatorUAData
+ });
+ return true;
+ }
+ return false;
+ }
+
+
+ // Simple Apply this code.
+ ponyfill();
+ polyfill();
+})();
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });

0 comments on commit 0732606

Please sign in to comment.