Skip to content

Commit

Permalink
0.1.25 (#72)
Browse files Browse the repository at this point in the history
Remove discover tab because it was kinda pointless (might revisit the
concept later).
Show confirmation prompt when removing game.
Make app not fail completely when Steam is missing or can't be found
(just gotta add the games manually).
Style adjustments.
  • Loading branch information
Raicuparta authored Nov 25, 2023
2 parents 943281b + cd7207a commit b11ff3d
Show file tree
Hide file tree
Showing 26 changed files with 195 additions and 319 deletions.
2 changes: 1 addition & 1 deletion backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rai-pal"
version = "0.1.24"
version = "0.1.25"
authors = ["Raicuparta"]
license = "GPL-3.0-or-later"
repository = "https://github.com/Raicuparta/rai-pal"
Expand All @@ -24,7 +24,7 @@ specta = "1.0.5"
tauri-specta = { version = "1.0.2", features = ["typescript"] }
serde = { version = "1.0", features = ["derive"] }
byteorder = "1.5.0"
tauri = { version = "1.5.2", features = [ "dialog-open", "updater", "shell-open", "dialog"] }
tauri = { version = "1.5.2", features = [ "dialog-confirm", "dialog-open", "updater", "shell-open", "dialog"] }
reqwest = "0.11.22"
goblin = "0.7.1"
open = "5.0.0"
Expand Down
19 changes: 6 additions & 13 deletions backend/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
use serde::Serialize;
use tauri::Manager;

use crate::{
result::Result,
serializable_enum,
};
use crate::serializable_enum;

serializable_enum!(AppEvent {
SyncInstalledGames,
SyncOwnedGames,
SyncDiscoverGames,
SyncMods,
ExecutedSteamCommand,
GameAdded,
GameRemoved,
Error,
});

pub trait EventEmitter {
fn emit_event<TPayload: Serialize + Clone>(&self, event: AppEvent, payload: TPayload)
-> Result;
fn emit_event<TPayload: Serialize + Clone>(&self, event: AppEvent, payload: TPayload);
}

impl EventEmitter for tauri::AppHandle {
fn emit_event<TPayload: Serialize + Clone>(
&self,
event: AppEvent,
payload: TPayload,
) -> Result {
Ok(self.emit_all(&event.to_string(), payload)?)
fn emit_event<TPayload: Serialize + Clone>(&self, event: AppEvent, payload: TPayload) {
self.emit_all(&event.to_string(), payload)
.unwrap_or_else(|err| eprintln!("Failed to emit event: {err}"));
}
}
85 changes: 32 additions & 53 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ use result::{
Error,
Result,
};
use steam::{
appinfo,
id_lists::SteamGame,
};
use steamlocate::SteamDir;
use tauri::{
api::dialog::message,
Expand All @@ -61,7 +57,6 @@ mod windows;
struct AppState {
installed_games: Mutex<Option<installed_game::Map>>,
owned_games: Mutex<Option<Vec<OwnedGame>>>,
discover_games: Mutex<Option<Vec<SteamGame>>>,
mod_loaders: Mutex<Option<mod_loader::DataMap>>,
}

Expand Down Expand Up @@ -106,12 +101,6 @@ async fn get_owned_games(state: tauri::State<'_, AppState>) -> Result<Vec<OwnedG
get_state_data(&state.owned_games)
}

#[tauri::command]
#[specta::specta]
async fn get_discover_games(state: tauri::State<'_, AppState>) -> Result<Vec<SteamGame>> {
get_state_data(&state.discover_games)
}

#[tauri::command]
#[specta::specta]
async fn get_mod_loaders(state: tauri::State<'_, AppState>) -> Result<mod_loader::DataMap> {
Expand All @@ -123,17 +112,15 @@ fn update_state<TData>(
data: TData,
mutex: &Mutex<Option<TData>>,
handle: &tauri::AppHandle,
) -> Result {
) {
if let Ok(mut mutex_guard) = mutex.lock() {
*mutex_guard = Some(data);
}

// Sends a signal to make the frontend request an app state refresh.
// I would have preferred to just send the state with the signal,
// but it seems like Tauri events are really slow for large data.
handle.emit_event(event, ())?;

Ok(())
handle.emit_event(event, ());
}

#[tauri::command]
Expand Down Expand Up @@ -213,7 +200,7 @@ fn refresh_single_game(
installed_games,
&state.installed_games,
handle,
)?;
);

Ok(())
}
Expand Down Expand Up @@ -246,20 +233,19 @@ async fn update_data(handle: tauri::AppHandle, state: tauri::State<'_, AppState>
mod_loaders.clone(),
&state.mod_loaders,
&handle,
)?;
);

let provider_map = provider::get_map();

let steam_dir = SteamDir::locate()?;
let app_info = appinfo::read(steam_dir.path())?;
let provider_map = provider::get_map(&handle);

let installed_games: HashMap<_, _> = provider_map
.values()
.flat_map(|provider| match provider.get_installed_games() {
Ok(games) => games,
Err(err) => {
// TODO properly handle these errors message to frontend.
eprintln!("Error getting installed games for provider: {}", err);
handle.emit_event(
AppEvent::Error,
format!("Error getting installed games for provider: {err}"),
);
Vec::default()
}
})
Expand All @@ -274,37 +260,24 @@ async fn update_data(handle: tauri::AppHandle, state: tauri::State<'_, AppState>
installed_games.clone(),
&state.installed_games,
&handle,
)?;

let (discover_games_result, owned_games_result) = futures::future::join(
steam::discover_games::get(&app_info),
futures::future::join_all(
provider_map
.values()
.map(provider::ProviderActions::get_owned_games),
),
)
.await;

let owned_games: Vec<OwnedGame> = owned_games_result
.into_iter()
.flat_map(result::Result::unwrap_or_default)
.collect();
);

