diff --git a/LICENSE.txt b/LICENSE.txt index 772f86728..5c01e2c3b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -106,6 +106,11 @@ grorp: textures/base/pack/place_btn.png derived by editing the text in aux1_btn.svg +Material Design, Google (Apache license v2.0): + textures/base/pack/contentdb_thumb_up.png + textures/base/pack/contentdb_thumb_down.png + textures/base/pack/contentdb_neutral.png + License of Luanti source code ------------------------------- diff --git a/builtin/async/mainmenu.lua b/builtin/async/mainmenu.lua index 0e9c222d1..c1d8618b4 100644 --- a/builtin/async/mainmenu.lua +++ b/builtin/async/mainmenu.lua @@ -1,5 +1,6 @@ core.log("info", "Initializing asynchronous environment") + function core.job_processor(func, serialized_param) local param = core.deserialize(serialized_param) @@ -7,3 +8,15 @@ function core.job_processor(func, serialized_param) return retval or core.serialize(nil) end + + +function core.get_http_accept_languages() + local languages + local current_language = core.get_language() + if current_language ~= "" then + languages = { current_language, "en;q=0.8" } + else + languages = { "en" } + end + return "Accept-Language: " .. table.concat(languages, ", ") +end diff --git a/builtin/mainmenu/content/contentdb.lua b/builtin/mainmenu/content/contentdb.lua index 963400a12..856924bd4 100644 --- a/builtin/mainmenu/content/contentdb.lua +++ b/builtin/mainmenu/content/contentdb.lua @@ -41,6 +41,7 @@ contentdb = { REASON_DEPENDENCY = "dependency", } +-- API documentation: https://content.luanti.org/help/api/ local function get_download_url(package, reason) local base_url = core.settings:get("contentdb_url") @@ -398,7 +399,6 @@ local function fetch_pkgs() local url = base_url .. "/api/packages/?type=mod&type=game&type=txp&protocol_version=" .. core.get_max_supp_proto() .. "&engine_version=" .. core.urlencode(version.string) - for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do item = item:trim() if item ~= "" then @@ -406,19 +406,11 @@ local function fetch_pkgs() end end - local languages - local current_language = core.get_language() - if current_language ~= "" then - languages = { current_language, "en;q=0.8" } - else - languages = { "en" } - end - local http = core.get_http_api() local response = http.fetch_sync({ url = url, extra_headers = { - "Accept-Language: " .. table.concat(languages, ", ") + core.get_http_accept_languages() }, }) if not response.succeeded then @@ -596,57 +588,54 @@ function contentdb.filter_packages(query, by_type) 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" } +local function get_package_info(key, path) + return function(package, callback) + assert(package) + if package[key] then + callback(package[key]) + return 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 + local function fetch(params) + local version = core.get_version() + local base_url = core.settings:get("contentdb_url") + local url = base_url .. + "/api/packages/" .. params.package.url_part .. params.path .. "?" .. + "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 = { + core.get_http_accept_languages() + }, + }) + if not response.succeeded then + return nil + end + + return core.parse_json(response.data) end - return core.parse_json(response.data) - end + local function my_callback(value) + package[key] = value + callback(value) + 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) + if not core.handle_async(fetch, { package = package, path = path }, my_callback) then + core.log("error", "ERROR: async event failed") + callback(nil) + end end end +contentdb.get_full_package_info = get_package_info("full_info", "/for-client/") +contentdb.get_package_reviews = get_package_info("reviews", "/for-client/reviews/") + + function contentdb.get_formspec_padding() -- Padding is increased on Android to account for notches -- TODO: use Android API to determine size of cut outs diff --git a/builtin/mainmenu/content/dlg_package.lua b/builtin/mainmenu/content/dlg_package.lua index 7edbf678f..d8fc057c1 100644 --- a/builtin/mainmenu/content/dlg_package.lua +++ b/builtin/mainmenu/content/dlg_package.lua @@ -32,6 +32,7 @@ end local function get_formspec(data) + local package = data.package local window_padding = contentdb.get_formspec_padding() local size = contentdb.get_formspec_size() size.x = math.min(size.x, 20) @@ -42,7 +43,7 @@ local function get_formspec(data) if not data.loading and not data.loading_error then data.loading = true - contentdb.get_full_package_info(data.package, function(info) + contentdb.get_full_package_info(package, function(info) data.loading = false if info == nil then @@ -61,7 +62,7 @@ local function get_formspec(data) -- check to see if that happened if not data.info then if data.loading_error then - return get_info_formspec(size, window_padding, fgettext("No packages could be retrieved")) + return get_info_formspec(size, window_padding, fgettext("Error loading package information")) end return get_info_formspec(size, window_padding, fgettext("Loading...")) end @@ -103,15 +104,15 @@ local function get_formspec(data) local left_button_rect = "0,0;2.875,1" local right_button_rect = "3.125,0;2.875,1" - if data.package.downloading then + if package.downloading then formspec[#formspec + 1] = "animated_image[5,0;1,1;downloading;" formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir) formspec[#formspec + 1] = "cdb_downloading.png;3;400;]" - elseif data.package.queued then + elseif package.queued then formspec[#formspec + 1] = "style[queued;border=false]" formspec[#formspec + 1] = "image_button[5,0;1,1;" .. core.formspec_escape(defaulttexturedir) formspec[#formspec + 1] = "cdb_queued.png;queued;]" - elseif not data.package.path then + elseif not package.path then formspec[#formspec + 1] = "style[install;bgcolor=green]" formspec[#formspec + 1] = "button[" formspec[#formspec + 1] = right_button_rect @@ -119,7 +120,7 @@ local function get_formspec(data) formspec[#formspec + 1] = fgettext("Install [$1]", info.download_size) formspec[#formspec + 1] = "]" else - if data.package.installed_release < data.package.release then + if package.installed_release < package.release then -- The install_ action also handles updating formspec[#formspec + 1] = "style[install;bgcolor=#28ccdf]" formspec[#formspec + 1] = "button[" @@ -137,10 +138,12 @@ local function get_formspec(data) formspec[#formspec + 1] = "]" end + local review_count = info.reviews.positive + info.reviews.neutral + info.reviews.negative local current_tab = data.current_tab or 1 local tab_titles = { fgettext("Description"), fgettext("Information"), + fgettext("Reviews") .. core.formspec_escape(" [" .. review_count .. "]"), } local tab_body_height = bottom_buttons_y - 2.8 @@ -162,8 +165,8 @@ local function get_formspec(data) local winfo = core.get_window_info() local fs_to_px = winfo.size.x / winfo.max_formspec_size.x for i, ss in ipairs(info.screenshots) do - local path = get_screenshot(data.package, ss.url, 2) - hypertext = hypertext .. "" if i ~= #info.screenshots then @@ -194,22 +197,54 @@ local function get_formspec(data) hypertext = hypertext .. "\n\n" .. info.long_description.body + -- Fix the path to blank.png. This is needed for bullet indentation. hypertext = hypertext:gsub("", + "") + hypertext = hypertext:gsub("", + "") + hypertext = hypertext:gsub("", + "") + table.insert_all(formspec, { + "hypertext[0,0;", W, ",", tab_body_height - 0.375, + ";reviews;", core.formspec_escape(hypertext), "]", + }) + elseif data.reviews_error then + table.insert_all(formspec, {"label[2,2;", fgettext("Error loading reviews"), "]"} ) + else + table.insert_all(formspec, {"label[2,2;", fgettext("Loading..."), "]"} ) + end else error("Unknown tab " .. current_tab) end @@ -269,9 +304,10 @@ local function handle_submit(this, fields) end if fields.open_contentdb then - local url = ("%s/packages/%s/?protocol_version=%d"):format( - core.settings:get("contentdb_url"), package.url_part, - core.get_max_supp_proto()) + local version = core.get_version() + local url = core.settings:get("contentdb_url") .. "/packages/" .. package.url_part .. + "/?protocol_version=" .. core.urlencode(core.get_max_supp_proto()) .. + "&engine_version=" .. core.urlencode(version.string) core.open_url(url) return true end @@ -295,7 +331,8 @@ local function handle_submit(this, fields) end if handle_hypertext_event(this, fields.desc, info.long_description) or - handle_hypertext_event(this, fields.info, info.info_hypertext) then + handle_hypertext_event(this, fields.info, info.info_hypertext) or + (package.reviews and handle_hypertext_event(this, fields.reviews, package.reviews)) then return true end end diff --git a/textures/base/pack/contentdb_neutral.png b/textures/base/pack/contentdb_neutral.png new file mode 100644 index 000000000..a73e30bcd Binary files /dev/null and b/textures/base/pack/contentdb_neutral.png differ diff --git a/textures/base/pack/contentdb_thumb_down.png b/textures/base/pack/contentdb_thumb_down.png new file mode 100644 index 000000000..591e86b46 Binary files /dev/null and b/textures/base/pack/contentdb_thumb_down.png differ diff --git a/textures/base/pack/contentdb_thumb_up.png b/textures/base/pack/contentdb_thumb_up.png new file mode 100644 index 000000000..26437d397 Binary files /dev/null and b/textures/base/pack/contentdb_thumb_up.png differ