Skip to content

Commit

Permalink
ContentDB redesign: Add package dialog
Browse files Browse the repository at this point in the history
Co-authored-by: Gregor Parzefall <[email protected]>
  • Loading branch information
rubenwardy and grorp committed Oct 5, 2024
1 parent 05cbd84 commit 78aab8c
Show file tree
Hide file tree
Showing 12 changed files with 529 additions and 130 deletions.
10 changes: 10 additions & 0 deletions builtin/common/misc_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ function core.formspec_escape(text)
end


local hypertext_escapes = {
["\\"] = "\\\\",
["<"] = "\\<",
[">"] = "\\>",
}
function core.hypertext_escape(text)
return text and text:gsub("[\\<>]", hypertext_escapes)
end


function core.wrap_text(text, max_length, as_table)
local result = {}
local line = {}
Expand Down
80 changes: 70 additions & 10 deletions builtin/mainmenu/content/contentdb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,23 @@ function contentdb.get_package_by_id(id)
end


function contentdb.calculate_package_id(type, author, name)
local id = author:lower() .. "/"
if (type == nil or type == "game") and #name > 5 and name:sub(#name - 4) == "_game" then
id = id .. name:sub(1, #name - 5)
else
id = id .. name
end
return id
end


function contentdb.get_package_by_info(author, name)
local id = contentdb.calculate_package_id(nil, author, name)
return contentdb.package_by_id[id]
end


-- Create a coroutine from `fn` and provide results to `callback` when complete (dead).
-- Returns a resumer function.
local function make_callback_coroutine(fn, callback)
Expand Down Expand Up @@ -415,15 +432,7 @@ local function fetch_pkgs(params)
local aliases = {}

for _, package in pairs(packages) do
local name_len = #package.name
-- This must match what contentdb.update_paths() does!
package.id = package.author:lower() .. "/"
if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
package.id = package.id .. package.name:sub(1, name_len - 5)
else
package.id = package.id .. package.name
end

package.id = params.calculate_package_id(package.type, package.author, package.name)
package.url_part = core.urlencode(package.author) .. "/" .. core.urlencode(package.name)

if package.aliases then
Expand All @@ -443,7 +452,7 @@ end

function contentdb.fetch_pkgs(callback)
contentdb.loading = true
core.handle_async(fetch_pkgs, nil, function(result)
core.handle_async(fetch_pkgs, { calculate_package_id = contentdb.calculate_package_id }, function(result)
if result then
contentdb.load_ok = true
contentdb.load_error = false
Expand Down Expand Up @@ -581,3 +590,54 @@ function contentdb.filter_packages(query, by_type)
end
end
end


function contentdb.get_full_package_info(package, callback)
assert(package)
if package.full_info then
callback(package.full_info)
return
end

local function fetch(params)
local version = core.get_version()
local base_url = core.settings:get("contentdb_url")

local languages
local current_language = core.get_language()
if current_language ~= "" then
languages = { current_language, "en;q=0.8" }
else
languages = { "en" }
end

local url = base_url ..
"/api/packages/" .. params.package.url_part .. "/for-client/?" ..
"protocol_version=" .. core.urlencode(core.get_max_supp_proto()) ..
"&engine_version=" .. core.urlencode(version.string) ..
"&formspec_version=" .. core.urlencode(core.get_formspec_version()) ..
"&include_images=false"
local http = core.get_http_api()
local response = http.fetch_sync({
url = url,
extra_headers = {
"Accept-Language: " .. table.concat(languages, ", ")
},
})
if not response.succeeded then
return nil
end

return core.parse_json(response.data)
end

local function my_callback(value)
package.full_info = value
callback(value)
end

if not core.handle_async(fetch, { package = package }, my_callback) then
core.log("error", "ERROR: async event failed")
callback(nil)
end
end
114 changes: 12 additions & 102 deletions builtin/mainmenu/content/dlg_contentdb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -46,48 +46,6 @@ local filter_types_type = {
}


local function install_or_update_package(this, package)
local install_parent
if package.type == "mod" then
install_parent = core.get_modpath()
elseif package.type == "game" then
install_parent = core.get_gamepath()
elseif package.type == "txp" then
install_parent = core.get_texturepath()
else
error("Unknown package type: " .. package.type)
end

if package.queued or package.downloading then
return
end

local function on_confirm()
local dlg = create_install_dialog(package)
dlg:set_parent(this)
this:hide()
dlg:show()

dlg:load_deps()
end

if package.type == "mod" and #pkgmgr.games == 0 then
local dlg = messagebox("install_game",
fgettext("You need to install a game before you can install a mod"))
dlg:set_parent(this)
this:hide()
dlg:show()
elseif not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then
local dlg = create_confirm_overwrite(package, on_confirm)
dlg:set_parent(this)
this:hide()
dlg:show()
else
on_confirm()
end
end


-- Resolves the package specification stored in auto_install_spec into an actual package.
-- May only be called after the package list has been loaded successfully.
local function resolve_auto_install_spec()
Expand Down Expand Up @@ -291,7 +249,7 @@ local function get_formspec(dlgdata)

-- image
formspec[#formspec + 1] = "image[0,0;1.5,1;"
formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package))
formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package, package.thumbnail, 1))
formspec[#formspec + 1] = "]"

-- title
Expand All @@ -301,52 +259,17 @@ local function get_formspec(dlgdata)
core.colorize("#BFBFBF", " by " .. package.author))
formspec[#formspec + 1] = "]"

-- buttons
local description_width = W - 2.625 - 2 * 0.7 - 2 * 0.15

local second_base = "image_button[-1.55,0;0.7,0.7;" .. core.formspec_escape(defaulttexturedir)
local third_base = "image_button[-2.4,0;0.7,0.7;" .. core.formspec_escape(defaulttexturedir)
formspec[#formspec + 1] = "container["
formspec[#formspec + 1] = W - 0.375*2
formspec[#formspec + 1] = ",0.1]"

if package.downloading then
formspec[#formspec + 1] = "animated_image[-1.7,-0.15;1,1;downloading;"
formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir)
formspec[#formspec + 1] = "cdb_downloading.png;3;400;]"
elseif package.queued then
formspec[#formspec + 1] = second_base
formspec[#formspec + 1] = "cdb_queued.png;queued;]"
elseif not package.path then
local elem_name = "install_" .. i .. ";"
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#71aa34]"
formspec[#formspec + 1] = second_base .. "cdb_add.png;" .. elem_name .. "]"
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Install") .. tooltip_colors
else
if package.installed_release < package.release then
-- The install_ action also handles updating
local elem_name = "install_" .. i .. ";"
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#28ccdf]"
formspec[#formspec + 1] = third_base .. "cdb_update.png;" .. elem_name .. "]"
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Update") .. tooltip_colors

description_width = description_width - 0.7 - 0.15
end

local elem_name = "uninstall_" .. i .. ";"
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#a93b3b]"
formspec[#formspec + 1] = second_base .. "cdb_clear.png;" .. elem_name .. "]"
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Uninstall") .. tooltip_colors
end

local web_elem_name = "view_" .. i .. ";"
formspec[#formspec + 1] = "image_button[-0.7,0;0.7,0.7;" ..
core.formspec_escape(defaulttexturedir) .. "cdb_viewonline.png;" .. web_elem_name .. "]"
formspec[#formspec + 1] = "tooltip[" .. web_elem_name ..
fgettext("View more information in a web browser") .. tooltip_colors
formspec[#formspec + 1] = "container_end[]"
-- button
formspec[#formspec + 1] = "button["
formspec[#formspec + 1] = W-0.375*2-2
formspec[#formspec + 1] = ",0.1;2,0.7;view_"
formspec[#formspec + 1] = i
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("View")
formspec[#formspec + 1] = "]"

-- description
local description_width = W - 2.625 - 2 * 0.7 - 2 * 0.15
formspec[#formspec + 1] = "textarea[1.855,0.3;"
formspec[#formspec + 1] = tostring(description_width)
formspec[#formspec + 1] = ",0.8;;;"
Expand Down Expand Up @@ -434,26 +357,13 @@ local function handle_submit(this, fields)
local package = contentdb.packages[i]
assert(package)

if fields["install_" .. i] then
install_or_update_package(this, package)
return true
end

if fields["uninstall_" .. i] then
local dlg = create_delete_content_dlg(package)
if fields["view_" .. i] then
local dlg = create_package_dialog(package)
dlg:set_parent(this)
this:hide()
dlg:show()
return true
end

if fields["view_" .. i] then
local url = ("%s/packages/%s?protocol_version=%d"):format(
core.settings:get("contentdb_url"), package.url_part,
core.get_max_supp_proto())
core.open_url(url)
return true
end
end

return false
Expand Down
42 changes: 42 additions & 0 deletions builtin/mainmenu/content/dlg_install.lua
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,45 @@ function create_install_dialog(package)

return dlg
end


function install_or_update_package(parent, package)
local install_parent
if package.type == "mod" then
install_parent = core.get_modpath()
elseif package.type == "game" then
install_parent = core.get_gamepath()
elseif package.type == "txp" then
install_parent = core.get_texturepath()
else
error("Unknown package type: " .. package.type)
end

if package.queued or package.downloading then
return
end

local function on_confirm()
local dlg = create_install_dialog(package)
dlg:set_parent(parent)
parent:hide()
dlg:show()

dlg:load_deps()
end

if package.type == "mod" and #pkgmgr.games == 0 then
local dlg = messagebox("install_game",
fgettext("You need to install a game before you can install a mod"))
dlg:set_parent(parent)
parent:hide()
dlg:show()
elseif not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then
local dlg = create_confirm_overwrite(package, on_confirm)
dlg:set_parent(parent)
parent:hide()
dlg:show()
else
on_confirm()
end
end
Loading

0 comments on commit 78aab8c

Please sign in to comment.