Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,28 @@
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": { "recommended": false }
"rules": {
"recommended": false,
"complexity": {
"noForEach": "warn",
"noStaticOnlyClass": "error",
"noUselessSwitchCase": "error",
"useFlatMap": "error"
},
"style": {
"noNegationElse": "off",
"useForOf": "error",
"useNodejsImportProtocol": "error",
"useNumberNamespace": "error"
},
"suspicious": {
"noDoubleEquals": "error",
"noThenProperty": "error",
"useIsArray": "error"
}
}
},
"javascript": { "globals": ["Global1"] },
"files": {
"include": ["src/**/*", "utils/**/*.js", "www/**/*.js", "www/res/**/*.css"],
"ignore": [
Expand Down
71 changes: 65 additions & 6 deletions src/lib/loadPlugins.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,84 @@
import fsOperation from "../fileSystem";
import Url from "../utils/Url";
import loadPlugin from "./loadPlugin";
import settings from "./settings";

export default async function loadPlugins() {
// theme-related keywords for determining theme plugins
const THEME_IDENTIFIERS = new Set([
"theme",
"catppuccin",
"pine",
"githubdark",
"radiant",
"rdtheme",
"ayumirage",
"dust",
"synthwave",
"dragon",
"mint",
"monokai",
"lumina_code",
"sweet",
"moonlight",
"bluloco",
]);

export default async function loadPlugins(loadOnlyTheme = false) {
const plugins = await fsOperation(PLUGIN_DIR).lsDir();
const results = [];
const failedPlugins = [];
const loadedPlugins = new Set();

if (plugins.length > 0) {
toast(strings["loading plugins"]);
}

let pluginsToLoad = [];
const currentTheme = settings.value.appTheme;

if (loadOnlyTheme) {
// Only load theme plugins matching current theme
pluginsToLoad = plugins.filter((pluginDir) => {
const pluginId = Url.basename(pluginDir.url);
return isThemePlugin(pluginId) && !loadedPlugins.has(pluginId);
});
} else {
// Load non-theme plugins that aren't loaded yet
pluginsToLoad = plugins.filter((pluginDir) => {
const pluginId = Url.basename(pluginDir.url);
return !isThemePlugin(pluginId) && !loadedPlugins.has(pluginId);
});
}

// Load plugins concurrently
const loadPromises = plugins.map(async (pluginDir) => {
const loadPromises = pluginsToLoad.map(async (pluginDir) => {
const pluginId = Url.basename(pluginDir.url);

if (loadOnlyTheme && currentTheme) {
const pluginIdLower = pluginId.toLowerCase();
const currentThemeLower = currentTheme.toLowerCase();
const matchFound = pluginIdLower.includes(currentThemeLower);
// Skip if:
// 1. No match found with current theme AND
// 2. It's not a theme plugin at all
if (!matchFound && !isThemePlugin(pluginId)) {
return;
}
}

try {
await loadPlugin(pluginId);
loadedPlugins.add(pluginId);
results.push(true);
} catch (error) {
window.log("error", `Failed to load plugin: ${pluginId}`);
window.log("error", error);
toast(`Failed to load plugin: ${pluginId}`);
console.error(`Error loading plugin ${pluginId}:`, error);
failedPlugins.push(pluginId);
results.push(false);
}
});

await Promise.allSettled(loadPromises);

if (failedPlugins.length > 0) {
setTimeout(() => {
cleanupFailedPlugins(failedPlugins).catch((error) => {
Expand All @@ -37,6 +89,13 @@ export default async function loadPlugins() {
return results.filter(Boolean).length;
}

function isThemePlugin(pluginId) {
// Convert to lowercase for case-insensitive matching
const id = pluginId.toLowerCase();
// Check if any theme identifier is present in the plugin ID
return Array.from(THEME_IDENTIFIERS).some((theme) => id.includes(theme));
}

async function cleanupFailedPlugins(pluginIds) {
for (const pluginId of pluginIds) {
try {
Expand All @@ -45,7 +104,7 @@ async function cleanupFailedPlugins(pluginIds) {
await fsOperation(pluginDir).delete();
}
} catch (error) {
window.log("error", `Failed to cleanup plugin ${pluginId}:`, error);
console.error(`Failed to cleanup plugin ${pluginId}:`, error);
}
}
}
20 changes: 15 additions & 5 deletions src/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,22 @@ async function onDeviceReady() {
window.log("error", error);
toast(`Error: ${error.message}`);
} finally {
setTimeout(() => {
setTimeout(async () => {
document.body.removeAttribute("data-small-msg");
app.classList.remove("loading", "splash");

// load plugins
try {
await loadPlugins();
} catch (error) {
window.log("error", "Failed to load plugins!");
window.log("error", error);
toast("Failed to load plugins!");
}
applySettings.afterRender();
}, 500);
}

// Check for app updates
if (navigator.onLine) {
cordova.plugin.http.sendRequest(
Expand Down Expand Up @@ -430,13 +440,13 @@ async function loadApp() {

new EditorFile();

//load plugins
// load theme plugins
try {
await loadPlugins();
await loadPlugins(true);
} catch (error) {
window.log("error", "Plugins loading failed!");
window.log("error", "Failed to load theme plugins!");
window.log("error", error);
toast("Plugins loading failed!");
toast("Failed to load theme plugins!");
}

acode.setLoadingMessage("Loading folders...");
Expand Down