From f3f19337a34bcafa3f9e1feb0d9bad720a5d112e Mon Sep 17 00:00:00 2001 From: Insality Date: Mon, 27 Oct 2025 01:15:57 +0200 Subject: [PATCH] Update --- druid/editor_scripts/core/asset_store.lua | 132 ++++++------------ .../core/asset_store_internal.lua | 21 +++ druid/editor_scripts/core/installer.lua | 13 +- druid/editor_scripts/core/path_replacer.lua | 22 --- druid/editor_scripts/core/ui_components.lua | 52 ++----- druid/editor_scripts/druid.editor_script | 2 +- game.project | 2 +- 7 files changed, 83 insertions(+), 161 deletions(-) create mode 100644 druid/editor_scripts/core/asset_store_internal.lua delete mode 100644 druid/editor_scripts/core/path_replacer.lua diff --git a/druid/editor_scripts/core/asset_store.lua b/druid/editor_scripts/core/asset_store.lua index 95dacdc..3328619 100644 --- a/druid/editor_scripts/core/asset_store.lua +++ b/druid/editor_scripts/core/asset_store.lua @@ -3,54 +3,10 @@ local installer = require("druid.editor_scripts.core.installer") local ui_components = require("druid.editor_scripts.core.ui_components") +local internal = require("druid.editor_scripts.core.asset_store_internal") local M = {} -local STORE_URL = "https://insality.github.io/core/druid_widget_store.json" - - ----Fetch widget data from the remote store ----@return table|nil, string|nil - Store data or nil, error message or nil -local function fetch_store_data() - print("Fetching widget data from:", STORE_URL) - - local response = http.request(STORE_URL, { - as = "json" - }) - - if response.status ~= 200 then - return nil, "Failed to fetch store data. HTTP status: " .. response.status - end - - if not response.body or not response.body.items then - return nil, "Invalid store data format" - end - - print("Successfully fetched", #response.body.items, "widgets") - return response.body, nil -end - - ----Filter items based on author and tag filters ----@param items table - List of widget items ----@param author_filter string - Author filter value ----@param tag_filter string - Tag filter value ----@return table - Filtered list of items -local function filter_items(items, author_filter, tag_filter) - local filtered = {} - - for _, item in ipairs(items) do - local author_match = author_filter == "All Authors" or item.author == author_filter - local tag_match = tag_filter == "All Categories" or (item.tags and table.concat(item.tags, ","):find(tag_filter)) - - if author_match and tag_match then - table.insert(filtered, item) - end - end - - return filtered -end - ---Handle widget installation ---@param item table - Widget item to install @@ -116,37 +72,25 @@ end ---Open the asset store dialog -function M.open_asset_store() - print("Opening Druid Asset Store") +function M.open_asset_store(store_url) + print("Opening Druid Asset Store from:", store_url) -- Fetch data synchronously before creating the dialog - local store_data, fetch_error = fetch_store_data() - local initial_items = {} - local initial_loading = false - local initial_error = nil - - if store_data then - initial_items = store_data.items - print("Successfully loaded", #initial_items, "widgets") - else - initial_error = fetch_error + local store_data, fetch_error = internal.download_json(store_url) + if not store_data then print("Failed to load widgets:", fetch_error) + return end + print("Successfully loaded", #store_data.items, "widgets") + local initial_items = store_data.items local dialog_component = editor.ui.component(function(props) - editor.prefs.set("druid.asset_install_folder", "/widget") -- State management local items, set_items = editor.ui.use_state(initial_items) - local loading, set_loading = editor.ui.use_state(initial_loading) - local error_message, set_error_message = editor.ui.use_state(initial_error) local install_folder, set_install_folder = editor.ui.use_state(editor.prefs.get("druid.asset_install_folder") or installer.get_default_install_folder()) - local author_filter, set_author_filter = editor.ui.use_state("All Authors") - local tag_filter, set_tag_filter = editor.ui.use_state("All Categories") + local search_query, set_search_query = editor.ui.use_state("") local install_status, set_install_status = editor.ui.use_state("") - -- Filter items - local filtered_items = editor.ui.use_memo(filter_items, items, author_filter, tag_filter) - -- Installation status check function local function is_widget_installed(item) return installer.is_widget_installed(item, install_folder) @@ -174,27 +118,43 @@ function M.open_asset_store() local content_children = {} -- Settings section - table.insert(content_children, editor.ui.label({ + table.insert(content_children, editor.ui.horizontal({ spacing = editor.ui.SPACING.MEDIUM, - text = "Installation Folder: " .. install_folder, - color = editor.ui.COLOR.TEXT + children = { + editor.ui.label({ + spacing = editor.ui.SPACING.MEDIUM, + text = "Installation Folder:", + color = editor.ui.COLOR.TEXT + }), + + editor.ui.string_field({ + value = install_folder, + on_value_changed = set_install_folder, + title = "Installation Folder:", + tooltip = "The folder to install the assets to", + }), + } })) - -- Filter section (only show if we have items) - if #items > 0 then - table.insert(content_children, editor.ui.label({ - spacing = editor.ui.SPACING.MEDIUM, - text = "Filters: Author: " .. author_filter .. ", Category: " .. tag_filter, - color = editor.ui.COLOR.TEXT - })) - end + -- Search section + table.insert(content_children, editor.ui.horizontal({ + spacing = editor.ui.SPACING.MEDIUM, + children = { + editor.ui.label({ + text = "Search:", + color = editor.ui.COLOR.TEXT + }), + editor.ui.string_field({ + value = search_query, + on_value_changed = set_search_query, + title = "Search:", + tooltip = "Search for widgets by title, author, or description", + }) + }, + })) -- Main content area - if loading then - table.insert(content_children, ui_components.create_loading_indicator("Loading widget store...")) - elseif error_message then - table.insert(content_children, ui_components.create_error_message(error_message)) - elseif #filtered_items == 0 then + if #items == 0 then table.insert(content_children, editor.ui.label({ text = "No widgets found matching the current filters.", color = editor.ui.COLOR.HINT, @@ -202,7 +162,7 @@ function M.open_asset_store() })) else table.insert(content_children, ui_components.create_widget_list( - filtered_items, is_widget_installed, on_install, on_open_api + items, is_widget_installed, on_install, on_open_api )) end @@ -219,7 +179,7 @@ function M.open_asset_store() title = "Druid Asset Store", content = editor.ui.vertical({ spacing = editor.ui.SPACING.SMALL, - padding = editor.ui.PADDING.NONE, + padding = editor.ui.PADDING.SMALL, children = content_children }), buttons = { @@ -231,11 +191,7 @@ function M.open_asset_store() }) end) - local result = editor.ui.show_dialog(dialog_component({})) - - -- Save the install folder preference (this will be handled by the state management in the dialog) - - return result + return editor.ui.show_dialog(dialog_component({})) end diff --git a/druid/editor_scripts/core/asset_store_internal.lua b/druid/editor_scripts/core/asset_store_internal.lua new file mode 100644 index 0000000..2733f53 --- /dev/null +++ b/druid/editor_scripts/core/asset_store_internal.lua @@ -0,0 +1,21 @@ +local M = {} + +---Download a JSON file from a URL +---@param json_url string - The URL to download the JSON from +---@return table|nil, string|nil - The JSON data or nil, error message or nil +function M.download_json(json_url) + local response = http.request(json_url, { as = "json" }) + + if response.status ~= 200 then + return nil, "Failed to fetch store data. HTTP status: " .. response.status + end + + if not response.body or not response.body.items then + return nil, "Invalid store data format" + end + + return response.body, nil +end + + +return M diff --git a/druid/editor_scripts/core/installer.lua b/druid/editor_scripts/core/installer.lua index dcf1d91..5fc485d 100644 --- a/druid/editor_scripts/core/installer.lua +++ b/druid/editor_scripts/core/installer.lua @@ -1,8 +1,8 @@ -local base64 = require("druid.editor_scripts.core.base64") -local path_replacer = require("druid.editor_scripts.core.path_replacer") --- Module for handling widget installation from zip files --- Downloads zip files and extracts them to the specified folder +local base64 = require("druid.editor_scripts.core.base64") + local M = {} local DEFAULT_INSTALL_FOLDER = "/widget" @@ -79,14 +79,13 @@ function M.install_widget(item, install_folder) print("Zip file removed successfully") -- Process paths within the extracted widget - local files_in_folder = path_replacer.get_all_files(folder_path) - pprint(files_in_folder) + --local files_in_folder = path_replacer.get_all_files(folder_path) + --pprint(files_in_folder) --if not path_replacer.process_widget_paths(install_folder .. "/" .. folder_name, new_base_path) then -- return false, "Failed to process widget paths" --end - return true, "Widget installed successfully" end @@ -96,8 +95,8 @@ end ---@param install_folder string - Install folder to check in ---@return boolean - True if widget is already installed function M.is_widget_installed(item, install_folder) - -- For now, assume widgets are not installed to avoid path issues - return false + local p = editor.resource_attributes(install_folder .. "/" .. item.id) + return p.exists end diff --git a/druid/editor_scripts/core/path_replacer.lua b/druid/editor_scripts/core/path_replacer.lua deleted file mode 100644 index f38505a..0000000 --- a/druid/editor_scripts/core/path_replacer.lua +++ /dev/null @@ -1,22 +0,0 @@ ---- Module for replacing paths in extracted widget files ---- Handles updating require statements and file paths to match the installation location - -local M = {} - - ----Recursively get all files in a directory ----@param dir_path string - Directory path to scan ----@param extension string|nil - Optional file extension filter (e.g., ".lua") ----@return string[] - List of file paths -function M.get_all_files(dir_path, extension) - local attributes = editor.resource_attributes(dir_path) - local files = io.popen("ls -R " .. dir_path) - for line in files:lines() do - print(line) - end - pprint(files) - return files -end - - -return M diff --git a/druid/editor_scripts/core/ui_components.lua b/druid/editor_scripts/core/ui_components.lua index ca125ba..045b5a8 100644 --- a/druid/editor_scripts/core/ui_components.lua +++ b/druid/editor_scripts/core/ui_components.lua @@ -162,9 +162,12 @@ function M.create_widget_item(item, is_installed, on_install, on_open_api) end return editor.ui.horizontal({ - spacing = editor.ui.SPACING.MEDIUM, - padding = editor.ui.PADDING.MEDIUM, + spacing = editor.ui.SPACING.NONE, + padding = editor.ui.PADDING.SMALL, children = { + editor.ui.separator({ + orientation = editor.ui.ORIENTATION.HORIZONTAL, + }), -- Widget icon placeholder editor.ui.label({ text = "📦", @@ -227,12 +230,13 @@ function M.create_widget_item(item, is_installed, on_install, on_open_api) -- Action buttons editor.ui.vertical({ - spacing = editor.ui.SPACING.SMALL, + spacing = editor.ui.SPACING.MEDIUM, children = { editor.ui.button({ - text = is_installed and "Reinstall" or "Install", + + text = "Install", on_pressed = on_install, - enabled = true + enabled = is_installed == false }), editor.ui.button({ text = "API", @@ -240,7 +244,7 @@ function M.create_widget_item(item, is_installed, on_install, on_open_api) enabled = item.api ~= nil }) } - }) + }), } }) end @@ -274,40 +278,4 @@ function M.create_widget_list(items, is_installed_func, on_install, on_open_api) end ----Create a loading indicator ----@param message string - Loading message ----@return userdata - UI component -function M.create_loading_indicator(message) - return editor.ui.vertical({ - spacing = editor.ui.SPACING.MEDIUM, - alignment = editor.ui.ALIGNMENT.CENTER, - children = { - editor.ui.label({ - text = message or "Loading...", - color = editor.ui.COLOR.TEXT, - alignment = editor.ui.ALIGNMENT.CENTER - }) - } - }) -end - - ----Create an error message display ----@param message string - Error message ----@return userdata - UI component -function M.create_error_message(message) - return editor.ui.vertical({ - spacing = editor.ui.SPACING.MEDIUM, - alignment = editor.ui.ALIGNMENT.CENTER, - children = { - editor.ui.label({ - text = "Error: " .. message, - color = editor.ui.COLOR.ERROR, - alignment = editor.ui.ALIGNMENT.CENTER - }) - } - }) -end - - return M diff --git a/druid/editor_scripts/druid.editor_script b/druid/editor_scripts/druid.editor_script index 8f45587..de7a0a1 100644 --- a/druid/editor_scripts/druid.editor_script +++ b/druid/editor_scripts/druid.editor_script @@ -74,7 +74,7 @@ function M.get_commands() label = "[Druid] Asset Store", locations = { "Edit" }, run = function() - return asset_store.open_asset_store() + return asset_store.open_asset_store("https://insality.github.io/core/druid_widget_store.json") end }, diff --git a/game.project b/game.project index e1be0a5..8ee53b8 100644 --- a/game.project +++ b/game.project @@ -58,7 +58,7 @@ cssfile = /builtins/manifests/web/dark_theme.css show_console_banner = 0 [native_extension] -app_manifest = +app_manifest = [graphics] texture_profiles = /builtins/graphics/default.texture_profiles