From b6b141ececdd234145bf62048a358a053eb6cdf4 Mon Sep 17 00:00:00 2001 From: Tadomika-Ari <124564764+Tadomika-Ari@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:43:14 +0200 Subject: [PATCH] feat!: add Config Swap plugin (#112) * feat!: init plugin * fix: fix widget not found on bar setting * feat!: add creation folder for plugin * feat!: add first version of Config Swap (simple modification test) * feat!: update toml with new feature * docs: prepare docs * feat!: add more place for view preview * feat!: add new page for store and allerady download * docs: improve lisibility * feat!: add description emplacement * feat!: add wallpaper support for install and set * docs: add more info to readme * feat: add cp depedencie * docs: add more info * feat!: add trad support * fix: change order for set wallpaper after change config * feat!: add settingsPath for data.json * feat!: add data.json creation if not exist * docs: add more docs info * feat!: rm useless preview image * docs: improve docs * feat!: change false description * feat!: add shellQuote for protect bad command * feat!: add path var in infoConfig.Change config type for infoConfig Type * feat!: add secure delete config and confirmation for delete config * feat!: add save function for save current config * feat!: add welcome warning and confirmation switch * feat!: add info for store section * docs: add new info in setting section * feat!: add resolve state dir for check all state dir possibility * feat!: add english translation compatibility * feat!: change thumbnail * docs: add more information on the readme * fix: rm useless button * docs: add comment * fix: add depedencie missing * fix: rm death code * fix: rm update interval not use * feat!: add delete, save and apply protection, reject invalid name * docs: add more info in info section * feat!: add more charactere in match string in isDetect function * fix: change wrong name function * feat!: add protection for invalid name in dowload Config --- config-swap/README.md | 130 ++++++ config-swap/config-swap-panel.luau | 655 +++++++++++++++++++++++++++ config-swap/config-swap-service.luau | 1 + config-swap/config-swap-widget.luau | 7 + config-swap/plugin.toml | 24 + config-swap/thumbnail.webp | Bin 0 -> 57732 bytes config-swap/translations/en.json | 47 ++ 7 files changed, 864 insertions(+) create mode 100644 config-swap/README.md create mode 100644 config-swap/config-swap-panel.luau create mode 100644 config-swap/config-swap-service.luau create mode 100644 config-swap/config-swap-widget.luau create mode 100644 config-swap/plugin.toml create mode 100644 config-swap/thumbnail.webp create mode 100644 config-swap/translations/en.json diff --git a/config-swap/README.md b/config-swap/README.md new file mode 100644 index 0000000..6f0dfe7 --- /dev/null +++ b/config-swap/README.md @@ -0,0 +1,130 @@ +# Config Swap + +A [Noctalia](https://github.com/noctalia-dev/noctalia) v5 plugin for switching between saved Noctalia configurations. + +## Dependencies + +For this plugin, you need: +* internet access to fetch configuration data from GitHub on the store page +* `cp` to apply a configuration +* `rm` to delete the selected installed configuration (not the current configuration) + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `tadomika_ari/config-swap` | +| Entries | Bar widget: `widget`; panel: `panel`; service: `start` | + +## Usage + +This plugin is still under development. + +You can open Config Swap with: + +```sh +noctalia msg panel-toggle tadomika_ari/config-swap:panel +``` + +The plugin downloads saved configurations from the `Config-Swap-Box` GitHub repository and stores them in `~/Config-Swap`. +Applying a configuration copies its `settings.toml` to `~/.local/state/noctalia/settings.toml` and sets the matching wallpaper. +Keep a backup of your current configuration before using it. + +Open the panel from the bar widget, then switch between the two views with `Show Store` and `Show List`. + + +### Before Start + +A welcome page is shown after each restart. Agree to continue, or close the plugin if you prefer not to use it. + +### Show Store + +The store view fetches available configurations from GitHub. +Use `refresh` to reload the list if nothing appears. + +Do not spam `refresh`; GitHub rate limits unauthenticated requests. + +Each card lets you `install` a configuration. + +An information panel is also available to explain the store view. + +| Action | Effect | +| --- | --- | +| Refresh | Refresh the GitHub API data | +| Info | Show information about the store | +| Install | Install the configuration in `~/Config-Swap` | +| Show list | Switch to the list view | + +### Show List + +The list view shows configurations already installed in `~/Config-Swap`. +From there, you can `apply` them again or `delete` them again to refresh the files. +You will be asked to confirm before applying the selected configuration and confirm before deleting the selected configuration. + +Click a preview image to see extra information such as the author, origin, and description. + +Use `Show Store` to return to the GitHub store view. + +| Action | Effect | +| --- | --- | +| Refresh | Refresh the GitHub API data | +| Delete | Delete the configuration in `~/Config-Swap` | +| Apply | Apply the configuration | +| Setting | Open the Config Swap settings | +| Click the preview | Open extra information | +| Show store | Switch to the store view | + +### Setting Info + +A settings panel is available. At this time, only saving a configuration is supported. + +You can save your current configuration under a custom name for backup or export. +Saving a configuration copies the current `settings.toml` and creates an `info.json` file, which is important for the plugin and for export to the GitHub store. The `info.json` file can be edited to add information, and you can also add a `preview.png` and a default wallpaper as `wallpaper.png`. +Files are saved in `~/Config-Swap/{name}`. + +This also refreshes the list of installed configurations. + +| Action | Effect | +| --- | --- | +| Input field | Enter a custom name for the save (default: `save`) | +| Save | Create a backup of the current configuration | + + +### Extra Info + +You can add your own configuration folder to `~/Config-Swap`. +Each configuration should follow the same structure as the downloaded ones, including an `info.json` file and the expected asset files. + +If you want to publish a configuration, add it to the `Config-Swap-Box` repository: https://github.com/Tadomika-Ari/Config-Swap-Box +Make sure Config Swap is enabled in your plugin list before you try to use it. + +You can delete a configuration with the trash button. A warning panel will appear before deletion. + +### Contributing + +You can contribute to Config Swap! Add your own configuration files and wallpaper to the store so others can use them. +To do so: +* Go to the Settings section and save your configuration. The plugin will copy your `settings.toml` and create an `info.json` file. +* Take a preview image and wallpaper, then go to `~/Config-Swap/{name}` and copy your `preview.png` and `wallpaper.png` files (the exact names are required). +* Update your `info.json` with important information such as the author and description. +* Go to the GitHub page linked from the information panel in the Store section and create a pull request. +* Wait for review, and then your configuration can be shared. + +## Settings + +No setting needed + +## Requirements + +- Noctalia ≥ 5.0.0 +- `cp` +- `rm` +- internet access for the store view + +## Install + +Install the plugin and add it to your bar. + +## License + +MIT. \ No newline at end of file diff --git a/config-swap/config-swap-panel.luau b/config-swap/config-swap-panel.luau new file mode 100644 index 0000000..47071a2 --- /dev/null +++ b/config-swap/config-swap-panel.luau @@ -0,0 +1,655 @@ +--!nonstrict +-- Config Swap panel + +-- Local variables + +local configBox = "~/Config-Swap" + +local listConfig = nil + +local pickSlots = {} +local columns = 2 +local previewWidth = 470 +local previewHeight = 350 +local previewImage = "" + +local selectedView = 0 -- Controls which screen to render (0=welcome, 1=installed, 2=store) + +local previewCache = {} -- In-memory map: config name -> cached preview image path +local previewPending = {} + +local configWidth = 800 -- Preview dialog size +local configHeight = 600 + +-- Data model + +type infoConfig = { + name: string, -- Configuration name + author: string, -- Configuration author + origin: string, -- Distribution/source (NixOS, Arch, CachyOS, etc.) + preview: string, -- Preview image path (preview.png) + path: string, -- Config path (example: config/{name}) + description: string, -- Short description + wallpaperPath: string, -- Wallpaper path + depedencie: boolean, -- Whether extra dependencies are required +} + +-- Resolve Noctalia state directory + +local function resolveStateDir() + return noctalia.getenv("NOCTALIA_STATE_HOME") + or ((noctalia.getenv("XDG_STATE_HOME") or ((noctalia.getenv("HOME") or "") .. "/.local/state")) .. "/noctalia") +end + +-- Detecte dangerous charactère + +function isDetect(target: string) + local match_string = "[/.$();]" + + if string.match(target, match_string) then + return true + else + return false + end +end + +-- Store listing cache + +local allConfig: { infoConfig } = {} + +local requestFetchList = { + url = "https://api.github.com/repos/Tadomika-Ari/Config-Swap-Box/contents/config", + method = "GET", + headers = { "Accept: application/json", "User-Agent: Config-Swap-Box-Plugin" }, + follow_redirects = true +} + +-- Translation helper + +function tr(key, subst) + if subst then + return noctalia.tr("panel." .. key, subst) + end + return noctalia.tr("panel." .. key) +end + +-- Build settings.toml path from the resolved state dir + +function takePosSetting() + local noctaliaStateDir = resolveStateDir() + local settingsTomlPath = noctaliaStateDir .. "/settings.toml" + return settingsTomlPath +end + +-- Shell escaping to safely build external commands + +local function shellQuote(s) + return "'" .. tostring(s):gsub("'", "'\\''") .. "'" +end + + +-- Welcome warning screen + +local function welcomeWarning() -- Shown after startup; refusing closes the plugin + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = tr("title"), textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + }), + ui.label({ text = tr("welcome_message_title"), textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("welcome_message1"), textAlign = "center", fontSize = 14, color = "on_surface_variant" }), + ui.label({ text = tr("welcome_message2"), textAlign = "center", fontSize = 14, color = "on_surface_variant" }), + ui.row({ gap = 8, justify = "center" }, { + ui.button({ text = tr("not_agree"), variant = "ghost", onClick = "onCloseClicked" }), + ui.button({ text = tr("agree"), onClick = function() + selectedView = 1 + render() + end + }), + }), + })) +end + +local function renderConfirmApply(data: infoConfig) -- Confirmation dialog before applying a config + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = tr("title"), textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + }), + ui.label({ text = tr("confirmation"), textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = data.name, textAlign = "center", fontSize = 14, color = "on_surface_variant" }), + ui.label({ text = tr("description_confirmation"), textAlign = "center", fontSize = 13, color = "on_surface_variant" }), + ui.row({ gap = 8, justify = "center" }, { + ui.button({ text = tr("cancel"), variant = "ghost", onClick = "render" }), + ui.button({ text = tr("apply"), variant = "primary", onClick = function() + applyConfig(data) + render() + end + }), + }), + })) +end + +-- Apply selected config and wallpaper + +function applyConfig(data: infoConfig) + noctalia.notify(tr("apply_notification_title")) + + if isDetect(data.name) == true then -- detecte malicious name + noctalia.notify(tr("apply_notification_title"), "Invalid name. Please check your info.json") + return + end + + local pathSettings = takePosSetting() + if not pathSettings then + noctalia.notify(tr("notification_title"), "Path not found, please check your setting toml") + return + end + + local src = shellQuote(noctalia.expandPath(configBox .. "/" .. data.name .. "/settings.toml")) + local dest = shellQuote(noctalia.expandPath(pathSettings)) + local cmd = "cp " .. src .. " " .. dest + + noctalia.runAsync(cmd, function(result) + if result and result.exitCode == 0 then + noctalia.setWallpaper(configBox .. "/" .. data.name .. "/wallpaper.png") + else + noctalia.notify(tr("notification_title"), "swap failed") + end + end) +end + +-- Download the full config bundle: settings, info json, preview, wallpaper + +function downloadConfig(data: infoConfig) + noctalia.notify(tr("install_notification_title")) + + if isDetect(data.name) == true then + noctalia.notify("Download", "Invalide name detected, please check target config") + return + end + + noctalia.mkdirAll(configBox .. "/" .. data.name) + + local path = data.path .. "/settings.toml" + local url = "https://raw.githubusercontent.com/Tadomika-Ari/Config-Swap-Box/main/" .. path + noctalia.download(url, configBox .. "/" .. data.name .. "/settings.toml" , function(ok) + if ok then + noctalia.notify(tr("notification_title"), tr("download_ok")) + else + noctalia.notify(tr("notification_title"), tr("download_failed")) + end + end) + local path = data.path .. "/info.json" + local url = "https://raw.githubusercontent.com/Tadomika-Ari/Config-Swap-Box/main/" .. path + noctalia.download(url, configBox .. "/" .. data.name .. "/info.json" , function(ok) + if ok then + noctalia.notify(tr("notification_title"), tr("download_ok")) + else + noctalia.notify(tr("notification_title"), tr("download_failed")) + end + end) + local path = data.path .. "/preview.png" + local url = "https://raw.githubusercontent.com/Tadomika-Ari/Config-Swap-Box/main/" .. path + noctalia.download(url, configBox .. "/" .. data.name .. "/preview.png" , function(ok) + if ok then + noctalia.notify(tr("notification_title"), tr("download_ok")) + else + noctalia.notify(tr("notification_title"), tr("download_failed")) + end + end) + local path = data.path .. "/wallpaper.png" + local url = "https://raw.githubusercontent.com/Tadomika-Ari/Config-Swap-Box/main/" .. path + noctalia.download(url, configBox .. "/" .. data.name .. "/wallpaper.png" , function(ok) + if ok then + noctalia.notify(tr("notification_title"), tr("download_ok")) + else + noctalia.notify(tr("notification_title"), tr("download_failed")) + end + end) +end + +-- GitHub store preview cache + +local function previewCachePath(name) + -- Keep cached previews under plugin data to avoid repeated downloads. + local dir = noctalia.pluginDataDir() .. "/preview-cache" + noctalia.mkdirAll(dir) + return dir .. "/" .. name .. ".png" +end + +local function queuePreviewDownload(name) + -- Prevent duplicate requests for the same preview while one is in flight. + if previewCache[name] ~= nil or previewPending[name] then + return + end + + local dest = previewCachePath(name) + if noctalia.fileExists(dest) then + previewCache[name] = dest + return + end + + previewPending[name] = true + local url = "https://raw.githubusercontent.com/Tadomika-Ari/Config-Swap-Box/main/config/" .. name .. "/preview.png" + + noctalia.download(url, dest, function(ok) + previewPending[name] = nil + if ok then + previewCache[name] = dest + render() + end + end) +end + +-- Delete an installed config + +local function delete(name) + + if not name or name == "" then + noctalia.notify("Delete", "invalid name") + return + end + + if isDetect(name) == true then -- detecte malicious name + noctalia.notify("Delete", "Invalide Name. Please check info.json") + return + end + + local target = noctalia.expandPath(configBox .. "/" .. name) + local cmd = "rm -rf " .. shellQuote(target) -- shellQuote protects the rm target path + noctalia.runAsync(cmd, function(result) + if result and result.exitCode == 0 then + noctalia.notify("Delete Ok") + else + noctalia.notify("Delete failed") + end + end) + render() +end + +local function renderDeleteConfirmation(name) -- Confirmation panel before deleting a config + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.label({ text = tr("confirmation_delete") .. name .. "?", align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ text = tr("delete"), onClick = function() + delete(name) + end + }), + ui.button({ glyph = "close", onClick = "render" }), + })) +end + +-- Save/backup settings section + +local noctaliaStateDir = resolveStateDir() +local settingsTomlPath = noctaliaStateDir .. "/settings.toml" -- Active settings file path + +local saveNameInput = "save" + +local function saveConfig() + local name = saveNameInput ~= "" and saveNameInput or "save" + + if isDetect(name) then -- detecte special charactere + noctalia.notify("Save", "Invalid Name") + return + end + + local savePath = configBox .. "/" .. name + noctalia.mkdirAll(savePath) + + local settingFile: infoConfig = { + name = name, + description = "save for reset", + path = configBox .. "/" .. name, + origin = "not give", + wallpaperPath = nil, + depedencie = false, + preview = nil, + author = noctalia.getenv("USER"), + } + local jsonData = noctalia.json.encode(settingFile) + noctalia.writeFile(savePath .. "/info.json", jsonData) + + local content = noctalia.readFile(settingsTomlPath) + if content then + noctalia.writeFile(savePath .. "/settings.toml", content) + noctalia.notify("Save", "Save ok : " .. name) + render() + else + noctalia.notify("Save", "settings.toml not found") + end +end + +function onSaveNameChange(value) + saveNameInput = value +end + +local function renderSetting() + local rowsSettings = { + ui.column({ gap = 8 }, { + ui.label({ + text = tr("description_setting1"), + fontSize = 12, + color = "on_surface_variant", + }), + ui.row({ flexGrow = 1, gap = 16, align = "center" }, { + ui.input({ + key = "save-name-input", + value = saveNameInput, + placeholder = "Save name", + onChange = "onSaveNameChange", + flexGrow = 1, + }), + ui.button({ text = tr("save"), onClick = function() + saveConfig() + end + }), + }), + }), + } + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.label({ text = "Setting section", textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ text = "X", onClick = "render"}), + ui.scroll({ gap = 12, align = "stretch", flexGrow = 1 }, rowsSettings), + })) +end + +-- Store information panel + +local function renderInfoStore() + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = tr("info_store_title"), textAlign = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ text = tr("info_store_github_button"), onClick = function() + noctalia.copyToClipboard("https://github.com/Tadomika-Ari/Config-Swap-Box", "text/plain") + noctalia.notify(tr("notification_title"), tr("info_store_copy_link_success")) + end + }), + ui.button({ glyph = "close", onClick = "render" }), + }), + ui.scroll({ gap = 16, align = "stretch", flexGrow = 1 }, { + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_store_what_is_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_store_what_is_body"), fontSize = 12, color = "on_surface_variant" }), + }), + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_store_installing_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_store_installing_body"), fontSize = 12, color = "on_surface_variant" }), + }), + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_store_applying_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_store_applying_body"), fontSize = 12, color = "on_surface_variant" }), + }), + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_store_community_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_store_community_body"), fontSize = 12, color = "on_surface_variant" }), + }), + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_how_to_submite_config_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_how_to_submite_config_body"), fontSize = 12, color = "on_surface_variant" }), + }), + ui.column({ gap = 4 }, { + ui.label({ text = tr("info_store_rate_limits_title"), fontSize = 13, fontWeight = "bold", color = "on_surface" }), + ui.label({ text = tr("info_store_rate_limits_body"), fontSize = 12, color = "on_surface_variant" }), + }), + }), + })) +end + +local function renderList() + + pickSlots = {} + local tiles = {} + local list = listConfig or {} + + for count = 1, #list, 1 do + local data = list[count] + local slotIndex = count - 1 + pickSlots[slotIndex] = data.path + + queuePreviewDownload(data.name) + + local imagePath = previewCache[data.name] or previewImage + + table.insert(tiles, ui.column({ gap = 4, key = data.path, align = "center" }, { + ui.image({ + path = imagePath, + width = previewWidth, + height = previewHeight, + fit = "cover", + radius = 8, + onClick = "" + }), + ui.row( {gap = 12, align = "start"}, { + ui.button({ text = tr("install"), onClick = function() + downloadConfig(data) + end + }), + ui.label({ + text = data.name, + fontSize = 11, + maxLines = 1, + maxWidth = 120, + textAlign = "center", + }), + } ), + })) + end + local rows = {} + local row = {} + for i, tile in ipairs(tiles) do + table.insert(row, tile) + if #row == columns or i == #tiles then + table.insert(rows, ui.row({ gap = 12, align = "start" }, row)) + row = {} + end + end + + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = tr("title"), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.label({ text = tr("store_title"), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ text = tr("show_list"), onClick = function() + selectedView = 1 + render() + end + }), + ui.button({ text = "Info", onClick = function() + renderInfoStore() + end + }), + ui.button({ text = tr("refresh"), onClick = "getFetchList"}), + ui.button({ glyph = "close", onClick = "onCloseClicked" }), + }), + ui.scroll({ gap = 12, align = "stretch", flexGrow = 1 }, rows), + })) +end + +-- Installed config details panel + +local function renderConfig(data: infoConfig) + local rows = { + ui.image({ + path = configBox .. "/" .. data.name .. "/preview.png", + width = configWidth, + height = configHeight, + fit = "cover", + radius = 8, + }), + ui.label({ text = data.name, align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.label({ text = tr("created_by", { author = data.author }), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.label({ text = tr("origin", { origin = data.origin }), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.label({ text = tr("description", { description = data.description or "" }), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ glyph = "trash", onClick = function() + renderDeleteConfirmation(data.name) + end + }), + ui.button({ glyph = "close", onClick = "render" }), + } + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.scroll({ gap = 12, align = "stretch", flexGrow = 1 }, rows), + })) +end + +-- List installed configs from ~/Config-Swap + +function getListInstall() + local localPath = configBox + local list = noctalia.listDir(localPath) + local listShow: { infoConfig } = {} + + for i, entryName in ipairs(list) do + local infoPath = configBox .. "/" .. entryName .. "/info.json" + local content = noctalia.readFile(infoPath) + local data = content and noctalia.json.decode(content) or nil + + if not data then + -- Fallback entry when info.json is missing or invalid. + table.insert(listShow, { + name = entryName, + path = "config/" .. entryName, + author = "None", + origin = "None", + preview = nil, + description = nil, + wallpaperPath = nil, + depedencie = false, + }) + continue + end + + table.insert(listShow, { + name = data.name, + path = data.path, + author = data.author, + origin = data.origin, + preview = data.preview, + description = data.description, + wallpaperPath = data.wallpaperPath, + depedencie = data.depedencie, + }) + end + return listShow +end + +-- Render installed configs grid + +local function renderInstall() + pickSlots = {} + local tiles = {} + local list = getListInstall() or {} + for count = 1, #list, 1 do + local data = list[count] + local slotIndex = count - 1 + pickSlots[slotIndex] = data.path + table.insert(tiles, ui.column({ gap = 4, key = data.path, align = "center" }, { + ui.image({ + path = configBox .. "/" .. data.name .. "/preview.png", + width = previewWidth, + height = previewHeight, + fit = "cover", + radius = 8, + onClick = function() + renderConfig(data) + end + }), + ui.row( {gap = 12, align = "start"}, { + ui.button({ text = "delete", onClick = function() + renderDeleteConfirmation(data.name) + end + }), + ui.label({ + text = data.name, + fontSize = 11, + maxLines = 1, + maxWidth = 120, + textAlign = "center", + }), + ui.button({ text = "apply", onClick = function() + renderConfirmApply(data) + end + }), + } ), + })) + end + local rows = {} + local row = {} + for i, tile in ipairs(tiles) do + table.insert(row, tile) + if #row == columns or i == #tiles then + table.insert(rows, ui.row({ gap = 12, align = "start" }, row)) + row = {} + end + end + panel.render(ui.column({ flexGrow = 1, gap = 16 }, { + ui.row({ align = "center", justify = "space_between", gap = 8 }, { + ui.label({ text = tr("title"), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.label({ text = tr("installed_title"), align = "center", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }), + ui.button({ text = tr("show_store"), onClick = function() + selectedView = 2 + render() + end + }), + ui.button({ text = "Setting", onClick = function() + renderSetting() + end + }), + ui.button({ text = tr("refresh"), onClick = "getFetchList"}), + ui.button({ glyph = "close", onClick = "onCloseClicked" }), + }), + ui.scroll({ gap = 12, align = "stretch", flexGrow = 1 }, rows), + })) +end + +-- Root view router + +function render() + if selectedView == 0 then + welcomeWarning() + end + if selectedView == 1 then + renderInstall() + end + if selectedView == 2 then + renderList() + end +end + +-- Fetch available configs from GitHub + +function getFetchList(onDone) + allConfig = {} + noctalia.http(requestFetchList, function(respond) + noctalia.log("raw body: " .. tostring(respond.body)) + if not respond.ok then + noctalia.notify("Error", respond.status) + end + local data, err = noctalia.json.decode(respond.body) + if err then + noctalia.log(err) + return + end + for i, item in ipairs(data) do + table.insert(allConfig, { + name = item.name, + path = item.path, + author = nil, + depedencie = nil, + description = nil, + origin = nil, + preview = nil, + wallpaperPath = nil, + }) + end + listConfig = allConfig + render() + end) +end + +-- Plugin entry points + +function onOpen(_context) + render() +end + +function onCloseClicked() + panel.close() +end \ No newline at end of file diff --git a/config-swap/config-swap-service.luau b/config-swap/config-swap-service.luau new file mode 100644 index 0000000..ee8a9f7 --- /dev/null +++ b/config-swap/config-swap-service.luau @@ -0,0 +1 @@ +noctalia.mkdirAll("~/Config-Swap") \ No newline at end of file diff --git a/config-swap/config-swap-widget.luau b/config-swap/config-swap-widget.luau new file mode 100644 index 0000000..e9b9d62 --- /dev/null +++ b/config-swap/config-swap-widget.luau @@ -0,0 +1,7 @@ +function update() + barWidget.setGlyph("file") +end + +function onClick() + noctalia.togglePanel("tadomika_ari/config-swap:panel") +end \ No newline at end of file diff --git a/config-swap/plugin.toml b/config-swap/plugin.toml new file mode 100644 index 0000000..489d94c --- /dev/null +++ b/config-swap/plugin.toml @@ -0,0 +1,24 @@ +id = "tadomika_ari/config-swap" +name = "Config Swap" +version = "1.0.0" +plugin_api = 4 +author = "TadomiKa-Ari" +license = "MIT" +dependencies = ["cp", "rm"] +icon = "file" +description = "A Noctalia widget for applying Configuration file with one click" +tags = ["utility"] + +[[widget]] +id = "widget" +entry = "config-swap-widget.luau" + +[[panel]] +id = "panel" +entry = "config-swap-panel.luau" +width = 1000 +height = 800 + +[[service]] +id = "start" +entry = "config-swap-service.luau" \ No newline at end of file diff --git a/config-swap/thumbnail.webp b/config-swap/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..fb975e84b8b551c1ac2a63681c8c211f6d08ce5e GIT binary patch literal 57732 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%0AKAWl*RVfdvvq2Rz|2LzlwJ7#{VddA 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 J^yV-y008elAcp_| literal 0 HcmV?d00001 diff --git a/config-swap/translations/en.json b/config-swap/translations/en.json new file mode 100644 index 0000000..5c48dc5 --- /dev/null +++ b/config-swap/translations/en.json @@ -0,0 +1,47 @@ +{ + "panel": { + "apply": "Apply", + "apply_notification_title": "Apply", + "created_by": "Created by {author}", + "description": "Description: {description}", + "download_failed": "Download failed", + "download_ok": "Download complete", + "install": "Install", + "install_notification_title": "Install", + "installed_title": "Installed Configs", + "notification_title": "Config Swap", + "origin": "Origin: {origin}", + "refresh": "Refresh", + "show_list": "Show List", + "show_store": "Show Store", + "store_title": "Config Store", + "title": "Config Swap", + "welcome_message_title": "Welcome to Config Swap!", + "welcome_message1": "Please read this carefully before you continue.", + "welcome_message2": "This plugin can replace your current Noctalia configuration. We recommend backing up your current settings first — use the Save button in the Installed section. Backups are stored in ~/Config-Swap.", + "not_agree": "Not now", + "agree": "I understand", + "confirmation": "Apply this configuration?", + "description_confirmation": "This will replace your current settings.toml and wallpaper. A backup is not created automatically unless you saved one first.", + "cancel": "Cancel", + "confirmation_delete": "Are you sure too delete ", + "delete": "delete", + "description_setting1": "Save your current configuration under a custom name at ~/Config-Swap/{name}. A default info.json is created and can be edited later at ~/Config-Swap/{name}/info.json. To set a preview, you can add preview.png to the config folder. This also works for wallpapers using wallpaper.png", + "save": "save", + "info_store_title": "Info Store section", + "info_store_github_button": "github", + "info_store_copy_link_success": "copy link success", + "info_store_what_is_title": "What is the Store?", + "info_store_what_is_body": "The Store lists community-submitted configuration profiles hosted on the Config-Swap-Box GitHub repository. Each profile bundles a settings.toml, a preview image, and an optional wallpaper.", + "info_store_installing_title": "Installing a profile", + "info_store_installing_body": "Pressing install downloads the profile's files into ~/Config-Swap/{name}. This does not change your current configuration yet.", + "info_store_applying_title": "Applying a profile", + "info_store_applying_body": "Pressing apply replaces your active settings.toml and wallpaper with the selected profile. This is not reversible unless you saved a backup first from the Setting section.", + "info_store_community_title": "Community content", + "info_store_community_body": "Profiles are submitted by community members and are reviewed by the owner.", + "info_store_rate_limits_title": "Rate limits", + "info_store_rate_limits_body": "The store list is fetched from the GitHub API, which limits unauthenticated requests. Avoid refreshing repeatedly in a short period of time.", + "info_how_to_submite_config_title": "How to submit a configuration", + "info_how_to_submite_config_body": "You can contribute to Config Swap by adding your own configuration files and wallpaper to the store so others can use them.\n\nTo do so:\n* Go to the Settings section and save your configuration. The plugin will copy your settings.toml and create an info.json file.\n* Take a preview image and wallpaper, then go to ~/Config-Swap/{name} and copy your preview.png and wallpaper.png files. The exact names are required.\n* Update your info.json with important information such as the author and description.\n* Go to the GitHub page linked from the information panel in the Store section and create a pull request.\n* Wait for review, and then your configuration can be shared." + } +} \ No newline at end of file