diff --git a/lib/pages/games.rb b/lib/pages/games.rb index 7a18531..de0f8c1 100644 --- a/lib/pages/games.rb +++ b/lib/pages/games.rb @@ -30,12 +30,19 @@ module W3DHubLauncher # game events and news container stack(fill: true, height: 1.0, margin_left: LARGE_PADDING, scroll: true) do - @event_container = flow(width: 1.0, height: 1.0, max_height: 380, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_GRAY) do + @event_container = stack(width: 1.0, padding: PADDING, margin_left: HALF_PADDING, margin_right: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0x88_26a269) do end # news container @news_container = flow(width: 1.0, margin_top: PADDING) do end + + # "dynamically" adjust news item widths + @news_container.subscribe(:size_changed) do |event| + @news_container.children.each do |box| + box.style.width = 1.0 / news_item_width_ratio + end + end end end @@ -62,6 +69,29 @@ module W3DHubLauncher return end + app_id = @current_app.id + unless MemCache[:"events_#{app_id}"] + Worker::Api.events(app_id) do |result| + if result.okay? + File.write("events_#{app_id}.json", result.data) + MemCache[:"events_#{app_id}"] = JSON.parse(result.data)&.map { |item| Worker::Api::ServerEvent.new(item) } || [] + + populate_game_event if app_id == @current_app.id + end + end + end + + unless MemCache[:"news_#{app_id}"] + Worker::Api.news(app_id) do |result| + if result.okay? + File.write("news_#{app_id}.json", result.data) + MemCache[:"news_#{app_id}"] = JSON.parse(result.data)["news"]&.map { |item| Worker::Api::NewsItem.new(item) } || [] + + populate_game_news if app_id == @current_app.id + end + end + end + populate_games_list populate_game_info populate_game_event @@ -80,8 +110,6 @@ module W3DHubLauncher end end end - - puts end end @@ -100,7 +128,9 @@ module W3DHubLauncher # web links stack(width: 1.0, fill: true, padding: 0, padding_top: LARGE_PADDING) do @current_app.web_links.each do |link| - link link.name, text_size: 24, tip: link.uri + link link.name, text_size: 24, tip: link.uri do + SDL.OpenURL(link.uri) + end end end @@ -131,38 +161,48 @@ module W3DHubLauncher end def populate_game_event - # TODO: Hide event container if there is no event - @event_container.show if false - @event_container.hide if true + app_events = MemCache[:"events_#{@current_app.id}"] || [] + if app_events.empty? + @event_container.hide + else + @event_container.show - @event_container.clear do - image safe_get_image("#{ROOT_PATH}/media/background.png"), fill: true, aspect_ratio: 16.0 / 9.0 + event = app_events.sort(&:start_time).last - stack(fill: true, height: 1.0, margin_left: PADDING) do - caption "Upcoming Event".upcase, color: 0xff_22aa11 - title "Red Alert: A Path Beyond Game Night" - tagline "July 11, 2028" - - flow(fill: true) - - button "Read More", margin_left: PADDING, margin_right: LARGE_PADDING, margin_bottom: PADDING, width: 1.0 + @event_container.clear do + caption "Upcoming Event".upcase, color: 0xaa_ffffff + tagline event.title # "Red Alert: A Path Beyond Game Night" + caption event.start_time.strftime("%B %e, %Y • %T") # "July 11, 2028" end end end def populate_game_news + app_news = MemCache[:"news_#{@current_app.id}"] || [] + @news_container.clear do - 9.times do - stack(width: 1.0 / 3, min_width: 345, height: 345, aspect_ratio: 1, margin_left: HALF_PADDING, margin_right: HALF_PADDING, margin_bottom: PADDING) do - stack(width: 1.0, fill: true, background_image: safe_get_image("#{ROOT_PATH}/media/background.png"), background_image_mode: :fill) - stack(width: 1.0, height: 1.0 / 3, padding: PADDING, v_align: :bottom, background_nine_slice: NINE_SLICE_ROUNDED_BOTTOM, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_GRAY, border_thickness_top: 1, border_color_top: Gosu::Color::BLACK) do - caption "NEWS", color: 0x88_ffffff - tagline "A News Item Post A News Item Post" + app_news.each do |item| + stack(width: 1.0 / news_item_width_ratio, height: 345, aspect_ratio: 1, margin_left: HALF_PADDING, margin_right: HALF_PADDING, margin_bottom: PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_GRAY) do + stack(width: 1.0, height: 1.0 / 3, padding: PADDING, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_GRAY) do + para item.timestamp.strftime("%B %e, %Y") #"September 29, 2026" + tagline item.title + end + + stack(width: 1.0, fill: true, padding: PADDING, padding_bottom: 0, scroll: false) do + para item.blurb + end + + button "Read More", margin: PADDING, width: 1.0, tip: item.uri do + SDL.OpenURL(item.uri) end end end end end + + def news_item_width_ratio + (@news_container.width / 400.0).round.clamp(1..10) + end end end end diff --git a/lib/pages/server_browser.rb b/lib/pages/server_browser.rb index 8f621ba..7cab49e 100644 --- a/lib/pages/server_browser.rb +++ b/lib/pages/server_browser.rb @@ -97,7 +97,7 @@ module W3DHubLauncher # server ping flow(width: 96, height: 1.0, margin_left: HALF_PADDING, margin_right: HALF_PADDING) do stack(fill: true, height: 1.0, v_align: :center) do - caption server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "?" : server.ping, width: 1.0, text_align: :center, tip: server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "Server has not replied yet or did not reply to ICMP Echo Request.\nPing unknown." : "" + caption server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "?" : format("%ims", server.ping), width: 1.0, text_align: :center, tip: server.ping == Worker::Api::GameServer::BAD_OR_UNKNOWN_PING ? "Server has not replied yet or did not reply to ICMP Echo Request.\nPing unknown." : "" inscription "ping", text_wrap: :none, width: 1.0, text_align: :center, margin_top: -HALF_PADDING end stack(width: 8, height: server.ping_score_ratio, v_align: :center, min_height: 8, background_nine_slice: NINE_SLICE_ROUNDED_SMALL, background_nine_slice_from_edge: NINE_SLICE_EDGE_SMALL, background_nine_slice_color: server.ping_score_color) diff --git a/lib/worker/api.rb b/lib/worker/api.rb index 6213528..8c120fc 100644 --- a/lib/worker/api.rb +++ b/lib/worker/api.rb @@ -54,12 +54,12 @@ module W3DHubLauncher # returns news for application def self.news(category = "launcher-home", &block) - Worker::Request.new(:news, category, &block) + W3DHubLauncher::Worker::Request.new(:w3dhub_api_call, { call: :fetch_news, arguments: [category] }, &block) end # returns news for application - def self.events(app_id, &block) - Worker::Request.new(:events, app_id, &block) + def self.events(category, &block) + W3DHubLauncher::Worker::Request.new(:w3dhub_api_call, { call: :fetch_events, arguments: [category] }, &block) end # request installation of application diff --git a/lib/worker/api/news_item.rb b/lib/worker/api/news_item.rb new file mode 100644 index 0000000..a75d917 --- /dev/null +++ b/lib/worker/api/news_item.rb @@ -0,0 +1,28 @@ +module W3DHubLauncher + class Worker + class Api + class NewsItem + attr_reader :topic_id, :title, :blurb, :uri, :image_uri, :author_id, :author, :author_uri, :timestamp + + def initialize(data) + @topic_id = Integer(data["topic-id"] || 0) + @title = data["title"].to_s + @blurb = clean_and_scrub_blurb(data["blurb"].to_s) + @uri = data["uri"].to_s + @image_uri = data["image"].to_s + + @author_id = data["author-id"].to_s + @author = data["author"].to_s + @author_uri = data["author-uri"].to_s + + @timestamp = Time.at(Integer(data["timestamp"] || 0), in: "UTC").localtime + end + + # Replaces multiple newlines with a single newline, and trims off any leading and trailing whitespace. + def clean_and_scrub_blurb(string) + string.gsub(/\n+/, "\n").strip + end + end + end + end +end diff --git a/lib/worker/api/server_event.rb b/lib/worker/api/server_event.rb new file mode 100644 index 0000000..f1a7322 --- /dev/null +++ b/lib/worker/api/server_event.rb @@ -0,0 +1,17 @@ +module W3DHubLauncher + class Worker + class Api + class ServerEvent + attr_reader :title, :image_uri, :app_id, :start_time, :end_time, :timestamp + def initialize(data) + @title = data["title"] + @image_uri = data["image"] + @app_id = data["server"] + @start_time = Time.parse(data["starttime"], in: "UTC").localtime + @end_time = Time.parse(data["endtime"], in: "UTC").localtime + @timestamp = Time.parse(data["dateTime"], in: "UTC").localtime + end + end + end + end +end diff --git a/lib/worker/api/test_event.rb b/lib/worker/api/test_event.rb new file mode 100644 index 0000000..96cd8af --- /dev/null +++ b/lib/worker/api/test_event.rb @@ -0,0 +1,19 @@ +module W3DHubLauncher + class Worker + class Api + class TestEvent + attr_reader :title, :image_uri, :timestamp + + def initialize(data) + @title = data["name"] + # @title = data["title"] + @image_uri = data["image"] + # @app_id = data["server"] + # @start_time = Time.parse(data["starttime"]).localtime + # @end_time = Time.parse(data["endtime"]).localtime + @timestamp = Time.parse(data["dateTime"], in: "UTC").localtime + end + end + end + end +end diff --git a/lib/worker/tasks/move_application.rb b/lib/worker/tasks/move_application.rb new file mode 100644 index 0000000..e69de29 diff --git a/lib/worker/w3dhub_api.rb b/lib/worker/w3dhub_api.rb index a8a9567..52d3e7f 100644 --- a/lib/worker/w3dhub_api.rb +++ b/lib/worker/w3dhub_api.rb @@ -33,10 +33,10 @@ module W3DHubLauncher Sync do |task| task.with_timeout(API_TIMEOUT) do Async::HTTP::Internet.send(method, url, headers, body) do |response| + # pp [method, url, headers, body] if response.success? result.data = response.read else - # pp response result.error = true end end @@ -124,12 +124,16 @@ module W3DHubLauncher result end - def fetch_news() - result = CyberarmEngine::Result.new + def fetch_news(category) + fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-news", method: :post, body: "data={\"category\":\"#{category}\"}", headers: headers(form_encoded: true)) end - def fetch_events() - result = CyberarmEngine::Result.new + def fetch_events(category) + fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-server-events", method: :post, body: "data={\"serverPath\":\"#{category}\"}", headers: headers(form_encoded: true)) + end + + def fetch_test_events(category) + fetch("#{PRIMARY_W3DHUB_API_ENDPOINT}/apis/w3dhub/1/get-testing-times") end def fetch_manifest() diff --git a/w3d_hub_linux_launcher.rb b/w3d_hub_linux_launcher.rb index 669db78..ade23c1 100644 --- a/w3d_hub_linux_launcher.rb +++ b/w3d_hub_linux_launcher.rb @@ -51,6 +51,11 @@ require_relative "lib/worker/api" require_relative "lib/worker/api/application" require_relative "lib/worker/api/game_server" require_relative "lib/worker/api/settings" +require_relative "lib/worker/api/news_item" +require_relative "lib/worker/api/server_event" +require_relative "lib/worker/api/test_event" +require_relative "lib/worker/api/legacy_manifest" +require_relative "lib/worker/api/legacy_manifest_package" require_relative "lib/worker/request" require_relative "lib/worker/w3dhub_api" require_relative "lib/worker/task" @@ -58,6 +63,7 @@ require_relative "lib/worker/tasks/install_application" require_relative "lib/worker/tasks/uninstall_application" require_relative "lib/worker/tasks/repair_application" require_relative "lib/worker/tasks/update_application" +require_relative "lib/worker/tasks/move_application" module W3DHubLauncher MemCache = {}