Fontend download progress
This commit is contained in:
parent
2bb85695c0
commit
6b497d30cd
17
FCLauncher/package-lock.json
generated
17
FCLauncher/package-lock.json
generated
@ -8,9 +8,26 @@
|
|||||||
"name": "fclauncher",
|
"name": "fclauncher",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tauri-apps/api": "^1.5.6",
|
||||||
"@tauri-apps/cli": "^1"
|
"@tauri-apps/cli": "^1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tauri-apps/api": {
|
||||||
|
"version": "1.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz",
|
||||||
|
"integrity": "sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0 OR MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.6.0",
|
||||||
|
"npm": ">= 6.6.0",
|
||||||
|
"yarn": ">= 1.19.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/tauri"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tauri-apps/cli": {
|
"node_modules/@tauri-apps/cli": {
|
||||||
"version": "1.5.14",
|
"version": "1.5.14",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz",
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tauri-apps/api": "^1.5.6",
|
||||||
"@tauri-apps/cli": "^1"
|
"@tauri-apps/cli": "^1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ fn ftp_connection(username: &str, password: &str) -> Result<NativeTlsFtpStream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn ftp_retr(file: PathBuf , mut writer: impl Write, mut callback: impl FnMut(usize)) -> Result<bool, FtpError> {
|
pub fn ftp_retr(window: Option<tauri::Window>, file: PathBuf , mut writer: impl Write, mut callback: impl FnMut(Option<tauri::Window>, usize, usize)) -> Result<bool, FtpError> {
|
||||||
let mut ftp_stream = ftp_connection_anonymous().unwrap();
|
let mut ftp_stream = ftp_connection_anonymous().unwrap();
|
||||||
let file = file.to_str().unwrap().replace("\\", "/");
|
let file = file.to_str().unwrap().replace("\\", "/");
|
||||||
let size = ftp_stream.size(&file)?;
|
let size = ftp_stream.size(&file)?;
|
||||||
@ -36,9 +36,10 @@ pub fn ftp_retr(file: PathBuf , mut writer: impl Write, mut callback: impl FnMut
|
|||||||
writer.write_all(&mut tx_bytes.split_at(bytes_read).0).unwrap();
|
writer.write_all(&mut tx_bytes.split_at(bytes_read).0).unwrap();
|
||||||
total += bytes_read;
|
total += bytes_read;
|
||||||
if total == size || bytes_read == 0 {
|
if total == size || bytes_read == 0 {
|
||||||
|
callback(window.clone(), 0, size);
|
||||||
break;
|
break;
|
||||||
}else{
|
}else{
|
||||||
callback(bytes_read);
|
callback(window.clone(), bytes_read, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -14,15 +14,13 @@ fn check_java(version: u8) -> bool {
|
|||||||
dir.exists()
|
dir.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install_java(version: u8) {
|
pub fn install_java(version: u8, window: tauri::Window) {
|
||||||
if check_java(version) {
|
if check_java(version) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let ftp_dir = PathBuf::new().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win.zip" } else {"lin.tar.gz"}));
|
let ftp_dir = PathBuf::new().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win.zip" } else {"lin.tar.gz"}));
|
||||||
let mut buff = Cursor::new(vec![]);
|
let mut buff = Cursor::new(vec![]);
|
||||||
let mut total: usize = 0;
|
ftp::ftp_retr(Some(window), ftp_dir, &mut buff, |window, data, size| util::download_callback(format!("Java {}", version), window,data, size)).unwrap();
|
||||||
let size = ftp_get_size(ftp_dir.clone()).unwrap();
|
|
||||||
ftp::ftp_retr(ftp_dir, &mut buff, |data| util::download_callback(data, &mut total, size)).unwrap();
|
|
||||||
|
|
||||||
std::fs::create_dir_all(get_local_data_directory().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win" } else {"lin"}))).unwrap();
|
std::fs::create_dir_all(get_local_data_directory().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win" } else {"lin"}))).unwrap();
|
||||||
buff.rewind().unwrap();
|
buff.rewind().unwrap();
|
||||||
|
@ -29,9 +29,10 @@ fn greet(name: &str) -> String {
|
|||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
prism::install_prism();
|
modpack::get_modpacks();
|
||||||
|
//prism::install_prism();
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, prism::launch_prism])
|
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, prism::launch_prism, prism::install_prism])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use std::io::{Read, Seek, Write};
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -61,22 +62,22 @@ fn check_modpack_needs_update(id: String) -> bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn launch_modpack(id: String){
|
pub async fn launch_modpack(window: tauri::Window, id: String){
|
||||||
|
|
||||||
if check_modpack_needs_update(id.clone()) {
|
if check_modpack_needs_update(id.clone()) {
|
||||||
install_modpack(id.clone());
|
install_modpack(window, id.clone());
|
||||||
}
|
}
|
||||||
// Launch
|
// Launch
|
||||||
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-l").arg(get_modpack_name(id)).spawn().unwrap();
|
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-l").arg(get_modpack_name(id)).spawn().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install_modpack(id: String){
|
fn install_modpack(window: tauri::Window, id: String){
|
||||||
let versions = get_versions(id.clone());
|
let versions = get_versions(id.clone());
|
||||||
let path = env::temp_dir().join(format!("{}.mrpack", get_modpack_name(id.clone())));
|
let path = env::temp_dir().join(format!("{}.mrpack", get_modpack_name(id.clone())));
|
||||||
let mut file = File::create(path.clone()).unwrap();
|
let mut file = File::create(path.clone()).unwrap();
|
||||||
let ftp_path = PathBuf::new().join(id.clone()).join(versions[versions.len()-1].file.clone().as_str());
|
let ftp_path = PathBuf::new().join(id.clone()).join(versions[versions.len()-1].file.clone().as_str());
|
||||||
println!("Downloading file {}", ftp_path.to_str().unwrap());
|
println!("Downloading file {}", ftp_path.to_str().unwrap());
|
||||||
ftp::ftp_retr(ftp_path, &mut file, |_| return).unwrap();
|
ftp::ftp_retr(Some(window.clone()), ftp_path, &mut file, |window, data, size| util::download_callback(get_modpack_name(id.clone()), window, data, size)).unwrap();
|
||||||
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-I").arg(path).spawn().unwrap();
|
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-I").arg(path).spawn().unwrap();
|
||||||
loop {
|
loop {
|
||||||
let version_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join(".minecraft").join("version.txt");
|
let version_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join(".minecraft").join("version.txt");
|
||||||
@ -102,7 +103,7 @@ fn install_modpack(id: String){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let java = get_java_version(mc_version);
|
let java = get_java_version(mc_version);
|
||||||
java::install_java(java);
|
java::install_java(java, window.clone());
|
||||||
|
|
||||||
let option_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join("instance.cfg");
|
let option_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join("instance.cfg");
|
||||||
let mut option_file = File::open(option_path.clone()).unwrap();
|
let mut option_file = File::open(option_path.clone()).unwrap();
|
||||||
@ -132,7 +133,7 @@ pub fn get_modpacks() -> Vec<ModpackEntry> {
|
|||||||
static mut modpacks: Vec<ModpackEntry> = Vec::new();
|
static mut modpacks: Vec<ModpackEntry> = Vec::new();
|
||||||
if modpacks.is_empty() {
|
if modpacks.is_empty() {
|
||||||
let mut buf = Cursor::new(vec![]);
|
let mut buf = Cursor::new(vec![]);
|
||||||
ftp::ftp_retr(PathBuf::new().join("modpacks.json"), &mut buf, |_| return);
|
ftp::ftp_retr(None, PathBuf::new().join("modpacks.json"), &mut buf, |_, _, _| return);
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
let v: Value = serde_json::from_reader(buf).unwrap();
|
let v: Value = serde_json::from_reader(buf).unwrap();
|
||||||
println!("{}", v[0]["name"]);
|
println!("{}", v[0]["name"]);
|
||||||
@ -147,7 +148,7 @@ pub fn get_modpacks() -> Vec<ModpackEntry> {
|
|||||||
fn get_versions(id: String) -> Vec<VersionEntry> {
|
fn get_versions(id: String) -> Vec<VersionEntry> {
|
||||||
let mut versions: Vec<VersionEntry> = Vec::new();
|
let mut versions: Vec<VersionEntry> = Vec::new();
|
||||||
let mut buf = Cursor::new(vec![]);
|
let mut buf = Cursor::new(vec![]);
|
||||||
ftp::ftp_retr(PathBuf::new().join(id).join("versions.json"), &mut buf, |_| return);
|
ftp::ftp_retr(None, PathBuf::new().join(id).join("versions.json"), &mut buf, |_, _, _| return);
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
let v: Value = serde_json::from_reader(buf).unwrap();
|
let v: Value = serde_json::from_reader(buf).unwrap();
|
||||||
for version in v.as_array().unwrap() {
|
for version in v.as_array().unwrap() {
|
||||||
|
@ -3,7 +3,7 @@ use flate2::read::GzDecoder;
|
|||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
use tauri::api::file;
|
use tauri::api::file;
|
||||||
|
|
||||||
use crate::{ftp, java, system_dirs::{get_local_data_directory, get_prism_executable}};
|
use crate::{ftp, java, system_dirs::{get_local_data_directory, get_prism_executable}, util};
|
||||||
|
|
||||||
|
|
||||||
pub fn check_prism() -> bool {
|
pub fn check_prism() -> bool {
|
||||||
@ -11,21 +11,19 @@ pub fn check_prism() -> bool {
|
|||||||
path.exists()
|
path.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
|
#[tauri::command]
|
||||||
|
pub async fn install_prism(window: tauri::Window){
|
||||||
if check_prism() {
|
if check_prism() {
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
java::install_java(21);
|
java::install_java(21, window.clone());
|
||||||
let path = PathBuf::new().join("prism").join(format!("prism-{}",if env::consts::OS == "windows" {"win.zip"} else {"lin.tar.gz"}));
|
let path = PathBuf::new().join("prism").join(format!("prism-{}",if env::consts::OS == "windows" {"win.zip"} else {"lin.tar.gz"}));
|
||||||
let size = ftp::ftp_get_size(path.clone())?;
|
let size = ftp::ftp_get_size(path.clone()).unwrap();
|
||||||
let mut buff = Cursor::new(vec![]);
|
let mut buff = Cursor::new(vec![]);
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
ftp::ftp_retr(path, &mut buff, |data| {
|
ftp::ftp_retr(Some(window.clone()), path, &mut buff, |window: Option<tauri::Window>, data, size| util::download_callback("Prism Launcher".to_string(),window, data, size)).unwrap();
|
||||||
total += data;
|
std::fs::create_dir_all(get_local_data_directory().join("prism")).unwrap();
|
||||||
println!("Downloading Prism: {}MB / {}MB", total/(1024*1024), size/(1024*1024));
|
buff.rewind().unwrap();
|
||||||
}).unwrap();
|
|
||||||
std::fs::create_dir_all(get_local_data_directory().join("prism"))?;
|
|
||||||
buff.rewind()?;
|
|
||||||
if env::consts::OS != "windows" {
|
if env::consts::OS != "windows" {
|
||||||
let tar = GzDecoder::new(buff);
|
let tar = GzDecoder::new(buff);
|
||||||
let mut archive = Archive::new(tar);
|
let mut archive = Archive::new(tar);
|
||||||
@ -39,7 +37,7 @@ pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut buff = Cursor::new(vec![]);
|
let mut buff = Cursor::new(vec![]);
|
||||||
ftp::ftp_retr(PathBuf::new().join("prism").join("prismlauncher.cfg"), &mut buff, |_| return).unwrap();
|
ftp::ftp_retr(Some(window.clone()), PathBuf::new().join("prism").join("prismlauncher.cfg"), &mut buff, |_, _, _| return).unwrap();
|
||||||
buff.rewind();
|
buff.rewind();
|
||||||
let mut file = File::create(get_local_data_directory().join("prism").join("prismlauncher.cfg")).unwrap();
|
let mut file = File::create(get_local_data_directory().join("prism").join("prismlauncher.cfg")).unwrap();
|
||||||
loop {
|
loop {
|
||||||
@ -57,7 +55,6 @@ pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,30 @@
|
|||||||
|
use std::clone;
|
||||||
|
|
||||||
pub fn download_callback(count: usize, total: &mut usize, size: usize){
|
use serde::Serialize;
|
||||||
*total += count;
|
|
||||||
println!("Downloading {}MB / {}MB", *total/(1024*1024), size/(1024*1024));
|
|
||||||
|
#[derive(Clone, Serialize)]
|
||||||
|
pub struct DownloadStatus {
|
||||||
|
downloaded: usize,
|
||||||
|
total: usize,
|
||||||
|
time_elapsed: usize,
|
||||||
|
download_name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn download_callback(download_name: String, window: Option<tauri::Window>, count: usize, size: usize){
|
||||||
|
unsafe{
|
||||||
|
static mut total: usize = 0;
|
||||||
|
total += count;
|
||||||
|
if let Some(window1) = window.clone() {
|
||||||
|
window1.emit("download_progress", DownloadStatus{downloaded: total, total: size, time_elapsed: 0, download_name: download_name});
|
||||||
|
}
|
||||||
|
println!("Downloading {}MB / {}MB", total/(1024*1024), size/(1024*1024));
|
||||||
|
if count == 0 {
|
||||||
|
if let Some(window2) = window {
|
||||||
|
window2.emit("download_finished", true);
|
||||||
|
}
|
||||||
|
total = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<body onload="load();">
|
<body>
|
||||||
|
|
||||||
<div class="Logo">
|
<div class="Logo">
|
||||||
<img src="assets/Title.png" alt="Title" id="Title">
|
<img src="assets/Title.png" alt="Title" id="Title">
|
||||||
@ -28,6 +28,9 @@
|
|||||||
<select name="modSelect" id="Modpacks" class="bg-dark text-white">
|
<select name="modSelect" id="Modpacks" class="bg-dark text-white">
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<p id="download_name"></p>
|
||||||
|
<p id="download_progress"></p>
|
||||||
|
|
||||||
<button id="launchGame" type="button">Launch Minecraft</button>
|
<button id="launchGame" type="button">Launch Minecraft</button>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,24 @@
|
|||||||
const { invoke } = window.__TAURI__.tauri;
|
const { invoke } = window.__TAURI__.tauri;
|
||||||
|
const { listen } = window.__TAURI__.event;
|
||||||
|
//import { listen } from '@tauri-apps/api';
|
||||||
|
|
||||||
let greetInputEl;
|
let greetInputEl;
|
||||||
let greetMsgEl;
|
let greetMsgEl;
|
||||||
|
|
||||||
async function greet() {
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
const download_progress = listen("download_progress", (progress) => {
|
||||||
greetMsgEl.textContent = "testing";
|
console.log("Downloading");
|
||||||
//greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value });
|
//console.log("Downloaded "+progress.payload.downloaded/(1024*1024) +"MB / " + progress.payload.total/(1024*1024) + "MB");
|
||||||
}
|
document.getElementById("download_name").textContent = "Downloading "+progress.payload.download_name;
|
||||||
|
document.getElementById("download_progress").textContent = progress.payload.downloaded/(1024*1024) + "MB / "+progress.payload.total/(1024*1024)+"MB";
|
||||||
|
document.getElementById("launchGame").disabled = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const download_finished = listen("download_finished", (event) => {
|
||||||
|
document.getElementById("download_name").textContent = "";
|
||||||
|
document.getElementById("download_progress").textContent = "";
|
||||||
|
document.getElementById("launchGame").disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
@ -29,6 +40,7 @@ function load() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.onload = async function() {
|
window.onload = async function() {
|
||||||
|
invoke("install_prism");
|
||||||
invoke("get_modpacks").then(addModpacks);
|
invoke("get_modpacks").then(addModpacks);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -48,6 +60,7 @@ function addModpacks(modpacks) {
|
|||||||
function gameLaunch() {
|
function gameLaunch() {
|
||||||
var packId = document.getElementById("Modpacks");
|
var packId = document.getElementById("Modpacks");
|
||||||
var selectedId = packId.value;
|
var selectedId = packId.value;
|
||||||
|
document.getElementById("launchGame").disabled = true;
|
||||||
//TODO Launch Game
|
//TODO Launch Game
|
||||||
invoke("launch_modpack", { id: selectedId}).then(window.close);
|
invoke("launch_modpack", { id: selectedId}).then(window.close);
|
||||||
|
|
||||||
|
34
FCLauncher/yarn.lock
Normal file
34
FCLauncher/yarn.lock
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@tauri-apps/api@^1.5.6":
|
||||||
|
version "1.5.6"
|
||||||
|
resolved "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz"
|
||||||
|
integrity sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-x64-gnu@1.5.14":
|
||||||
|
version "1.5.14"
|
||||||
|
resolved "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.14.tgz"
|
||||||
|
integrity sha512-kD9v/UwPDuhIgq2TJj/s2/7rqk+vmExVV6xHPKI8vVbIvlNAOZqmx3fpxjej1241vhJ/piGd/m6q6YMWGsL0oQ==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-x64-musl@1.5.14":
|
||||||
|
version "1.5.14"
|
||||||
|
resolved "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.14.tgz"
|
||||||
|
integrity sha512-204Drgg9Zx0+THKndqASz4+iPCwqA3gQVF9C0CDIArNXrjPyJjVvW8VP5CHiZYaTNWxlz/ltyxluM6UFWbXNFw==
|
||||||
|
|
||||||
|
"@tauri-apps/cli@^1":
|
||||||
|
version "1.5.14"
|
||||||
|
resolved "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz"
|
||||||
|
integrity sha512-JOSMKymlg116UdEXSj69eg5p1OtZnQkUE0qIGbtNDO1sk3X/KgBN6+oHBW0BzPStp/W0AjBgrMWCqjHPwEpOug==
|
||||||
|
optionalDependencies:
|
||||||
|
"@tauri-apps/cli-darwin-arm64" "1.5.14"
|
||||||
|
"@tauri-apps/cli-darwin-x64" "1.5.14"
|
||||||
|
"@tauri-apps/cli-linux-arm-gnueabihf" "1.5.14"
|
||||||
|
"@tauri-apps/cli-linux-arm64-gnu" "1.5.14"
|
||||||
|
"@tauri-apps/cli-linux-arm64-musl" "1.5.14"
|
||||||
|
"@tauri-apps/cli-linux-x64-gnu" "1.5.14"
|
||||||
|
"@tauri-apps/cli-linux-x64-musl" "1.5.14"
|
||||||
|
"@tauri-apps/cli-win32-arm64-msvc" "1.5.14"
|
||||||
|
"@tauri-apps/cli-win32-ia32-msvc" "1.5.14"
|
||||||
|
"@tauri-apps/cli-win32-x64-msvc" "1.5.14"
|
Loading…
Reference in New Issue
Block a user