This commit is contained in:
Insality
2025-10-26 19:00:39 +02:00
parent 9fba1899da
commit 1f1438b4af
2 changed files with 170 additions and 163 deletions

View File

@@ -12,22 +12,22 @@ local STORE_URL = "https://insality.github.io/core/druid_widget_store.json"
---Fetch widget data from the remote store ---Fetch widget data from the remote store
---@return table|nil, string|nil - Store data or nil, error message or nil ---@return table|nil, string|nil - Store data or nil, error message or nil
local function fetch_store_data() local function fetch_store_data()
print("Fetching widget data from:", STORE_URL) print("Fetching widget data from:", STORE_URL)
local response = http.request(STORE_URL, { local response = http.request(STORE_URL, {
as = "json" as = "json"
}) })
if response.status ~= 200 then if response.status ~= 200 then
return nil, "Failed to fetch store data. HTTP status: " .. response.status return nil, "Failed to fetch store data. HTTP status: " .. response.status
end end
if not response.body or not response.body.items then if not response.body or not response.body.items then
return nil, "Invalid store data format" return nil, "Invalid store data format"
end end
print("Successfully fetched", #response.body.items, "widgets") print("Successfully fetched", #response.body.items, "widgets")
return response.body, nil return response.body, nil
end end
@@ -37,18 +37,18 @@ end
---@param tag_filter string - Tag filter value ---@param tag_filter string - Tag filter value
---@return table - Filtered list of items ---@return table - Filtered list of items
local function filter_items(items, author_filter, tag_filter) local function filter_items(items, author_filter, tag_filter)
local filtered = {} local filtered = {}
for _, item in ipairs(items) do for _, item in ipairs(items) do
local author_match = author_filter == "All Authors" or item.author == author_filter 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)) 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 if author_match and tag_match then
table.insert(filtered, item) table.insert(filtered, item)
end end
end end
return filtered return filtered
end end
@@ -58,29 +58,29 @@ end
---@param on_success function - Success callback ---@param on_success function - Success callback
---@param on_error function - Error callback ---@param on_error function - Error callback
local function handle_install(item, install_folder, on_success, on_error) local function handle_install(item, install_folder, on_success, on_error)
print("Installing widget:", item.id) print("Installing widget:", item.id)
local success, message = installer.install_widget(item, install_folder) local success, message = installer.install_widget(item, install_folder)
if success then if success then
print("Installation successful:", message) print("Installation successful:", message)
on_success(message) on_success(message)
else else
print("Installation failed:", message) print("Installation failed:", message)
on_error(message) on_error(message)
end end
end end
---Handle opening API documentation ---Handle opening API documentation
---@param item table - Widget item ---@param item table - Widget item
local function handle_open_api(item) local function handle_open_api(item)
if item.api then if item.api then
print("Opening API documentation:", item.api) print("Opening API documentation:", item.api)
editor.browse(item.api) editor.browse(item.api)
else else
print("No API documentation available for:", item.id) print("No API documentation available for:", item.id)
end end
end end
@@ -88,152 +88,154 @@ end
---@param success boolean - Whether installation was successful ---@param success boolean - Whether installation was successful
---@param message string - Status message ---@param message string - Status message
local function show_install_status(success, message) local function show_install_status(success, message)
local dialog_component = editor.ui.component(function() local dialog_component = editor.ui.component(function()
return editor.ui.dialog({ return editor.ui.dialog({
title = success and "Installation Successful" or "Installation Failed", title = success and "Installation Successful" or "Installation Failed",
content = editor.ui.vertical({ content = editor.ui.vertical({
spacing = editor.ui.SPACING.MEDIUM, spacing = editor.ui.SPACING.MEDIUM,
padding = editor.ui.PADDING.MEDIUM, padding = editor.ui.PADDING.MEDIUM,
children = { children = {
editor.ui.label({ editor.ui.label({
text = message, text = message,
color = success and editor.ui.COLOR.TEXT or editor.ui.COLOR.ERROR, color = success and editor.ui.COLOR.TEXT or editor.ui.COLOR.ERROR,
alignment = editor.ui.ALIGNMENT.LEFT alignment = editor.ui.ALIGNMENT.LEFT
}) })
} }
}), }),
buttons = { buttons = {
editor.ui.dialog_button({ editor.ui.dialog_button({
text = "OK", text = "OK",
default = true default = true
}) })
} }
}) })
end) end)
editor.ui.show_dialog(dialog_component({})) editor.ui.show_dialog(dialog_component({}))
end end
---Open the asset store dialog ---Open the asset store dialog
function M.open_asset_store() function M.open_asset_store()
print("Opening Druid Asset Store") print("Opening Druid Asset Store")
-- Fetch data synchronously before creating the dialog -- Fetch data synchronously before creating the dialog
local store_data, fetch_error = fetch_store_data() local store_data, fetch_error = fetch_store_data()
local initial_items = {} local initial_items = {}
local initial_loading = false local initial_loading = false
local initial_error = nil local initial_error = nil
if store_data then if store_data then
initial_items = store_data.items initial_items = store_data.items
print("Successfully loaded", #initial_items, "widgets") print("Successfully loaded", #initial_items, "widgets")
else else
initial_error = fetch_error initial_error = fetch_error
print("Failed to load widgets:", fetch_error) print("Failed to load widgets:", fetch_error)
end end
local dialog_component = editor.ui.component(function(props) local dialog_component = editor.ui.component(function(props)
editor.prefs.set("druid.asset_install_folder", "/widget") editor.prefs.set("druid.asset_install_folder", "/widget")
-- State management -- State management
local items, set_items = editor.ui.use_state(initial_items) local items, set_items = editor.ui.use_state(initial_items)
local loading, set_loading = editor.ui.use_state(initial_loading) local loading, set_loading = editor.ui.use_state(initial_loading)
local error_message, set_error_message = editor.ui.use_state(initial_error) 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 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 author_filter, set_author_filter = editor.ui.use_state("All Authors")
local tag_filter, set_tag_filter = editor.ui.use_state("All Categories") local tag_filter, set_tag_filter = editor.ui.use_state("All Categories")
local install_status, set_install_status = editor.ui.use_state("") local install_status, set_install_status = editor.ui.use_state("")
-- Filter items -- Filter items
local filtered_items = editor.ui.use_memo(filter_items, items, author_filter, tag_filter) local filtered_items = editor.ui.use_memo(filter_items, items, author_filter, tag_filter)
-- Installation status check function -- Installation status check function
local function is_widget_installed(item) local function is_widget_installed(item)
return installer.is_widget_installed(item, install_folder) return installer.is_widget_installed(item, install_folder)
end end
-- Installation handlers -- Installation handlers
local function on_install(item) local function on_install(item)
handle_install(item, install_folder, handle_install(item, install_folder,
function(message) function(message)
set_install_status("Success: " .. message) set_install_status("Success: " .. message)
show_install_status(true, message) show_install_status(true, message)
end, end,
function(message) function(message)
set_install_status("Error: " .. message) set_install_status("Error: " .. message)
show_install_status(false, message) show_install_status(false, message)
end end
) )
end end
local function on_open_api(item) local function on_open_api(item)
handle_open_api(item) handle_open_api(item)
end end
-- Build UI content -- Build UI content
local content_children = {} local content_children = {}
-- Settings section -- Settings section
table.insert(content_children, editor.ui.label({ table.insert(content_children, editor.ui.label({
text = "Installation Folder: " .. install_folder, spacing = editor.ui.SPACING.MEDIUM,
color = editor.ui.COLOR.TEXT text = "Installation Folder: " .. install_folder,
})) color = editor.ui.COLOR.TEXT
}))
-- Filter section (only show if we have items) -- Filter section (only show if we have items)
if #items > 0 then if #items > 0 then
table.insert(content_children, editor.ui.label({ table.insert(content_children, editor.ui.label({
text = "Filters: Author: " .. author_filter .. ", Category: " .. tag_filter, spacing = editor.ui.SPACING.MEDIUM,
color = editor.ui.COLOR.TEXT text = "Filters: Author: " .. author_filter .. ", Category: " .. tag_filter,
})) color = editor.ui.COLOR.TEXT
end }))
end
-- Main content area -- Main content area
if loading then if loading then
table.insert(content_children, ui_components.create_loading_indicator("Loading widget store...")) table.insert(content_children, ui_components.create_loading_indicator("Loading widget store..."))
elseif error_message then elseif error_message then
table.insert(content_children, ui_components.create_error_message(error_message)) table.insert(content_children, ui_components.create_error_message(error_message))
elseif #filtered_items == 0 then elseif #filtered_items == 0 then
table.insert(content_children, editor.ui.label({ table.insert(content_children, editor.ui.label({
text = "No widgets found matching the current filters.", text = "No widgets found matching the current filters.",
color = editor.ui.COLOR.HINT, color = editor.ui.COLOR.HINT,
alignment = editor.ui.ALIGNMENT.CENTER alignment = editor.ui.ALIGNMENT.CENTER
})) }))
else else
table.insert(content_children, ui_components.create_widget_list( table.insert(content_children, ui_components.create_widget_list(
filtered_items, is_widget_installed, on_install, on_open_api filtered_items, is_widget_installed, on_install, on_open_api
)) ))
end end
-- Install status message -- Install status message
if install_status ~= "" then if install_status ~= "" then
table.insert(content_children, editor.ui.label({ table.insert(content_children, editor.ui.label({
text = install_status, text = install_status,
color = install_status:find("Success") and editor.ui.COLOR.TEXT or editor.ui.COLOR.ERROR, color = install_status:find("Success") and editor.ui.COLOR.TEXT or editor.ui.COLOR.ERROR,
alignment = editor.ui.ALIGNMENT.CENTER alignment = editor.ui.ALIGNMENT.CENTER
})) }))
end end
return editor.ui.dialog({ return editor.ui.dialog({
title = "Druid Asset Store", title = "Druid Asset Store",
content = editor.ui.vertical({ content = editor.ui.vertical({
spacing = editor.ui.SPACING.MEDIUM, spacing = editor.ui.SPACING.SMALL,
padding = editor.ui.PADDING.MEDIUM, padding = editor.ui.PADDING.NONE,
children = content_children children = content_children
}), }),
buttons = { buttons = {
editor.ui.dialog_button({ editor.ui.dialog_button({
text = "Close", text = "Close",
cancel = true cancel = true
}) })
} }
}) })
end) end)
local result = editor.ui.show_dialog(dialog_component({})) local result = editor.ui.show_dialog(dialog_component({}))
-- Save the install folder preference (this will be handled by the state management in the dialog) -- Save the install folder preference (this will be handled by the state management in the dialog)
return result return result
end end

View File

@@ -184,12 +184,16 @@ function M.create_widget_item(item, is_installed, on_install, on_open_api)
text = item.title or item.id, text = item.title or item.id,
color = editor.ui.COLOR.TEXT color = editor.ui.COLOR.TEXT
}), }),
editor.ui.label({
text = version_text .. "",
color = editor.ui.COLOR.HINT
}),
editor.ui.label({ editor.ui.label({
text = "by " .. (item.author or "Unknown"), text = "by " .. (item.author or "Unknown"),
color = editor.ui.COLOR.HINT color = editor.ui.COLOR.HINT
}), }),
editor.ui.label({ editor.ui.label({
text = version_text .. "" .. size_text, text = "" .. size_text,
color = editor.ui.COLOR.HINT color = editor.ui.COLOR.HINT
}), }),
} }
@@ -262,9 +266,10 @@ function M.create_widget_list(items, is_installed_func, on_install, on_open_api)
end end
end end
return editor.ui.vertical({ return editor.ui.scroll({
spacing = editor.ui.SPACING.SMALL, content = editor.ui.vertical({
children = widget_items children = widget_items
})
}) })
end end