diff --git a/package.json b/package.json index 16d8bd1..8ae6d04 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@tauri-apps/plugin-opener": "2.4.0", "@tauri-apps/plugin-os": "2.3.0", "axios": "1.10.0", + "date-fns": "4.1.0", "react": "19.1.0", "react-dom": "19.1.0" }, diff --git a/src-tauri/src/keys.rs b/src-tauri/src/keys.rs index 0bfebb6..2c6c4cf 100644 --- a/src-tauri/src/keys.rs +++ b/src-tauri/src/keys.rs @@ -1,8 +1,8 @@ pub struct Keys; impl Keys { - pub const SERVER_RECEIVE_TRANSFER_KEY: &str = ""; - pub const SERVER_SEND_TRANSFER_KEY: &str = ""; - pub const CONFIG_ENCRYPTION_KEY: &str = ""; - pub const VERSIONS_ENCRYPTION_KEY: &str = ""; + pub const SERVER_RECEIVE_TRANSFER_KEY: &str = ""; + pub const SERVER_SEND_TRANSFER_KEY: &str = ""; + pub const CONFIG_ENCRYPTION_KEY: &str = ""; + pub const VERSIONS_ENCRYPTION_KEY: &str = ""; } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b0b770f..42decd5 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,8 +1,8 @@ #[cfg_attr(mobile, tauri::mobile_entry_point)] - mod keys; use futures_util::stream::StreamExt; +use keys::Keys; use std::{ fs::{File, create_dir_all}, io::{BufReader, Write, copy}, @@ -13,9 +13,9 @@ use std::{ use tauri::{AppHandle, Emitter, Manager}; use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; use tauri_plugin_opener::OpenerExt; +use tauri_plugin_os::platform; use tokio::{io::AsyncWriteExt, task::spawn_blocking, time::timeout}; use zip::ZipArchive; -use keys::Keys; #[cfg(target_os = "linux")] use std::{fs, os::unix::fs::PermissionsExt}; @@ -48,6 +48,7 @@ pub async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> zip::result::Z .map_err(|e| zip::result::ZipError::Io(std::io::Error::new(std::io::ErrorKind::Other, e)))? } +#[allow(unused_variables)] #[tauri::command] async fn download( app: AppHandle, @@ -75,7 +76,10 @@ async fn download( let download_part_path = downloads_path.join(format!("{}.part", name)); let download_zip_path = downloads_path.join(format!("{}.zip", name)); - let executable_path = game_path.join(&name).join(&executable); + + if download_part_path.exists() { + let _ = tokio::fs::remove_file(&download_part_path).await; + } let _ = tokio::fs::create_dir_all(&downloads_path).await; if let Ok(true) = tokio::fs::try_exists(&game_path.join(name.clone())).await { @@ -132,6 +136,7 @@ async fn download( #[cfg(target_os = "linux")] { + let executable_path = game_path.join(&name).join(&executable); let mut perms = fs::metadata(&executable_path).unwrap().permissions(); perms.set_mode(0o755); fs::set_permissions(executable_path, perms).unwrap(); @@ -142,7 +147,7 @@ async fn download( } #[tauri::command] -fn launch_game(app: AppHandle, name: String, executable: String) { +fn launch_game(app: AppHandle, name: String, executable: String, wine: bool) { let game_folder = app .path() .app_local_data_dir() @@ -158,7 +163,39 @@ fn launch_game(app: AppHandle, name: String, executable: String) { .show(|_| {}); return; } - match Command::new(&game_path).current_dir(&game_folder).spawn() { + let result = if wine && (platform() == "linux" || platform() == "macos") { + let wine_path_output = Command::new("which").arg("wine").output(); + let wine_path = match wine_path_output { + Ok(output) if output.status.success() => { + let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); + if path.is_empty() { + app.dialog() + .message("Wine is not installed. Please install Wine to run this version of Berry Dash.") + .kind(MessageDialogKind::Error) + .title("Wine not found") + .show(|_| {}); + return; + } + path + } + _ => { + app.dialog() + .message("Wine is not installed. Please install Wine to run this version of Berry Dash.") + .kind(MessageDialogKind::Error) + .title("Wine not found") + .show(|_| {}); + return; + } + }; + Command::new(wine_path) + .arg(&game_path) + .current_dir(&game_folder) + .spawn() + } else { + Command::new(&game_path).current_dir(&game_folder).spawn() + }; + + match result { Ok(_) => println!("Game launched successfully."), Err(e) => { app.dialog() diff --git a/src/componets/Sidebar.tsx b/src/componets/Sidebar.tsx index 60e5237..c25ea7b 100644 --- a/src/componets/Sidebar.tsx +++ b/src/componets/Sidebar.tsx @@ -2,14 +2,24 @@ import './Sidebar.css' import Icon from '../Icon.png' import { openUrl } from '@tauri-apps/plugin-opener' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCog, faDownload, faRankingStar, faServer } from '@fortawesome/free-solid-svg-icons' +import { + faCog, + faDownload, + faRankingStar, + faServer +} from '@fortawesome/free-solid-svg-icons' import { faDiscord } from '@fortawesome/free-brands-svg-icons' import { useState } from 'react' import { platform } from '@tauri-apps/plugin-os' import { getCurrentWindow } from '@tauri-apps/api/window' import { SidebarProps } from '../types/SidebarProps' -export default function Sidebar({ setShowPopup, setPopupMode, setFadeOut }: SidebarProps) { +export default function Sidebar ({ + setShowPopup, + setPopupMode, + setFadeOut, + downloadProgress +}: SidebarProps) { const [rot, setRot] = useState(0) const [dir, setDir] = useState(1) @@ -41,7 +51,9 @@ export default function Sidebar({ setShowPopup, setPopupMode, setFadeOut }: Side style={{ transform: `rotate(${rot}deg)`, transition: 'transform 0.3s ease', - marginTop: ['windows','macos'].includes(platform()) ? '20px' : '0px' + marginTop: ['windows', 'macos'].includes(platform()) + ? '20px' + : '0px' }} onClick={() => setRot(r => { @@ -71,14 +83,60 @@ export default function Sidebar({ setShowPopup, setPopupMode, setFadeOut }: Side } /> -