let discover_games = discover_games_result.unwrap_or_default();
update_state(
AppEvent::SyncDiscoverGames,
discover_games,
&state.discover_games,
&handle,
)?;
let owned_games: Vec<OwnedGame> = futures::future::join_all(
provider_map
.values()
.map(provider::ProviderActions::get_owned_games),
)
.await
.into_iter()
.flat_map(result::Result::unwrap_or_default)
.collect();

update_state(
AppEvent::SyncOwnedGames,
owned_games,
&state.owned_games,
&handle,
)?;
);

Ok(())
}
Expand Down Expand Up @@ -335,9 +308,9 @@ async fn add_game(
installed_games,
&state.installed_games,
&handle,
)?;
);

handle.emit_event(AppEvent::GameAdded, game_name)?;
handle.emit_event(AppEvent::GameAdded, game_name);

Ok(())
}
Expand All @@ -360,13 +333,20 @@ async fn remove_game(
installed_games,
&state.installed_games,
&handle,
)?;
);

handle.emit_event(AppEvent::GameRemoved, game.name)?;
handle.emit_event(AppEvent::GameRemoved, game.name);

Ok(())
}

#[tauri::command]
#[specta::specta]
async fn delete_steam_appinfo_cache() -> Result {
let steam_dir = SteamDir::locate()?;
steam::appinfo::delete(steam_dir.path())
}

