mirror of
https://github.com/minetest/minetest.git
synced 2024-11-30 11:33:44 +01:00
ContentDB GUI: Load package list asynchronously (#13551)
This commit is contained in:
parent
e4bedc7ea8
commit
526c5f2348
@ -23,9 +23,18 @@ if not core.get_http_api then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local store = {
|
||||||
|
loading = false,
|
||||||
|
load_ok = false,
|
||||||
|
load_error = false,
|
||||||
|
|
||||||
-- Unordered preserves the original order of the ContentDB API,
|
-- Unordered preserves the original order of the ContentDB API,
|
||||||
-- before the package list is ordered based on installed state.
|
-- before the package list is ordered based on installed state.
|
||||||
local store = { packages = {}, packages_full = {}, packages_full_unordered = {}, aliases = {} }
|
packages = {},
|
||||||
|
packages_full = {},
|
||||||
|
packages_full_unordered = {},
|
||||||
|
aliases = {},
|
||||||
|
}
|
||||||
|
|
||||||
local http = core.get_http_api()
|
local http = core.get_http_api()
|
||||||
|
|
||||||
@ -65,7 +74,7 @@ local REASON_DEPENDENCY = "dependency"
|
|||||||
-- encodes for use as URL parameter or path component
|
-- encodes for use as URL parameter or path component
|
||||||
local function urlencode(str)
|
local function urlencode(str)
|
||||||
return str:gsub("[^%a%d()._~-]", function(char)
|
return str:gsub("[^%a%d()._~-]", function(char)
|
||||||
return string.format("%%%02X", string.byte(char))
|
return ("%%%02X"):format(char:byte())
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
assert(urlencode("sample text?") == "sample%20text%3F")
|
assert(urlencode("sample text?") == "sample%20text%3F")
|
||||||
@ -432,7 +441,7 @@ function install_dialog.get_formspec()
|
|||||||
"container_end[]",
|
"container_end[]",
|
||||||
}
|
}
|
||||||
|
|
||||||
return table.concat(formspec, "")
|
return table.concat(formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
function install_dialog.handle_submit(this, fields)
|
function install_dialog.handle_submit(this, fields)
|
||||||
@ -577,29 +586,33 @@ local function get_screenshot(package)
|
|||||||
return defaulttexturedir .. "loading_screenshot.png"
|
return defaulttexturedir .. "loading_screenshot.png"
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.load()
|
local function fetch_pkgs(param)
|
||||||
local version = core.get_version()
|
local version = core.get_version()
|
||||||
local base_url = core.settings:get("contentdb_url")
|
local base_url = core.settings:get("contentdb_url")
|
||||||
local url = base_url ..
|
local url = base_url ..
|
||||||
"/api/packages/?type=mod&type=game&type=txp&protocol_version=" ..
|
"/api/packages/?type=mod&type=game&type=txp&protocol_version=" ..
|
||||||
core.get_max_supp_proto() .. "&engine_version=" .. urlencode(version.string)
|
core.get_max_supp_proto() .. "&engine_version=" .. param.urlencode(version.string)
|
||||||
|
|
||||||
for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
|
for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
|
||||||
item = item:trim()
|
item = item:trim()
|
||||||
if item ~= "" then
|
if item ~= "" then
|
||||||
url = url .. "&hide=" .. urlencode(item)
|
url = url .. "&hide=" .. param.urlencode(item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local http = core.get_http_api()
|
||||||
local response = http.fetch_sync({ url = url })
|
local response = http.fetch_sync({ url = url })
|
||||||
if not response.succeeded then
|
if not response.succeeded then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
store.packages_full = core.parse_json(response.data) or {}
|
local packages = core.parse_json(response.data)
|
||||||
store.aliases = {}
|
if not packages or #packages == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local aliases = {}
|
||||||
|
|
||||||
for _, package in pairs(store.packages_full) do
|
for _, package in pairs(packages) do
|
||||||
local name_len = #package.name
|
local name_len = #package.name
|
||||||
-- This must match what store.update_paths() does!
|
-- This must match what store.update_paths() does!
|
||||||
package.id = package.author:lower() .. "/"
|
package.id = package.author:lower() .. "/"
|
||||||
@ -609,22 +622,58 @@ function store.load()
|
|||||||
package.id = package.id .. package.name
|
package.id = package.id .. package.name
|
||||||
end
|
end
|
||||||
|
|
||||||
package.url_part = urlencode(package.author) .. "/" .. urlencode(package.name)
|
package.url_part = param.urlencode(package.author) .. "/" .. param.urlencode(package.name)
|
||||||
|
|
||||||
if package.aliases then
|
if package.aliases then
|
||||||
for _, alias in ipairs(package.aliases) do
|
for _, alias in ipairs(package.aliases) do
|
||||||
-- We currently don't support name changing
|
-- We currently don't support name changing
|
||||||
local suffix = "/" .. package.name
|
local suffix = "/" .. package.name
|
||||||
if alias:sub(-#suffix) == suffix then
|
if alias:sub(-#suffix) == suffix then
|
||||||
store.aliases[alias:lower()] = package.id
|
aliases[alias:lower()] = package.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
store.packages_full_unordered = store.packages_full
|
return { packages = packages, aliases = aliases }
|
||||||
store.packages = store.packages_full
|
end
|
||||||
store.loaded = true
|
|
||||||
|
local function sort_and_filter_pkgs()
|
||||||
|
store.update_paths()
|
||||||
|
store.sort_packages()
|
||||||
|
store.filter_packages(search_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
function store.load()
|
||||||
|
if store.load_ok then
|
||||||
|
sort_and_filter_pkgs()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if store.loading then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
store.loading = true
|
||||||
|
core.handle_async(
|
||||||
|
fetch_pkgs,
|
||||||
|
{ urlencode = urlencode },
|
||||||
|
function(result)
|
||||||
|
if result then
|
||||||
|
store.packages = result.packages
|
||||||
|
store.packages_full = result.packages
|
||||||
|
store.packages_full_unordered = result.packages
|
||||||
|
store.aliases = result.aliases
|
||||||
|
sort_and_filter_pkgs()
|
||||||
|
|
||||||
|
store.load_ok = true
|
||||||
|
store.load_error = false
|
||||||
|
else
|
||||||
|
store.load_error = true
|
||||||
|
end
|
||||||
|
|
||||||
|
store.loading = false
|
||||||
|
core.event_handler("Refresh")
|
||||||
|
end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.update_paths()
|
function store.update_paths()
|
||||||
@ -735,7 +784,29 @@ function store.filter_packages(query)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function get_info_formspec(text)
|
||||||
|
local H = 9.5
|
||||||
|
return table.concat({
|
||||||
|
"formspec_version[6]",
|
||||||
|
"size[15.75,9.5]",
|
||||||
|
not TOUCHSCREEN_GUI and "position[0.5,0.55]" or "",
|
||||||
|
|
||||||
|
"label[4,4.35;", text, "]",
|
||||||
|
"container[0,", H - 0.8 - 0.375, "]",
|
||||||
|
"button[0.375,0;5,0.8;back;", fgettext("Back to Main Menu"), "]",
|
||||||
|
"container_end[]",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
function store.get_formspec(dlgdata)
|
function store.get_formspec(dlgdata)
|
||||||
|
if store.loading then
|
||||||
|
return get_info_formspec(fgettext("Loading..."))
|
||||||
|
end
|
||||||
|
if store.load_error then
|
||||||
|
return get_info_formspec(fgettext("No packages could be retrieved"))
|
||||||
|
end
|
||||||
|
assert(store.load_ok)
|
||||||
|
|
||||||
store.update_paths()
|
store.update_paths()
|
||||||
|
|
||||||
dlgdata.pagemax = math.max(math.ceil(#store.packages / num_per_page), 1)
|
dlgdata.pagemax = math.max(math.ceil(#store.packages / num_per_page), 1)
|
||||||
@ -745,12 +816,10 @@ function store.get_formspec(dlgdata)
|
|||||||
|
|
||||||
local W = 15.75
|
local W = 15.75
|
||||||
local H = 9.5
|
local H = 9.5
|
||||||
local formspec
|
local formspec = {
|
||||||
if #store.packages_full > 0 then
|
"formspec_version[6]",
|
||||||
formspec = {
|
|
||||||
"formspec_version[3]",
|
|
||||||
"size[15.75,9.5]",
|
"size[15.75,9.5]",
|
||||||
"position[0.5,0.55]",
|
not TOUCHSCREEN_GUI and "position[0.5,0.55]" or "",
|
||||||
|
|
||||||
"style[status,downloading,queued;border=false]",
|
"style[status,downloading,queued;border=false]",
|
||||||
|
|
||||||
@ -759,12 +828,12 @@ function store.get_formspec(dlgdata)
|
|||||||
"field_close_on_enter[search_string;false]",
|
"field_close_on_enter[search_string;false]",
|
||||||
"image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]",
|
"image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]",
|
||||||
"image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;]",
|
"image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;]",
|
||||||
"dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
|
"dropdown[9.175,0;2.7875,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
|
||||||
"container_end[]",
|
"container_end[]",
|
||||||
|
|
||||||
-- Page nav buttons
|
-- Page nav buttons
|
||||||
"container[0,", H - 0.8 - 0.375, "]",
|
"container[0,", H - 0.8 - 0.375, "]",
|
||||||
"button[0.375,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
|
"button[0.375,0;5,0.8;back;", fgettext("Back to Main Menu"), "]",
|
||||||
|
|
||||||
"container[", W - 0.375 - 0.8*4 - 2, ",0]",
|
"container[", W - 0.375 - 0.8*4 - 2, ",0]",
|
||||||
"image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]",
|
"image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]",
|
||||||
@ -779,7 +848,7 @@ function store.get_formspec(dlgdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if number_downloading > 0 then
|
if number_downloading > 0 then
|
||||||
formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;downloading;"
|
formspec[#formspec + 1] = "button[12.5875,0.375;2.7875,0.8;downloading;"
|
||||||
if #download_queue > 0 then
|
if #download_queue > 0 then
|
||||||
formspec[#formspec + 1] = fgettext("$1 downloading,\n$2 queued", number_downloading, #download_queue)
|
formspec[#formspec + 1] = fgettext("$1 downloading,\n$2 queued", number_downloading, #download_queue)
|
||||||
else
|
else
|
||||||
@ -797,31 +866,21 @@ function store.get_formspec(dlgdata)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if num_avail_updates == 0 then
|
if num_avail_updates == 0 then
|
||||||
formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;status;"
|
formspec[#formspec + 1] = "button[12.5875,0.375;2.7875,0.8;status;"
|
||||||
formspec[#formspec + 1] = fgettext("No updates")
|
formspec[#formspec + 1] = fgettext("No updates")
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "]"
|
||||||
else
|
else
|
||||||
formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;update_all;"
|
formspec[#formspec + 1] = "button[12.5875,0.375;2.7875,0.8;update_all;"
|
||||||
formspec[#formspec + 1] = fgettext("Update All [$1]", num_avail_updates)
|
formspec[#formspec + 1] = fgettext("Update All [$1]", num_avail_updates)
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "]"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #store.packages == 0 then
|
if #store.packages == 0 then
|
||||||
formspec[#formspec + 1] = "label[4,3;"
|
formspec[#formspec + 1] = "label[4,4.75;"
|
||||||
formspec[#formspec + 1] = fgettext("No results")
|
formspec[#formspec + 1] = fgettext("No results")
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "]"
|
||||||
end
|
end
|
||||||
else
|
|
||||||
formspec = {
|
|
||||||
"size[12,7]",
|
|
||||||
"position[0.5,0.55]",
|
|
||||||
"label[4,3;", fgettext("No packages could be retrieved"), "]",
|
|
||||||
"container[0,", H - 0.8 - 0.375, "]",
|
|
||||||
"button[0,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
|
|
||||||
"container_end[]",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- download/queued tooltips always have the same message
|
-- download/queued tooltips always have the same message
|
||||||
local tooltip_colors = ";#dff6f5;#302c2e]"
|
local tooltip_colors = ";#dff6f5;#302c2e]"
|
||||||
@ -891,7 +950,7 @@ function store.get_formspec(dlgdata)
|
|||||||
formspec[#formspec + 1] = "container_end[]"
|
formspec[#formspec + 1] = "container_end[]"
|
||||||
|
|
||||||
-- description
|
-- description
|
||||||
local description_width = W - 0.375*5 - 0.85 - 2*0.7
|
local description_width = W - 0.375*5 - 0.85 - 2*0.7 - 0.15
|
||||||
formspec[#formspec + 1] = "textarea[1.855,0.3;"
|
formspec[#formspec + 1] = "textarea[1.855,0.3;"
|
||||||
formspec[#formspec + 1] = tostring(description_width)
|
formspec[#formspec + 1] = tostring(description_width)
|
||||||
formspec[#formspec + 1] = ",0.8;;;"
|
formspec[#formspec + 1] = ",0.8;;;"
|
||||||
@ -901,7 +960,7 @@ function store.get_formspec(dlgdata)
|
|||||||
formspec[#formspec + 1] = "container_end[]"
|
formspec[#formspec + 1] = "container_end[]"
|
||||||
end
|
end
|
||||||
|
|
||||||
return table.concat(formspec, "")
|
return table.concat(formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
function store.handle_submit(this, fields)
|
function store.handle_submit(this, fields)
|
||||||
@ -1042,16 +1101,8 @@ function store.handle_submit(this, fields)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function create_store_dlg(type)
|
function create_store_dlg(type)
|
||||||
if not store.loaded or #store.packages_full == 0 then
|
|
||||||
store.load()
|
|
||||||
end
|
|
||||||
|
|
||||||
store.update_paths()
|
|
||||||
store.sort_packages()
|
|
||||||
|
|
||||||
search_string = ""
|
search_string = ""
|
||||||
cur_page = 1
|
cur_page = 1
|
||||||
|
|
||||||
if type then
|
if type then
|
||||||
-- table.indexof does not work on tables that contain `nil`
|
-- table.indexof does not work on tables that contain `nil`
|
||||||
for i, v in pairs(filter_types_type) do
|
for i, v in pairs(filter_types_type) do
|
||||||
@ -1060,9 +1111,11 @@ function create_store_dlg(type)
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
filter_type = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
store.filter_packages(search_string)
|
store.load()
|
||||||
|
|
||||||
return dialog_create("store",
|
return dialog_create("store",
|
||||||
store.get_formspec,
|
store.get_formspec,
|
||||||
|
Loading…
Reference in New Issue
Block a user