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( [[ by %s %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