#[tauri::command]
#[specta::specta]
// This command is here just so tauri_specta exports these types.
Expand All @@ -392,7 +372,6 @@ fn main() {
.manage(AppState {
installed_games: Mutex::default(),
owned_games: Mutex::default(),
discover_games: Mutex::default(),
mod_loaders: Mutex::default(),
})
.setup(|_app| {
Expand Down Expand Up @@ -425,7 +404,6 @@ fn main() {
update_data,
get_installed_games,
get_owned_games,
get_discover_games,
get_mod_loaders,
open_game_folder,
install_mod,
Expand All @@ -436,6 +414,7 @@ fn main() {
open_mods_folder,
add_game,
remove_game,
delete_steam_appinfo_cache,
]
);

Expand Down
14 changes: 9 additions & 5 deletions backend/src/providers/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use async_trait::async_trait;
use enum_dispatch::enum_dispatch;

use crate::{
events::{
AppEvent,
EventEmitter,
},
installed_game::InstalledGame,
owned_game::OwnedGame,
providers::{
Expand Down Expand Up @@ -49,23 +53,23 @@ where
Ok((TProvider::ID.to_string(), mod_loader))
}

fn add_entry<TProvider: ProviderActions + ProviderStatic>(map: &mut Map)
fn add_entry<TProvider: ProviderActions + ProviderStatic>(map: &mut Map, handle: &tauri::AppHandle)
where
Provider: std::convert::From<TProvider>,
{
match create_map_entry::<TProvider>() {
Ok((key, value)) => {
map.insert(key, value);
}
Err(err) => eprintln!("Failed to create map entry: {err}"),
Err(err) => handle.emit_event(AppEvent::Error, format!("Failed to set up provider: {err}")),
}
}

pub fn get_map() -> Map {
pub fn get_map(handle: &tauri::AppHandle) -> Map {
let mut map = Map::new();

add_entry::<SteamProvider>(&mut map);
add_entry::<ManualProvider>(&mut map);
add_entry::<SteamProvider>(&mut map, handle);
add_entry::<ManualProvider>(&mut map, handle);

map
}
4 changes: 4 additions & 0 deletions backend/src/steam/appinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,7 @@ pub fn read(steam_path: &Path) -> Result<SteamAppInfoFile> {
let mut appinfo_file = BufReader::new(fs::File::open(get_path(steam_path))?);
SteamAppInfoFile::load(&mut appinfo_file)
}

pub fn delete(steam_path: &Path) -> Result {
Ok(fs::remove_file(get_path(steam_path))?)
}
2 changes: 1 addition & 1 deletion backend/src/steam/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ use crate::{

pub fn run(command: &str, handle: &tauri::AppHandle) -> Result {
open::that_detached(format!("steam://{command}"))?;
handle.emit_event(AppEvent::ExecutedSteamCommand, ())?;
handle.emit_event(AppEvent::ExecutedSteamCommand, ());
Ok(())
}
26 changes: 0 additions & 26 deletions backend/src/steam/discover_games.rs

This file was deleted.

1 change: 0 additions & 1 deletion backend/src/steam/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod appinfo;
pub mod command;
pub mod discover_games;
pub mod id_lists;
pub mod thumbnail;
2 changes: 1 addition & 1 deletion backend/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"dialog": {
"all": false,
"ask": false,
"confirm": false,
"confirm": true,
"message": false,
"open": true,
"save": false
Expand Down
11 changes: 5 additions & 6 deletions frontend/api/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ export function getOwnedGames() {
return invoke()<OwnedGame[]>("get_owned_games")
}

export function getDiscoverGames() {
return invoke()<SteamGame[]>("get_discover_games")
}

export function getModLoaders() {
return invoke()<{ [key: string]: ModLoaderData }>("get_mod_loaders")
}
Expand Down Expand Up @@ -70,12 +66,15 @@ export function removeGame(gameId: string) {
return invoke()<null>("remove_game", { gameId })
}

export function deleteSteamAppinfoCache() {
return invoke()<null>("delete_steam_appinfo_cache")
}

export type GameExecutable = { path: string; engine: GameEngine | null; architecture: Architecture | null; operatingSystem: OperatingSystem | null; scriptingBackend: UnityScriptingBackend | null }
export type InstalledGame = { id: string; name: string; providerId: ProviderId; discriminator: string | null; steamLaunch: SteamLaunchOption | null; executable: GameExecutable; thumbnailUrl: string | null; availableMods: { [key: string]: boolean } }
export type ProviderId = "Steam" | "Manual"
export type AppEvent = "SyncInstalledGames" | "SyncOwnedGames" | "SyncDiscoverGames" | "SyncMods" | "ExecutedSteamCommand" | "GameAdded" | "GameRemoved"
export type SteamGame = { id: string; nsfw: boolean; engine: GameEngineBrand }
export type GameEngine = { brand: GameEngineBrand; version: GameEngineVersion | null }
export type AppEvent = "SyncInstalledGames" | "SyncOwnedGames" | "SyncMods" | "ExecutedSteamCommand" | "GameAdded" | "GameRemoved" | "Error"
export type Mod = { id: string; name: string; scriptingBackend: UnityScriptingBackend | null; engine: GameEngineBrand | null; kind: ModKind; path: string }
export type ModLoaderData = { id: string; path: string; mods: Mod[] }
export type OwnedGame = { id: string; providerId: ProviderId; name: string; installed: boolean; osList: OperatingSystem[]; engine: GameEngineBrand; releaseDate: number; thumbnailUrl: string }
Expand Down
Loading

0 comments on commit b11ff3d

Please sign in to comment.