mtmenu/views/online_content.lua
2026-02-10 21:46:25 -05:00

231 lines
9.3 KiB
Lua

local function fetch_content()
local url = core.settings:get("contentdb_url")
.."/api/packages/?type=mod&type=game&type=txp&protocol_version="
..core.get_max_supp_proto().."&engine_version="
..core.urlencode(core.get_version().string)
for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
item = item:trim()
if item ~= "" then
url = url .. "&hide=" .. core.urlencode(item)
end
end
local http = core.get_http_api()
local response = http.fetch_sync({
url = url,
extra_headers = {
core.get_http_accept_languages()
},
})
return core.parse_json(response.data)
end
return function(state)
imfs.begin(size.x, size.y)
:padding(0, 0)
:bgcolor(theme.styles.bg_color, true)
imfs.box(0, 0, "100%", 1, theme.styles.container.bg_color)
imfs.row(0.2, 0.125, "100% - 0.4", 0.75)
:gap(0.1)
imfs.group(0, 0, "1.25x", 0.75)
imfs.image(0, 0, "100%", "100%", theme.get_background_image("button"))
imfs.row(0.15, 0.05, "100% - 0.3", "100% - 0.13")
local show_type = state.show_type()
imfs.button(0, 0, "1x", "100%", "All")
:style(show_type == "all" and style_borderless_alt or style_borderless)
:style("hovered", style_borderless_hovered)
:style("pressed", style_borderless_hovered)
:onclick(function()
if show_type ~= "all" then
state.show_type("all")
state.page(1)
-- state.content = package.all()
-- if state.search ~= "" then
-- state.content_shown(search_content(state, state.search))
-- else
-- state.content_shown(state.content)
-- end
end
end)
imfs.box(0, 0, 0.1, "100%", theme.styles.container.border_color)
imfs.button(0, 0, "1x", "100%", "Games")
:style(show_type == "games" and style_borderless_alt or style_borderless)
:style("hovered", style_borderless_hovered)
:style("pressed", style_borderless_hovered)
:onclick(function()
if show_type ~= "games" then
state.show_type("games")
state.page(1)
-- state.content = package.games()
-- if state.search ~= "" then
-- state.content_shown(search_content(state, state.search))
-- else
-- state.content_shown(state.content)
-- end
end
end)
imfs.box(0, 0, 0.1, "100%", theme.styles.container.border_color)
imfs.button(0, 0, "1x", "100%", "Mods")
:style(show_type == "mods" and style_borderless_alt or style_borderless)
:style("hovered", style_borderless_hovered)
:style("pressed", style_borderless_hovered)
:onclick(function()
if show_type ~= "mods" then
state.show_type("mods")
state.page(1)
-- state.content = package.mods()
-- if state.search ~= "" then
-- state.content_shown(search_content(state, state.search))
-- else
-- state.content_shown(state.content)
-- end
end
end)
imfs.box(0, 0, 0.1, "100%", theme.styles.container.border_color)
imfs.button(0, 0, "1x", "100%", "Texture Packs")
:style(show_type == "texturepacks" and style_borderless_alt or style_borderless)
:style("hovered", style_borderless_hovered)
:style("pressed", style_borderless_hovered)
:onclick(function()
if show_type ~= "texturepacks" then
state.show_type("texturepacks")
state.page(1)
-- state.content = package.texturepacks()
-- if state.search ~= "" then
-- state.content_shown(search_content(state, state.search))
-- else
-- state.content_shown(state.content)
-- end
end
end)
imfs.row_end()
imfs.group_end()
theme.field(0, 0, "1x", "100%")
:onchange(function(value)
state.search = value
end)
imfs.button(0, 0, 0.75, 0.75)
:image(theme.icon("search"))
:style({
bgimg = theme.get_background_image("button"),
bgimg_middle = theme.styles.button.border_width,
})
:tooltip("Search content")
:onclick(function()
end)
imfs.button(0, 0, 0.75, 0.75)
:image(theme.icon("cancel"))
:style({
bgimg = theme.get_background_image("button"),
bgimg_middle = theme.styles.button.border_width,
})
:tooltip("Clear search")
:onclick(function()
end)
imfs.button(0, 0, 2, "100%", "Back")
:onclick(function()
show_content_menu()
end)
imfs.row_end()
imfs.box(0, 0.95, "100%", 0.1, theme.styles.container.border_color)
if not state.content_shown() then
imfs.row(0, "50% - 0.25", "100%", 0.5)
:align("center")
imfs.image(0, 0, 1, 0.5, theme.icon("loader"))
:animated(4, 200)
imfs.row_end()
if not state.loading then
core.handle_async(fetch_content, nil, function(content)
state.content = content
state.num_content = #content
state.content_shown(state.content)
state.loading = false
end)
state.loading = true
end
return imfs.end_()
end
local content = state.content_shown()
local num_per_page = math.floor((size.x + 0.5) / 5.5) * math.floor((size.y - 1.05) / 3.5)
local excess_x = (size.x + 0.5) % 5.5
local excess_y = (size.y - 1.05) % 3.5
imfs.scroll_container(0, 1.05, "100%", "100% - 1.55", "horizontal", 0, "")
:scrollbar(function()
imfs.scrollbar(0, size.y - 0.5, size.x, 0.5, "horizontal", state.page())
:options({
min = 1,
max = math.ceil(state.num_content / num_per_page),
smallstep = 1
})
:onchange(function(action, value)
if action == "CHG" then
state.page(value)
end
end)
end)
local x = 0
local y = 0
local start = (state.page() - 1) * num_per_page
local i = start
local idx = start
while idx < start + num_per_page do
i = i + 1
local pkg = content[i]
if not pkg then break end
if not package.is_installed(pkg.type, pkg.name) then
idx = idx + 1
imfs.group(x + excess_x / 2, y + excess_y / 2, 5, 3)
imfs.image(0, 0, "100%", "100%", package.screenshot(pkg))
imfs.box(0, 0, "100%", "100%", "#000a")
imfs.hypertext(0.1, 0.1, "100% - 0.2", "100% - 0.2", string.format(
[[<global color=#fff><style size=24><b>%s</b></style>
<b> by %s</b>
%s]],
core.hypertext_escape(pkg.title or pkg.name),
pkg.author,
pkg.short_description
))
:style(".scrollbar", {
size = "0"
})
imfs.button(0, 0, "100%", "100%")
:styles(styles_no_background)
:style("hovered", {
bgimg = "[fill:1x1:0,0:#fff",
bgcolor = "#0004"
})
:style("pressed", {
bgimg = "[fill:1x1:0,0:#fff",
bgcolor = "#0004"
})
:onclick(function()
end)
imfs.group_end()
x = x + 5.5
if x + 5 > size.x then
x = 0
y = y + 3.5
end
end
end
imfs.scroll_container_end()
return imfs.end_()
end