mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-13 16:22:43 +10:00
Merge remote-tracking branch 'origin/main'
# Conflicts: # src-tauri/src/lib.rs
This commit is contained in:
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -1022,6 +1022,7 @@ dependencies = [
|
||||
"directories",
|
||||
"env_logger",
|
||||
"hex",
|
||||
"http",
|
||||
"log",
|
||||
"openssl",
|
||||
"rayon",
|
||||
|
||||
@ -36,6 +36,7 @@ structured-logger = "1.0.3"
|
||||
hex = "0.4.3"
|
||||
tauri-plugin-dialog = "2"
|
||||
env_logger = "0.11.5"
|
||||
http = "1.1.0"
|
||||
|
||||
[dependencies.uuid]
|
||||
version = "1.10.0"
|
||||
|
||||
@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Emitter, Manager};
|
||||
use url::Url;
|
||||
|
||||
use crate::{db::DatabaseAuth, AppState, AppStatus, User, DB};
|
||||
use crate::{db::{fetch_base_url, DatabaseAuth}, AppState, AppStatus, User, DB};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct InitiateRequestBody {
|
||||
@ -79,10 +79,7 @@ pub fn generate_authorization_header() -> String {
|
||||
}
|
||||
|
||||
pub fn fetch_user() -> Result<User, ()> {
|
||||
let base_url = {
|
||||
let handle = DB.borrow_data().unwrap();
|
||||
Url::parse(&handle.base_url).unwrap()
|
||||
};
|
||||
let base_url = fetch_base_url();
|
||||
|
||||
let endpoint = base_url.join("/api/v1/client/user").unwrap();
|
||||
let header = generate_authorization_header();
|
||||
|
||||
@ -7,6 +7,7 @@ use std::{
|
||||
use directories::BaseDirs;
|
||||
use rustbreak::{deser::Bincode, PathDatabase};
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::DB;
|
||||
|
||||
@ -62,3 +63,8 @@ pub fn setup() -> DatabaseInterface {
|
||||
pub fn is_set_up() -> bool {
|
||||
return !DB.borrow_data().unwrap().base_url.is_empty();
|
||||
}
|
||||
|
||||
pub fn fetch_base_url() -> Url {
|
||||
let handle = DB.borrow_data().unwrap();
|
||||
Url::parse(&handle.base_url).unwrap()
|
||||
}
|
||||
|
||||
@ -1,15 +1,22 @@
|
||||
mod auth;
|
||||
mod db;
|
||||
mod library;
|
||||
mod remote;
|
||||
mod unpacker;
|
||||
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
|
||||
use db::{fetch_base_url, DatabaseInterface, DATA_ROOT_DIR};
|
||||
use env_logger;
|
||||
use env_logger::Env;
|
||||
use auth::{auth_initiate, recieve_handshake};
|
||||
use db::{DatabaseInterface, DATA_ROOT_DIR};
|
||||
use http::{header::*, response::Builder as ResponseBuilder, status::StatusCode};
|
||||
use library::{fetch_game, fetch_library, Game};
|
||||
use log::info;
|
||||
use remote::{gen_drop_url, use_remote};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashMap, io, sync::{LazyLock, Mutex}, task, thread
|
||||
};
|
||||
use structured_logger::{json::new_writer, Builder};
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
@ -20,19 +27,19 @@ pub enum AppStatus {
|
||||
SignedInNeedsReauth,
|
||||
}
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all="camelCase")]
|
||||
pub struct User {
|
||||
id: String,
|
||||
username: String,
|
||||
admin: bool,
|
||||
display_name: String,
|
||||
profile_picture: String,
|
||||
displayName: String,
|
||||
profilePicture: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct AppState {
|
||||
status: AppStatus,
|
||||
user: Option<User>,
|
||||
games: HashMap<String, Game>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@ -43,7 +50,7 @@ fn fetch_state<'a>(state: tauri::State<'_, Mutex<AppState>>) -> Result<AppState,
|
||||
Ok(cloned_state)
|
||||
}
|
||||
|
||||
fn setup() -> AppState {
|
||||
fn setup<'a>() -> AppState {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||
|
||||
let is_set_up = db::is_set_up();
|
||||
@ -51,22 +58,24 @@ fn setup() -> AppState {
|
||||
return AppState {
|
||||
status: AppStatus::NotConfigured,
|
||||
user: None,
|
||||
games: HashMap::new(),
|
||||
};
|
||||
}
|
||||
|
||||
let auth_result = auth::setup().unwrap();
|
||||
AppState {
|
||||
return AppState {
|
||||
status: auth_result.0,
|
||||
user: auth_result.1,
|
||||
}
|
||||
games: HashMap::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub static DB: LazyLock<DatabaseInterface> = LazyLock::new(db::setup);
|
||||
pub static DB: LazyLock<DatabaseInterface> = LazyLock::new(|| db::setup());
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
let state = setup();
|
||||
info!("Initialized drop client");
|
||||
info!("initialized drop client");
|
||||
|
||||
let mut builder = tauri::Builder::default().plugin(tauri_plugin_dialog::init());
|
||||
|
||||
@ -81,10 +90,16 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.manage(Mutex::new(state))
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// DB
|
||||
fetch_state,
|
||||
// Auth
|
||||
auth_initiate,
|
||||
// Remote
|
||||
use_remote,
|
||||
gen_drop_url,
|
||||
// Library
|
||||
fetch_library,
|
||||
fetch_game,
|
||||
])
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.setup(|app| {
|
||||
@ -113,14 +128,46 @@ pub fn run() {
|
||||
app.deep_link().on_open_url(move |event| {
|
||||
info!("handling drop:// url");
|
||||
let binding = event.urls();
|
||||
let url = binding.first().unwrap();
|
||||
if url.host_str().unwrap() == "handshake" {
|
||||
recieve_handshake(handle.clone(), url.path().to_string())
|
||||
let url = binding.get(0).unwrap();
|
||||
match url.host_str().unwrap() {
|
||||
"handshake" => recieve_handshake(handle.clone(), url.path().to_string()),
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.register_asynchronous_uri_scheme_protocol("object", move |_ctx, request, responder| {
|
||||
let base_url = fetch_base_url();
|
||||
|
||||
// Drop leading /
|
||||
let object_id = &request.uri().path()[1..];
|
||||
|
||||
let object_url = base_url
|
||||
.join("/api/v1/client/object/")
|
||||
.unwrap()
|
||||
.join(object_id)
|
||||
.unwrap();
|
||||
|
||||
info!["{}", object_url.to_string()];
|
||||
|
||||
let header = generate_authorization_header();
|
||||
let client: reqwest::blocking::Client = reqwest::blocking::Client::new();
|
||||
let response = client
|
||||
.get(object_url.to_string())
|
||||
.header("Authorization", header)
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
let resp_builder = ResponseBuilder::new().header(
|
||||
CONTENT_TYPE,
|
||||
response.headers().get("Content-Type").unwrap(),
|
||||
);
|
||||
let data = Vec::from(response.bytes().unwrap());
|
||||
let resp = resp_builder.body(data).unwrap();
|
||||
|
||||
responder.respond(resp);
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
70
src-tauri/src/library.rs
Normal file
70
src-tauri/src/library.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::{borrow::BorrowMut, sync::Mutex};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
use crate::{auth::generate_authorization_header, db::fetch_base_url, AppState};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Game {
|
||||
id: String,
|
||||
mName: String,
|
||||
mShortDescription: String,
|
||||
mDescription: String,
|
||||
// mDevelopers
|
||||
// mPublishers
|
||||
|
||||
mIconId: String,
|
||||
mBannerId: String,
|
||||
mCoverId: String,
|
||||
mImageLibrary: Vec<String>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn fetch_library(app: AppHandle) -> Result<String, String> {
|
||||
let base_url = fetch_base_url();
|
||||
let library_url = base_url.join("/api/v1/client/user/library").unwrap();
|
||||
|
||||
let header = generate_authorization_header();
|
||||
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let response = client
|
||||
.get(library_url.to_string())
|
||||
.header("Authorization", header)
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
if response.status() != 200 {
|
||||
return Err(format!(
|
||||
"Library fetch request failed with {}",
|
||||
response.status()
|
||||
));
|
||||
}
|
||||
|
||||
// Keep as string
|
||||
let games = response.json::<Vec<Game>>().unwrap();
|
||||
|
||||
let state = app.state::<Mutex<AppState>>();
|
||||
let mut handle = state.lock().unwrap();
|
||||
|
||||
for game in games.iter() {
|
||||
handle.games.insert(game.id.clone(), game.clone());
|
||||
}
|
||||
|
||||
drop(handle);
|
||||
|
||||
return Ok(json!(games.clone()).to_string());
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn fetch_game(id: String, app: tauri::AppHandle) -> Result<String, String> {
|
||||
let state = app.state::<Mutex<AppState>>();
|
||||
let handle = state.lock().unwrap();
|
||||
let game = handle.games.get(&id);
|
||||
if game.is_some() {
|
||||
return Ok(json!(game.unwrap()).to_string());
|
||||
}
|
||||
|
||||
return Ok("".to_string());
|
||||
}
|
||||
Reference in New Issue
Block a user