diff --git a/gui/src-tauri/Cargo.lock b/gui/src-tauri/Cargo.lock index c353fed..aee54d7 100644 --- a/gui/src-tauri/Cargo.lock +++ b/gui/src-tauri/Cargo.lock @@ -2005,6 +2005,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tokio", ] [[package]] diff --git a/gui/src-tauri/Cargo.toml b/gui/src-tauri/Cargo.toml index bb990f2..5c46677 100644 --- a/gui/src-tauri/Cargo.toml +++ b/gui/src-tauri/Cargo.toml @@ -16,6 +16,7 @@ tauri-build = { version = "1.2", features = [] } tauri = { version = "1.2", features = ["shell-execute", "shell-open", "shell-sidecar", "window-all"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +tokio = { version = "1.0", features = ["time"] } [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/gui/src-tauri/src/main.rs b/gui/src-tauri/src/main.rs index 523550d..765721f 100644 --- a/gui/src-tauri/src/main.rs +++ b/gui/src-tauri/src/main.rs @@ -1,15 +1,81 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; +use tauri::{window::WindowBuilder, WindowEvent}; +use tokio::time::sleep; + +const INIT_SCRIPT: &str = r#" +function onSelectUserClick(e) { + const element = document.getElementById('authorize-switch-approval-link'); + if (!element) { + return; + } + e.preventDefault(); + + // very hacky way... + window.ipc.postMessage(JSON.stringify({ + "cmd":"tauri", + "callback":0, + "error":0, + "__tauriModule":"Event", + "message":{"cmd":"emit","event":"login","payload":element.href} + })) +} +function detectAndInject() { + const element = document.getElementById('authorize-switch-approval-link'); + if (!element) { + window.setTimeout(detectAndInject, 100); + return; + } + element.addEventListener('click', onSelectUserClick); +} +detectAndInject(); +"#; // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command #[tauri::command] -fn greet(name: &str) -> String { - format!("Hello, {}! You've been greeted from Rust!", name) +async fn open_login_window(app: tauri::AppHandle, url: String) -> Option { + let window = WindowBuilder::new(&app, "login", tauri::WindowUrl::App("/".into())) + .title("Login") + .initialization_script(INIT_SCRIPT) + .build() + .ok()?; + let result: Arc>> = Arc::new(Mutex::new(None)); + let r2 = result.clone(); + let r3 = result.clone(); + + window.listen("login", move |e| { + let mut result = r2.lock().unwrap(); + *result = e.payload().map(ToString::to_string); + }); + window.on_window_event(move |e| { + if let WindowEvent::Destroyed = e { + let mut result = r3.lock().unwrap(); + if result.is_none() { + *result = Some("".to_string()); + } + } + }); + window + .eval(&format!("window.location.href = '{}'", url)) + .ok()?; + + loop { + sleep(Duration::from_millis(100)).await; + let result = result.lock().unwrap(); + if result.is_some() { + window.close().ok(); + return result.clone(); + } + } } fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![greet]) + .invoke_handler(tauri::generate_handler![open_login_window]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/gui/src/pages/Home.tsx b/gui/src/pages/Home.tsx index f320709..17cf708 100644 --- a/gui/src/pages/Home.tsx +++ b/gui/src/pages/Home.tsx @@ -2,6 +2,8 @@ import React from 'react' import { WebviewWindow } from '@tauri-apps/api/window' import { Loading } from 'components/Loading' import { JSONRPCClient, S3SIService, StdioTransport } from 'jsonrpc'; +import { invoke } from '@tauri-apps/api'; +import { emit } from '@tauri-apps/api/event'; const client = new JSONRPCClient({ transport: new StdioTransport() @@ -14,12 +16,11 @@ export const Home: React.FC = ({ }) => { if (result.error) { throw new Error(result.error.message); } - const webview = new WebviewWindow('login', { - url: 'https://accounts.nintendo.com/', - resizable: true, - focus: true, - }); + const sessionToken = await invoke('open_login_window', { + url: result.result.url + }) + console.log(sessionToken) } return <> Hello world! diff --git a/src/jsonrpc/types.ts b/src/jsonrpc/types.ts index 6e7506c..e6c310b 100644 --- a/src/jsonrpc/types.ts +++ b/src/jsonrpc/types.ts @@ -33,8 +33,11 @@ export type Transport = { }; export type RPCResult = { - result?: Result; - error?: Error; + result: Result; + error?: undefined; +} | { + result?: undefined; + error: Error; }; export type Service = {