aboutsummaryrefslogtreecommitdiff
path: root/builtin/mainmenu
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/mainmenu')
-rw-r--r--builtin/mainmenu/dlg_version_info.lua172
-rw-r--r--builtin/mainmenu/init.lua3
2 files changed, 174 insertions, 1 deletions
diff --git a/builtin/mainmenu/dlg_version_info.lua b/builtin/mainmenu/dlg_version_info.lua
new file mode 100644
index 000000000..568fca3f4
--- /dev/null
+++ b/builtin/mainmenu/dlg_version_info.lua
@@ -0,0 +1,172 @@
+--[[
+Minetest
+Copyright (C) 2018-2020 SmallJoker, 2022 rubenwardy
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+]]
+
+if not core.get_http_api then
+ function check_new_version()
+ end
+ return
+end
+
+local function version_info_formspec(data)
+ local cur_ver = core.get_version()
+ local title = fgettext("A new $1 version is available", cur_ver.project)
+ local message =
+ fgettext("Installed version: $1\nNew version: $2\n" ..
+ "Visit $3 to find out how to get the newest version and stay up to date" ..
+ " with features and bugfixes.",
+ cur_ver.string, data.new_version or "", data.url or "")
+
+ local fs = {
+ "formspec_version[3]",
+ "size[12.8,7]",
+ "style_type[label;textcolor=#0E0]",
+ "label[0.5,0.8;", core.formspec_escape(title), "]",
+ "textarea[0.4,1.6;12,3.4;;;",
+ core.formspec_escape(message), "]",
+ "container[0.4,5.8]",
+ "button[0.0,0;4.0,0.8;version_check_visit;", fgettext("Visit website"), "]",
+ "button[4.5,0;3.5,0.8;version_check_remind;", fgettext("Later"), "]",
+ "button[8.5.5,0;3.5,0.8;version_check_never;", fgettext("Never"), "]",
+ "container_end[]",
+ }
+
+ return table.concat(fs, "")
+end
+
+local function version_info_buttonhandler(this, fields)
+ if fields.version_check_remind then
+ -- Erase last known, user will be reminded again at next check
+ core.settings:set("update_last_known", "")
+ this:delete()
+ return true
+ end
+ if fields.version_check_never then
+ core.settings:set("update_last_checked", "disabled")
+ this:delete()
+ return true
+ end
+ if fields.version_check_visit then
+ if type(this.data.url) == "string" then
+ core.open_url(this.data.url)
+ end
+ this:delete()
+ return true
+ end
+
+ return false
+end
+
+local function create_version_info_dlg(new_version, url)
+ assert(type(new_version) == "string")
+ assert(type(url) == "string")
+
+ local retval = dialog_create("version_info",
+ version_info_formspec,
+ version_info_buttonhandler,
+ nil)
+
+ retval.data.new_version = new_version
+ retval.data.url = url
+
+ return retval
+end
+
+local function get_current_version_code()
+ -- Format: Major.Minor.Patch
+ -- Convert to MMMNNNPPP
+ local cur_string = core.get_version().string
+ local cur_major, cur_minor, cur_patch = cur_string:match("^(%d+).(%d+).(%d+)")
+
+ if not cur_patch then
+ core.log("error", "Failed to parse version numbers (invalid tag format?)")
+ return
+ end
+
+ return (cur_major * 1000 + cur_minor) * 1000 + cur_patch
+end
+
+local function on_version_info_received(json)
+ local maintab = ui.find_by_name("maintab")
+ if maintab.hidden then
+ -- Another dialog is open, abort.
+ return
+ end
+
+ local known_update = tonumber(core.settings:get("update_last_known")) or 0
+
+ -- Format: MMNNPPP (Major, Minor, Patch)
+ local new_number = type(json.latest) == "table" and json.latest.version_code
+ if type(new_number) ~= "number" then
+ core.log("error", "Failed to read version number (invalid response?)")
+ return
+ end
+
+ local cur_number = get_current_version_code()
+ if new_number <= known_update or new_number < cur_number then
+ return
+ end
+
+ -- Also consider updating from 1.2.3-dev to 1.2.3
+ if new_number == cur_number and not core.get_version().is_dev then
+ return
+ end
+
+ core.settings:set("update_last_known", tostring(new_number))
+
+ -- Show version info dialog (once)
+ maintab:hide()
+
+ local version_info_dlg = create_version_info_dlg(json.latest.version, json.latest.url)
+ version_info_dlg:set_parent(maintab)
+ version_info_dlg:show()
+
+ ui.update()
+end
+
+function check_new_version()
+ local url = core.settings:get("update_information_url")
+ if core.settings:get("update_last_checked") == "disabled" or
+ url == "" then
+ -- Never show any updates
+ return
+ end
+
+ local time_now = os.time()
+ local time_checked = tonumber(core.settings:get("update_last_checked")) or 0
+ if time_now - time_checked < 2 * 24 * 3600 then
+ -- Check interval of 2 entire days
+ return
+ end
+
+ core.settings:set("update_last_checked", tostring(time_now))
+
+ core.handle_async(function(params)
+ local http = core.get_http_api()
+ return http.fetch_sync(params)
+ end, { url = url }, function(result)
+ local json = result.succeeded and core.parse_json(result.data)
+ if type(json) ~= "table" or not json.latest then
+ core.log("error", "Failed to read JSON output from " .. url ..
+ ", status code = " .. result.code)
+ return
+ end
+
+ on_version_info_received(json)
+ end)
+end
diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua
index f890765fa..386d4928c 100644
--- a/builtin/mainmenu/init.lua
+++ b/builtin/mainmenu/init.lua
@@ -47,6 +47,7 @@ dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
+dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua")
local tabs = {}
@@ -121,8 +122,8 @@ local function init_globals()
end
ui.set_default("maintab")
+ check_new_version()
tv_main:show()
-
ui.update()
end