Skip to content

Commit 2541b3a

Browse files
authored
UI image system(s) rework
Merge pull request #20 from ArmchairDevelopers/ui-image-rework
2 parents 2952439 + 286405e commit 2541b3a

14 files changed

Lines changed: 378 additions & 612 deletions

maxima-ui/src/bridge/game_images.rs

Lines changed: 0 additions & 154 deletions
This file was deleted.

maxima-ui/src/bridge/get_friends.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ use maxima::{core::LockedMaxima, rtm::client::BasicPresence};
55
use std::sync::mpsc::Sender;
66

77
use crate::{
8-
bridge_thread::{MaximaLibResponse, InteractThreadFriendListResponse},
9-
views::friends_view::{UIFriend, UIFriendImageWrapper},
8+
bridge_thread::{InteractThreadFriendListResponse, MaximaLibResponse}, ui_image::UIImageCacheLoaderCommand, views::friends_view::UIFriend
109
};
1110

1211
pub async fn get_friends_request(
1312
maxima_arc: LockedMaxima,
1413
channel: Sender<MaximaLibResponse>,
14+
remote_provider_channel: Sender<UIImageCacheLoaderCommand>,
1515
ctx: &Context,
1616
) -> Result<()> {
1717
debug!("recieved request to load friends");
@@ -23,14 +23,13 @@ pub async fn get_friends_request(
2323

2424
let friends = maxima.friends(0).await?;
2525
for bitchass in friends {
26-
26+
remote_provider_channel.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Avatar(bitchass.id().to_string()), bitchass.avatar().as_ref().unwrap().medium().path().to_string())).unwrap();
2727
let friend_info = UIFriend {
2828
name: bitchass.display_name().to_string(),
2929
id: bitchass.id().to_string(),
3030
online: BasicPresence::Offline,
3131
game: None,
3232
game_presence: None,
33-
avatar: UIFriendImageWrapper::Unloaded(bitchass.avatar().as_ref().unwrap().medium().path().to_string()),
3433
};
3534

3635
let res = MaximaLibResponse::FriendInfoResponse(InteractThreadFriendListResponse {

maxima-ui/src/bridge/get_games.rs

Lines changed: 109 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,122 @@
11
use anyhow::{Ok, Result, bail};
22
use egui::Context;
3-
use log::debug;
4-
use maxima::core::LockedMaxima;
5-
use std::sync::mpsc::Sender;
3+
use log::{debug, info};
4+
use maxima::{core::{service_layer::{ServiceGame, ServiceGameImagesRequestBuilder, ServiceLayerClient, SERVICE_REQUEST_GAMEIMAGES}, LockedMaxima}, util::native::maxima_dir};
5+
use std::{fs, sync::mpsc::Sender};
66

77
use crate::{
8-
bridge_thread::{InteractThreadGameListResponse, MaximaLibResponse},
9-
GameDetailsWrapper, GameInfo, GameUIImagesWrapper,
8+
bridge_thread::{InteractThreadGameListResponse, MaximaLibResponse}, ui_image::UIImageCacheLoaderCommand, GameDetailsWrapper, GameInfo
109
};
1110

11+
async fn get_preferred_hero_image(images: &Option<ServiceGame>) -> Option<String> {
12+
if images.is_none() {
13+
return None;
14+
}
15+
16+
let key_art = images.as_ref().unwrap().key_art();
17+
if key_art.is_none() {
18+
return None;
19+
}
20+
21+
let key_art = key_art.as_ref().unwrap();
22+
23+
debug!("{:?}", key_art);
24+
if let Some(img) = key_art.aspect_10x3_image() {
25+
return Some(img.path().clone());
26+
}
27+
28+
if let Some(img) = key_art.aspect_2x1_image() {
29+
return Some(img.path().clone());
30+
}
31+
32+
if let Some(img) = key_art.aspect_16x9_image() {
33+
return Some(img.path().clone());
34+
}
35+
36+
None
37+
}
38+
39+
fn get_logo_image(images: &Option<ServiceGame>) -> Option<String> {
40+
if images.is_none() {
41+
return None;
42+
}
43+
44+
let logo_set = images.as_ref().unwrap().primary_logo();
45+
if logo_set.is_none() {
46+
return None;
47+
}
48+
49+
let largest_logo = logo_set.as_ref().unwrap().largest_image();
50+
if largest_logo.is_none() {
51+
return None;
52+
}
53+
54+
Some(largest_logo.as_ref().unwrap().path().to_string())
55+
}
56+
57+
async fn handle_images(slug: String, locale: String, has_hero: bool, has_logo: bool, channel: Sender<UIImageCacheLoaderCommand>, service_layer: ServiceLayerClient) -> Result<()> {
58+
debug!("handling image downloads for {}", &slug);
59+
let images = service_layer
60+
.request(SERVICE_REQUEST_GAMEIMAGES, ServiceGameImagesRequestBuilder::default()
61+
.should_fetch_context_image(!has_logo)
62+
.should_fetch_backdrop_images(!has_hero)
63+
.game_slug(slug.clone())
64+
.locale(locale.clone())
65+
.build()?).await?;
66+
67+
if !has_hero {
68+
if let Some(hero) = get_preferred_hero_image(&images).await {
69+
channel.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Hero(slug.clone()), hero)).unwrap()
70+
}
71+
}
72+
73+
if !has_logo {
74+
if let Some(logo) = get_logo_image(&images) {
75+
channel.send(UIImageCacheLoaderCommand::ProvideRemote(crate::ui_image::UIImageType::Logo(slug), logo))?
76+
} else {
77+
channel.send(UIImageCacheLoaderCommand::Stub(crate::ui_image::UIImageType::Logo(slug)))?
78+
}
79+
}
80+
81+
Ok(())
82+
}
83+
84+
1285
pub async fn get_games_request(
1386
maxima_arc: LockedMaxima,
1487
channel: Sender<MaximaLibResponse>,
88+
channel1: Sender<UIImageCacheLoaderCommand>,
1589
ctx: &Context,
1690
) -> Result<()> {
1791
debug!("recieved request to load games");
1892
let mut maxima = maxima_arc.lock().await;
93+
let service_layer = maxima.service_layer().clone();
94+
let locale = maxima.locale().short_str().to_owned();
1995
let logged_in = maxima.auth_storage().lock().await.current().is_some();
2096
if !logged_in {
2197
bail!("Ignoring request to load games, not logged in.");
2298
}
2399

100+
24101
let owned_games = maxima.mut_library().games().await;
25102

103+
26104
if owned_games.len() <= 0 {
27105
return Ok(());
28106
}
29107

30108
for game in owned_games {
109+
info!("processing {}", &game.base_offer().slug());
31110
let game_info = GameInfo {
32111
slug: game.base_offer().slug().to_string(),
33112
offer: game.base_offer().offer().offer_id().to_string(),
34113
name: game.name(),
35-
images: GameUIImagesWrapper::Unloaded,
36114
details: GameDetailsWrapper::Unloaded,
37115
dlc: game.extra_offers().clone(),
38116
installed: game.base_offer().installed().await,
39117
has_cloud_saves: game.base_offer().offer().has_cloud_save(),
40118
};
119+
let slug = game_info.slug.clone();
41120
let settings = crate::GameSettings {
42121
//TODO: eventually support cloud saves, the option is here for that but for now, keep it disabled in ui!
43122
cloud_saves: true,
@@ -49,6 +128,30 @@ pub async fn get_games_request(
49128
settings
50129
});
51130
channel.send(res)?;
131+
132+
let game_hero = maxima_dir()
133+
.unwrap()
134+
.join("cache/ui/images/")
135+
.join(&slug)
136+
.join("hero.jpg");
137+
let game_logo = maxima_dir()
138+
.unwrap()
139+
.join("cache/ui/images/")
140+
.join(&slug)
141+
.join("logo.png");
142+
let has_hero = fs::metadata(&game_hero).is_ok();
143+
let has_logo = fs::metadata(&game_logo).is_ok();
144+
145+
if !has_hero || !has_logo {
146+
//we're like 20 tasks deep i swear but this shit's gonna be real fast, trust
147+
let slug_send = slug.clone();
148+
let locale_send = locale.clone();
149+
let channel_send = channel1.clone();
150+
let service_layer_send = service_layer.clone();
151+
tokio::task::spawn(async move { handle_images(slug_send, locale_send, has_hero, has_logo, channel_send, service_layer_send).await });
152+
tokio::task::yield_now().await;
153+
154+
}
52155

53156
egui::Context::request_repaint(&ctx);
54157
}

maxima-ui/src/bridge/get_user_avatar.rs

Lines changed: 0 additions & 27 deletions
This file was deleted.

maxima-ui/src/bridge/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
pub mod game_details;
2-
pub mod game_images;
32
pub mod get_friends;
43
pub mod get_games;
5-
pub mod get_user_avatar;
64
pub mod login_oauth;
75
pub mod start_game;

0 commit comments

Comments
 (0)