diff --git a/.vscode/settings.json b/.vscode/settings.json index 639360100..2e0caf532 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,11 @@ { "editor.formatOnSave": true, - "autoimport.doubleQuotes": false, - "java.configuration.updateBuildConfiguration": "disabled", "prettier.requireConfig": true, - "javascript.format.enable": true, + "js/ts.format.enabled": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "prettier.tabWidth": 2, "prettier.useTabs": false, - "javascript.format.semicolons": "insert", + "js/ts.format.semicolons": "insert", "[scss]": { "editor.defaultFormatter": "vscode.css-language-features" }, @@ -27,6 +25,13 @@ "attr_quotes": "single" } }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "quickFix.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, "cSpell.words": [ "abap", "Acode", @@ -126,6 +131,7 @@ "flac", "Flix", "floobits", + "FOXBIZ", "Foxdebug", "freemarker", "gamemaker", @@ -370,10 +376,9 @@ "wtest", "wxml", "wxss", + "xhrs", + "XMLHTTP", "xquery", "Zeek" - ], - "[javascript]": { - "editor.defaultFormatter": "biomejs.biome" - } + ] } diff --git a/biome.json b/biome.json index 1f48da7bc..49e104a29 100644 --- a/biome.json +++ b/biome.json @@ -39,18 +39,15 @@ }, "files": { "includes": [ - "**/src/**/*", - "**/utils/**/*.js", - "!**/www/build/**/*", - "**/www/res/**/*.css", - "**/src/plugins/terminal/**", - "!**/ace-builds", - "!**/src/plugins/**/*", - "!**/plugins/**/*", - "!**/hooks/**/*", - "!**/fastlane/**/*", - "!**/res/**/*", - "!**/platforms/**/*" + "src/**/*.js", + "utils/**/*.js", + "!src/lang/**/*.json", + "!src/plugins/**/*.js", + "!www/**/*", + "!plugins/**/*", + "!hooks/**/*", + "!fastlane/**/*", + "!platforms/**/*" ] } } diff --git a/bun.lock b/bun.lock index 17fef2836..2c111fa7d 100644 --- a/bun.lock +++ b/bun.lock @@ -37,7 +37,6 @@ "@codemirror/state": "^6.6.0", "@codemirror/theme-one-dark": "^6.1.3", "@codemirror/view": "^6.40.0", - "@deadlyjack/ajax": "^1.2.6", "@emmetio/codemirror6-plugin": "^0.4.0", "@lezer/highlight": "^1.2.3", "@ungap/custom-elements": "^1.3.0", @@ -425,8 +424,6 @@ "@codemirror/view": ["@codemirror/view@6.40.0", "", { "dependencies": { "@codemirror/state": "^6.6.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg=="], - "@deadlyjack/ajax": ["@deadlyjack/ajax@1.2.6", "", {}, "sha512-VwZU8YUflO2/V/dl3dluu+3jg8Ghz/W5fwxD5Z21OZXKeV73d+vStKVBe4wi+Av2KbTR35K7Z+5Q3iIpjB41MA=="], - "@discoveryjs/json-ext": ["@discoveryjs/json-ext@0.5.7", "", {}, "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw=="], "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], diff --git a/hooks/post-process.js b/hooks/post-process.js index 21c411934..e7a175ac3 100644 --- a/hooks/post-process.js +++ b/hooks/post-process.js @@ -30,6 +30,18 @@ enableStaticContext(); patchTargetSdkVersion(); enableKeyboardWorkaround(); +function getPackageName() { + const configPath = path.resolve(__dirname, '../config.xml'); + if (!fs.existsSync(configPath)) { + console.warn('[Cordova Hook] ⚠️ config.xml not found at', configPath); + throw new Error(`config.xml is missing at ${configPath}`); + } + const content = fs.readFileSync(configPath, 'utf-8'); + const match = content.match(/id="([^"]+)"/); + const packageName = match ? match[1] : 'com.foxdebug.acode'; + return packageName; +} + function getTmpDir() { const tmpdirEnv = process.env.TMPDIR; @@ -107,11 +119,17 @@ function enableLegacyJni() { const prefix = execSync('npm prefix').toString().trim(); const gradleFile = path.join(prefix, 'platforms/android/app/build.gradle'); - if (!fs.existsSync(gradleFile)) return; + if (!fs.existsSync(gradleFile)){ + console.warn('[Cordova Hook] ⚠️ build.gradle not found'); + return + }; let content = fs.readFileSync(gradleFile, 'utf-8'); // Check for correct block to avoid duplicate insertion - if (content.includes('useLegacyPackaging = true')) return; + if (content.includes('useLegacyPackaging = true')){ + console.log('[Cordova Hook] ✅ Legacy JNI packaging already enabled, skipping'); + return + }; // Inject under android block with correct Groovy syntax content = content.replace(/android\s*{/, match => { @@ -133,12 +151,16 @@ function enableLegacyJni() { function enableStaticContext() { try { const prefix = execSync('npm prefix').toString().trim(); + const packageName = getPackageName(); const mainActivityPath = path.join( prefix, - 'platforms/android/app/src/main/java/com/foxdebug/acode/MainActivity.java' + 'platforms/android/app/src/main/java', + packageName.replace(/\./g, '/'), + 'MainActivity.java' ); if (!fs.existsSync(mainActivityPath)) { + console.warn('[Cordova Hook] ⚠️ MainActivity.java not found at', mainActivityPath); return; } @@ -150,6 +172,7 @@ function enableStaticContext() { content.includes('public static Context getContext()') && content.includes('weakContext = new WeakReference<>(this);') ) { + console.log('[Cordova Hook] ✅ Static context already enabled, skipping'); return; } @@ -181,6 +204,7 @@ function enableStaticContext() { ); fs.writeFileSync(mainActivityPath, content, 'utf-8'); + console.log('[Cordova Hook] ✅ Enabled static context'); } catch (err) { console.error('[Cordova Hook] ❌ Failed to patch MainActivity:', err.message); } @@ -189,12 +213,16 @@ function enableStaticContext() { function enableKeyboardWorkaround() { try{ const prefix = execSync('npm prefix').toString().trim(); + const packageName = getPackageName(); const mainActivityPath = path.join( prefix, - 'platforms/android/app/src/main/java/com/foxdebug/acode/MainActivity.java' + 'platforms/android/app/src/main/java', + packageName.replace(/\./g, '/'), + 'MainActivity.java' ); if (!fs.existsSync(mainActivityPath)) { + console.warn('[Cordova Hook] ⚠️ MainActivity.java not found at', mainActivityPath); return; } @@ -202,6 +230,7 @@ function enableKeyboardWorkaround() { // Skip if already patched if (content.includes('SoftInputAssist')) { + console.log('[Cordova Hook] ✅ Keyboard workaround already enabled, skipping'); return; } diff --git a/jsconfig.json b/jsconfig.json index 89b465f62..b1983ca52 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,9 +1,8 @@ { "exclude": ["**/node_modules", "**/platforms", "**/www", "www/js/ace/**/*"], "compilerOptions": { - "baseUrl": "./src", "paths": { - "*": ["*"] + "*": ["./src/*"] } }, "include": ["src/**/*"], diff --git a/package-lock.json b/package-lock.json index b78b58a49..72268cd75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,6 @@ "@codemirror/state": "^6.6.0", "@codemirror/theme-one-dark": "^6.1.3", "@codemirror/view": "^6.40.0", - "@deadlyjack/ajax": "^1.2.6", "@emmetio/codemirror6-plugin": "^0.4.0", "@lezer/highlight": "^1.2.3", "@ungap/custom-elements": "^1.3.0", @@ -2421,12 +2420,6 @@ "w3c-keyname": "^2.2.4" } }, - "node_modules/@deadlyjack/ajax": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@deadlyjack/ajax/-/ajax-1.2.6.tgz", - "integrity": "sha512-VwZU8YUflO2/V/dl3dluu+3jg8Ghz/W5fwxD5Z21OZXKeV73d+vStKVBe4wi+Av2KbTR35K7Z+5Q3iIpjB41MA==", - "license": "MIT" - }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", diff --git a/package.json b/package.json index f2a2a811d..aed6191ec 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "com.foxdebug.acode.rk.exec.terminal": {}, "com.foxdebug.acode.rk.customtabs": {}, "com.foxdebug.acode.rk.plugin.plugincontext": {}, - "com.foxdebug.acode.rk.auth": {}, - "cordova-plugin-system": {} + "cordova-plugin-system": {}, + "com.foxdebug.acode.rk.auth": {} }, "platforms": [ "android" @@ -137,7 +137,6 @@ "@codemirror/state": "^6.6.0", "@codemirror/theme-one-dark": "^6.1.3", "@codemirror/view": "^6.40.0", - "@deadlyjack/ajax": "^1.2.6", "@emmetio/codemirror6-plugin": "^0.4.0", "@lezer/highlight": "^1.2.3", "@ungap/custom-elements": "^1.3.0", diff --git a/src/cm/lsp/serverLauncher.ts b/src/cm/lsp/serverLauncher.ts index 1350a1ff3..8ed527971 100644 --- a/src/cm/lsp/serverLauncher.ts +++ b/src/cm/lsp/serverLauncher.ts @@ -35,6 +35,8 @@ const STATUS_FAILED: InstallStatus = "failed"; const AXS_BINARY = "$PREFIX/axs"; +let alreadyInformed = false; + function getTerminalRequiredMessage(): string { return ( strings?.terminal_required_message_for_lsp ?? @@ -1081,7 +1083,14 @@ export async function ensureServerRunning( } catch {} if (!isTerminalInstalled) { const message = getTerminalRequiredMessage(); - alert(strings?.error, message); + + if (!alreadyInformed){ + alreadyInformed = true; + alert(strings?.error, message); + }else{ + toast(message); + } + const unavailable: LspError = new Error(message); unavailable.code = "LSP_SERVER_UNAVAILABLE"; throw unavailable; diff --git a/src/components/sidebar/index.js b/src/components/sidebar/index.js index 0b606960f..da5202b19 100644 --- a/src/components/sidebar/index.js +++ b/src/components/sidebar/index.js @@ -3,8 +3,17 @@ import toast from "components/toast"; import Ref from "html-tag-js/ref"; import actionStack from "lib/actionStack"; import auth, { loginEvents } from "lib/auth"; -import constants from "lib/constants"; +import config from "lib/config"; +/** + * @typedef {object} SideBar + * @extends HTMLElement + * @property {function():void} hide + * @property {function():void} toggle + * @property {function():void} onshow + */ + +/**@type {HTMLElement} */ let $sidebar; /**@type {Array<(el:HTMLElement)=>boolean>} */ let preventSlideTests = []; @@ -14,14 +23,6 @@ const events = { hide: [], }; -/** - * @typedef {object} SideBar - * @extends HTMLElement - * @property {function():void} hide - * @property {function():void} toggle - * @property {function():void} onshow - */ - /** * Create a sidebar * @param {HTMLElement} [$container] - the element that will contain the sidebar @@ -31,7 +32,7 @@ const events = { function create($container, $toggler) { let { innerWidth } = window; - const START_THRESHOLD = constants.SIDEBAR_SLIDE_START_THRESHOLD_PX; //Point where to start swipe + const START_THRESHOLD = config.SIDEBAR_SLIDE_START_THRESHOLD_PX; //Point where to start swipe const MIN_WIDTH = 200; //Min width of the side bar const MAX_WIDTH = () => innerWidth * 0.7; //Max width of the side bar const resizeBar = Ref(); @@ -103,12 +104,46 @@ function create($container, $toggler) { async function handleUserIconClick(e) { try { - const isLoggedIn = await auth.isLoggedIn(); - - if (!isLoggedIn) { - auth.openLoginUrl(); + const user = await auth.getLoggedInUser(); + + if (!user) { + CustomTabs.open( + `${config.BASE_URL}/login?redirect=app`, + { showTitle: true }, + () => {}, + () => {}, + ); } else { - toggleUserMenu(); + const menu = userContextMenu.el; + const isActive = menu.classList.toggle("active"); + + if (isActive) { + const menuName = userContextMenu.el.querySelector(".user-menu-name"); + const menuEmail = + userContextMenu.el.querySelector(".user-menu-email"); + + if (menuName) { + menuName.content = ( +
+ + {strings["plugin-not-supported"]} +
Thank you for supporting Acode!