mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-14 14:17:25 -05:00
added discord rpc
This commit is contained in:
@@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tauri::webview::NewWindowResponse;
|
||||
use tauri::{AppHandle, Emitter, Manager, State, WebviewUrl, WebviewWindowBuilder};
|
||||
use tauri::{AppHandle, Emitter, Listener, Manager, State, WebviewUrl, WebviewWindowBuilder};
|
||||
|
||||
fn debug_log(msg: &str) {
|
||||
let log_dir = if let Ok(app_data) = std::env::var("APPDATA") {
|
||||
@@ -40,6 +40,19 @@ fn debug_log(msg: &str) {
|
||||
|
||||
struct NodeServices(Mutex<Option<Child>>);
|
||||
|
||||
struct NodeStdin(Mutex<Option<std::process::ChildStdin>>);
|
||||
|
||||
fn write_node_line(state: &NodeStdin, line: &str) -> Result<(), String> {
|
||||
use std::io::Write;
|
||||
let mut lock = state.0.lock().map_err(|e| e.to_string())?;
|
||||
if let Some(stdin) = lock.as_mut() {
|
||||
stdin.write_all(line.as_bytes()).map_err(|e| e.to_string())?;
|
||||
stdin.write_all(b"\n").map_err(|e| e.to_string())?;
|
||||
stdin.flush().map_err(|e| e.to_string())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static WINDOW_COUNTER: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(1);
|
||||
|
||||
static READY_URL: Mutex<Option<String>> = Mutex::new(None);
|
||||
@@ -485,6 +498,70 @@ const LINK_HANDLER_SCRIPT: &str = r##"
|
||||
injectLiquidNavBar();
|
||||
}
|
||||
startNavObserver();
|
||||
|
||||
(function () {
|
||||
let last = '';
|
||||
let timer = null;
|
||||
|
||||
function metaImage() {
|
||||
const m = document.querySelector("meta[property='og:image']");
|
||||
return m && m.content ? m.content : '';
|
||||
}
|
||||
|
||||
function send(attempt) {
|
||||
const n = typeof attempt === 'number' ? attempt : 0;
|
||||
const tauri = window.__TAURI__;
|
||||
if (!tauri || !tauri.core) {
|
||||
if (n < 40) setTimeout(() => send(n + 1), 250);
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
label: window.__VYLA_WINDOW_LABEL || 'main',
|
||||
url: location.href,
|
||||
title: document.title || '',
|
||||
image: metaImage(),
|
||||
closed: false
|
||||
};
|
||||
const v = document.querySelector('video');
|
||||
if (v && Number.isFinite(v.duration) && v.duration > 0) {
|
||||
payload.position = v.currentTime;
|
||||
payload.duration = v.duration;
|
||||
payload.paused = v.paused;
|
||||
}
|
||||
if (!tauri.event) {
|
||||
if (n < 40) setTimeout(() => send(n + 1), 250);
|
||||
return;
|
||||
}
|
||||
tauri.event.emit('vyla-presence', payload).catch((e) => console.error('[vyla] presence emit failed', e));
|
||||
}
|
||||
|
||||
function check() {
|
||||
if (location.href === last) return;
|
||||
last = location.href;
|
||||
send();
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(send, 1500);
|
||||
}
|
||||
|
||||
['pushState', 'replaceState'].forEach((fn) => {
|
||||
const orig = history[fn];
|
||||
history[fn] = function () {
|
||||
const r = orig.apply(this, arguments);
|
||||
setTimeout(check, 0);
|
||||
return r;
|
||||
};
|
||||
});
|
||||
|
||||
window.addEventListener('popstate', check);
|
||||
window.addEventListener('hashchange', check);
|
||||
window.addEventListener('focus', () => send());
|
||||
['play', 'pause', 'seeked'].forEach((name) => {
|
||||
document.addEventListener(name, () => send(), true);
|
||||
});
|
||||
setInterval(check, 2000);
|
||||
setInterval(() => { if (document.hasFocus()) send(); }, 5000);
|
||||
check();
|
||||
})();
|
||||
"##;
|
||||
|
||||
#[tauri::command]
|
||||
@@ -515,6 +592,13 @@ fn win_drag(window: tauri::Window) -> Result<(), String> {
|
||||
window.start_dragging().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn report_location(state: State<'_, NodeStdin>, payload: serde_json::Value) -> Result<(), String> {
|
||||
let line = serde_json::json!({ "type": "presence", "payload": payload }).to_string();
|
||||
debug_log(&format!("[PRESENCE] {}", line));
|
||||
write_node_line(&state, &line)
|
||||
}
|
||||
|
||||
fn normalize_url(url: &str) -> Option<tauri::Url> {
|
||||
let final_url = if url.starts_with("http") || url.starts_with("tauri://") {
|
||||
url.to_string()
|
||||
@@ -647,9 +731,11 @@ fn main() {
|
||||
win_maximize,
|
||||
win_close,
|
||||
win_drag,
|
||||
open_new_window
|
||||
open_new_window,
|
||||
report_location
|
||||
])
|
||||
.manage(NodeServices(Mutex::new(None)))
|
||||
.manage(NodeStdin(Mutex::new(None)))
|
||||
.setup(|app| {
|
||||
debug_log("Tauri setup started");
|
||||
let app_data = app.path().app_data_dir().unwrap_or_default();
|
||||
@@ -895,6 +981,13 @@ fn main() {
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(stdin) = child.stdin.take() {
|
||||
let stdin_state: State<NodeStdin> = app.state();
|
||||
if let Ok(mut lock) = stdin_state.0.lock() {
|
||||
*lock = Some(stdin);
|
||||
};
|
||||
}
|
||||
|
||||
let state: State<NodeServices> = app.state();
|
||||
if let Ok(mut lock) = state.0.lock() {
|
||||
*lock = Some(child);
|
||||
@@ -911,6 +1004,14 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
let presence_handle = app.handle().clone();
|
||||
app.listen("vyla-presence", move |event| {
|
||||
debug_log(&format!("[PRESENCE] {}", event.payload()));
|
||||
let line = format!("{{\"type\":\"presence\",\"payload\":{}}}", event.payload());
|
||||
let state: State<NodeStdin> = presence_handle.state();
|
||||
let _ = write_node_line(&state, &line);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| {
|
||||
@@ -924,6 +1025,11 @@ fn main() {
|
||||
}
|
||||
};
|
||||
window.app_handle().exit(0);
|
||||
} else {
|
||||
let label = window.label().to_string();
|
||||
let line = serde_json::json!({ "type": "presence", "payload": { "label": label, "closed": true } }).to_string();
|
||||
let state: State<NodeStdin> = window.state();
|
||||
let _ = write_node_line(&state, &line);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user