Creation and deletion of modpacks implemented.
This commit is contained in:
parent
332acf65c8
commit
c39fcfe66b
@ -11,7 +11,7 @@ edition = "2021"
|
|||||||
tauri-build = { version = "1", features = [] }
|
tauri-build = { version = "1", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "1", features = [ "updater", "dialog-ask", "shell-open"] }
|
tauri = { version = "1", features = [ "dialog-open", "updater", "dialog-ask", "shell-open"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
suppaftp = { version = "6.0.1", features = ["native-tls"] }
|
suppaftp = { version = "6.0.1", features = ["native-tls"] }
|
||||||
@ -25,6 +25,7 @@ parking_lot = "0.12.3"
|
|||||||
reqwest = { version = "0.12.5", features = ["stream"] }
|
reqwest = { version = "0.12.5", features = ["stream"] }
|
||||||
futures-util = "0.3.30"
|
futures-util = "0.3.30"
|
||||||
ssh2 = "0.9.4"
|
ssh2 = "0.9.4"
|
||||||
|
chrono = "0.4.38"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::modpack::get_modpacks;
|
||||||
|
use crate::modpack::VersionEntry;
|
||||||
use crate::sftp;
|
use crate::sftp;
|
||||||
use crate::modpack;
|
use crate::modpack;
|
||||||
|
use crate::ModpackEntry;
|
||||||
use ssh2::Sftp;
|
use ssh2::Sftp;
|
||||||
use ssh2::Session;
|
use ssh2::Session;
|
||||||
|
use chrono;
|
||||||
|
|
||||||
//static USERNAME: parking_lot::Mutex<String> = parking_lot::const_mutex(String::new());
|
//static USERNAME: parking_lot::Mutex<String> = parking_lot::const_mutex(String::new());
|
||||||
//static PASSWORD: parking_lot::Mutex<String> = parking_lot::const_mutex(String::new());
|
//static PASSWORD: parking_lot::Mutex<String> = parking_lot::const_mutex(String::new());
|
||||||
@ -42,6 +46,16 @@ async fn update_modpacks(modpacks: Vec<modpack::ModpackEntry>) -> Result<(), Str
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn update_versions(id: String, versions: Vec<modpack::VersionEntry>) -> Result<(), String>{
|
||||||
|
let data = serde_json::to_string(&versions).or(Err("Unable to serialize json"))?;
|
||||||
|
let reader = Cursor::new(data.as_bytes());
|
||||||
|
let ref mut session = *SESSION.lock().await;
|
||||||
|
if let Some(session) = session {
|
||||||
|
sftp::uplaod(None, session.clone(), PathBuf::from(format!("/ftp/{}/versions.json", id)), reader, format!("modpacks.json"), data.as_bytes().len()).await;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn shift_up(id: String){
|
pub async fn shift_up(id: String){
|
||||||
let mut modpacks = modpack::get_modpacks().await;
|
let mut modpacks = modpack::get_modpacks().await;
|
||||||
@ -73,3 +87,44 @@ pub async fn shift_down(id: String){
|
|||||||
}
|
}
|
||||||
update_modpacks(modpacks).await;
|
update_modpacks(modpacks).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn add_pack(id: String, name: String){
|
||||||
|
{
|
||||||
|
let ref mut session = *SESSION.lock().await;
|
||||||
|
if let Some(session) = session{
|
||||||
|
sftp::mkdir(session.clone(), PathBuf::from(format!("/ftp/{}", id))).await;
|
||||||
|
sftp::mkdir(session.clone(), PathBuf::from(format!("/ftp/{}/Versions", id))).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let versions: Vec<VersionEntry> = Vec::new();
|
||||||
|
update_versions(id.clone(), versions).await;
|
||||||
|
let mut modpacks = get_modpacks().await;
|
||||||
|
modpacks.push(modpack::ModpackEntry{id: id, name: name, last_updated: format!("{:?}", chrono::offset::Utc::now())});
|
||||||
|
update_modpacks(modpacks).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remove_pack(id: String){
|
||||||
|
let mut modpacks = get_modpacks().await;
|
||||||
|
let mut index = 0;
|
||||||
|
for pack in modpacks.clone() {
|
||||||
|
if pack.id == id {
|
||||||
|
modpacks.remove(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
update_modpacks(modpacks).await;
|
||||||
|
{
|
||||||
|
let ref mut session = *SESSION.lock().await;
|
||||||
|
if let Some(session) = session{
|
||||||
|
sftp::rmdir(session.clone(), PathBuf::from(format!("/ftp/{}", id))).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn update_pack(id: String, path: String, version: String){
|
||||||
|
println!("Update modpack {}, to version {}, from file {}", id, version, path);
|
||||||
|
}
|
@ -36,7 +36,7 @@ fn main() {
|
|||||||
//modpack::get_modpacks();
|
//modpack::get_modpacks();
|
||||||
//prism::install_prism();
|
//prism::install_prism();
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, modpack::get_versions, prism::launch_prism, prism::install_prism, admin::login, admin::drop_session, admin::shift_up, admin::shift_down])
|
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, modpack::get_versions, modpack::get_latest_version, prism::launch_prism, prism::install_prism, admin::login, admin::drop_session, admin::shift_up, admin::shift_down, admin::add_pack, admin::remove_pack, admin::update_pack])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
@ -20,16 +20,16 @@ use crate::https;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct ModpackEntry{
|
pub struct ModpackEntry{
|
||||||
name: String,
|
pub name: String,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
last_updated: String
|
pub last_updated: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct VersionEntry{
|
pub struct VersionEntry{
|
||||||
version: String,
|
pub Version: String,
|
||||||
file: String,
|
pub File: String,
|
||||||
date: String
|
pub Date: String
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_modpack_name(id: String) -> String {
|
async fn get_modpack_name(id: String) -> String {
|
||||||
@ -56,7 +56,7 @@ async fn check_modpack_needs_update(id: String) -> bool{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let versions = versions.unwrap();
|
let versions = versions.unwrap();
|
||||||
let latest = versions[versions.len()-1].version.clone();
|
let latest = versions[versions.len()-1].Version.clone();
|
||||||
|
|
||||||
let mut file = File::open(get_local_data_directory().join("prism").join("instances").join(instance_name).join(".minecraft").join("version.txt")).unwrap();
|
let mut file = File::open(get_local_data_directory().join("prism").join("instances").join(instance_name).join(".minecraft").join("version.txt")).unwrap();
|
||||||
let mut current = String::new();
|
let mut current = String::new();
|
||||||
@ -84,10 +84,10 @@ async fn install_modpack(window: tauri::Window, id: String){
|
|||||||
let versions = get_versions(id.clone()).await.unwrap();
|
let versions = get_versions(id.clone()).await.unwrap();
|
||||||
let path = env::temp_dir().join(format!("{}.mrpack", get_modpack_name(id.clone()).await));
|
let path = env::temp_dir().join(format!("{}.mrpack", get_modpack_name(id.clone()).await));
|
||||||
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(Some(window.clone()), ftp_path, &mut file, |window, data, size| util::download_callback(name.clone(), window, data, size)).unwrap();
|
//ftp::ftp_retr(Some(window.clone()), ftp_path, &mut file, |window, data, size| util::download_callback(name.clone(), window, data, size)).unwrap();
|
||||||
https::download(Some(window.clone()), format!("https://gitea.piwalker.net/fclauncher/{}/{}", id.clone(), versions[versions.len()-1].file.clone()), &mut file, get_modpack_name(id.clone()).await).await;
|
https::download(Some(window.clone()), format!("https://gitea.piwalker.net/fclauncher/{}/{}", id.clone(), versions[versions.len()-1].File.clone()), &mut file, get_modpack_name(id.clone()).await).await;
|
||||||
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()).await).join(".minecraft").join("version.txt");
|
let version_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone()).await).join(".minecraft").join("version.txt");
|
||||||
@ -95,7 +95,7 @@ async fn install_modpack(window: tauri::Window, id: String){
|
|||||||
let mut ver_file = File::open(version_path).unwrap();
|
let mut ver_file = File::open(version_path).unwrap();
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
ver_file.read_to_string(&mut buf).unwrap();
|
ver_file.read_to_string(&mut buf).unwrap();
|
||||||
if buf == versions[versions.len()-1].version.clone().as_str() {
|
if buf == versions[versions.len()-1].Version.clone().as_str() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,10 +181,10 @@ pub async fn get_versions(id: String) -> Result<Vec<VersionEntry>,String> {
|
|||||||
//ftp::ftp_retr(None, PathBuf::new().join(id).join("versions.json"), &mut buf, |_, _, _| return);
|
//ftp::ftp_retr(None, PathBuf::new().join(id).join("versions.json"), &mut buf, |_, _, _| return);
|
||||||
https::download(None, format!("https://gitea.piwalker.net/fclauncher/{}/versions.json", id.clone()), &mut buf, format!("{}/versions.json", id.clone())).await;
|
https::download(None, format!("https://gitea.piwalker.net/fclauncher/{}/versions.json", id.clone()), &mut buf, format!("{}/versions.json", id.clone())).await;
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
let v: Value = serde_json::from_reader(buf).or(Err(format!("Unable to parse json")))?;
|
let versions: Vec<VersionEntry> = serde_json::from_reader(buf).or(Err(format!("Unable to parse json")))?;
|
||||||
for version in v.as_array().unwrap() {
|
//for version in v.as_array().unwrap() {
|
||||||
versions.push(VersionEntry{version: version["Version"].as_str().unwrap().to_string(), file: version["File"].as_str().unwrap().to_string(), date: version["Date"].as_str().unwrap().to_string()});
|
//versions.push(VersionEntry{version: version["Version"].as_str().unwrap().to_string(), file: version["File"].as_str().unwrap().to_string(), date: version["Date"].as_str().unwrap().to_string()});
|
||||||
}
|
//}
|
||||||
return Ok(versions.clone());
|
return Ok(versions.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +205,15 @@ fn get_java_version(mc_version: &str) -> u8{
|
|||||||
return java;
|
return java;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn get_latest_version(id: String) -> Result<String, String>{
|
||||||
|
let versions = get_versions(id).await.unwrap();
|
||||||
|
if(versions.len() == 0){
|
||||||
|
return Ok(format!(""));
|
||||||
|
}
|
||||||
|
Ok(versions[versions.len()-1].Version.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//pub fn create_json(modpacks: Vec<ModpackEntry>) -> Result<serde_json::Value, String> {
|
//pub fn create_json(modpacks: Vec<ModpackEntry>) -> Result<serde_json::Value, String> {
|
||||||
|
|
||||||
|
@ -2,8 +2,10 @@ use std::io::prelude::*;
|
|||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use futures_util::future::BoxFuture;
|
||||||
use futures_util::io::BufReader;
|
use futures_util::io::BufReader;
|
||||||
use futures_util::io::Cursor;
|
use futures_util::io::Cursor;
|
||||||
|
use futures_util::FutureExt;
|
||||||
use ssh2::OpenFlags;
|
use ssh2::OpenFlags;
|
||||||
use ssh2::Session;
|
use ssh2::Session;
|
||||||
use ssh2::Sftp;
|
use ssh2::Sftp;
|
||||||
@ -41,3 +43,24 @@ pub async fn uplaod(window: Option<tauri::Window>, sess: Session, path: PathBuf,
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn mkdir(sess: Session, path: PathBuf) -> Result<(), String>{
|
||||||
|
let sftp = sess.sftp().or(Err("Unable to open sftp session"))?;
|
||||||
|
sftp.mkdir(path.as_path(), 0o775).or(Err(format!("Unable to create directory")))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rmdir(sess: Session, path: PathBuf) -> BoxFuture<'static, ()>{
|
||||||
|
async move {
|
||||||
|
let sftp = sess.sftp().or(Err("Unable to open sftp session")).unwrap();
|
||||||
|
let dirs = sftp.readdir(path.as_path()).or(Err("unable to stat directory")).unwrap();
|
||||||
|
for dir in dirs {
|
||||||
|
if dir.1.is_dir() {
|
||||||
|
rmdir(sess.clone(), dir.0).await;
|
||||||
|
}else {
|
||||||
|
sftp.unlink(dir.0.as_path()).or(Err(format!("Unable to delete file"))).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sftp.rmdir(path.as_path()).or(Err(format!("Unable to delete directory"))).unwrap();
|
||||||
|
}.boxed()
|
||||||
|
}
|
@ -25,7 +25,8 @@
|
|||||||
},
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"all": false,
|
"all": false,
|
||||||
"ask": true
|
"ask": true,
|
||||||
|
"open": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"windows": [
|
"windows": [
|
||||||
|
@ -31,16 +31,17 @@
|
|||||||
<button id="down" class="square-button"></button>
|
<button id="down" class="square-button"></button>
|
||||||
<button id="remove" class="square-button"></button>
|
<button id="remove" class="square-button"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="vertical" >
|
<div class="vertical" id="update">
|
||||||
<input placeholder="Version" id="pack_version" />
|
<input placeholder="Version" id="pack_version" />
|
||||||
<input placeholder="File" id="file_path" />
|
<input placeholder="File" id="file_path" />
|
||||||
<button id="browse">Browse</button>
|
<button id="browse">Browse</button>
|
||||||
<button id="Update">Update Pack</button>
|
<button id="update_pack">Update Pack</button>
|
||||||
|
</div>
|
||||||
|
<div class="vertical" id="create">
|
||||||
|
<input placeholder="Name" id="pack_name" />
|
||||||
|
<input placeholder="ID" id="pack_id" />
|
||||||
|
<button id="add">Create Pack</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="horizontal-input">
|
|
||||||
<input id="pack_name" placeholder="name" />
|
|
||||||
<button id="add" class="square-button"></button>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
const { invoke } = window.__TAURI__.tauri;
|
const { invoke } = window.__TAURI__.tauri;
|
||||||
const { listen } = window.__TAURI__.event;
|
const { listen } = window.__TAURI__.event;
|
||||||
const { ask } = window.__TAURI__.dialog;
|
const { ask, open } = window.__TAURI__.dialog;
|
||||||
const downBar = document.querySelector(".progressFinished");
|
const downBar = document.querySelector(".progressFinished");
|
||||||
//import { listen } from '@tauri-apps/api';
|
//import { listen } from '@tauri-apps/api';
|
||||||
|
|
||||||
var selected_pack = "";
|
var selected_pack = "";
|
||||||
|
var update_menu = document.getElementById("update");
|
||||||
|
var create_menu = document.getElementById("create");
|
||||||
|
|
||||||
const download_progress = listen("download_progress", (progress) => {
|
const download_progress = listen("download_progress", (progress) => {
|
||||||
console.log("Downloading");
|
console.log("Downloading");
|
||||||
@ -28,8 +30,12 @@ const download_finished = listen("download_finished", (event) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
document.getElementById("browse").addEventListener("click", browse);
|
||||||
|
document.getElementById("update_pack").addEventListener("click", update_pack);
|
||||||
document.getElementById("up").addEventListener("click", up);
|
document.getElementById("up").addEventListener("click", up);
|
||||||
document.getElementById("down").addEventListener("click", down);
|
document.getElementById("down").addEventListener("click", down);
|
||||||
|
document.getElementById("add").addEventListener("click", add);
|
||||||
|
document.getElementById("remove").addEventListener("click", remove);
|
||||||
document.getElementById("back").addEventListener("click", back);
|
document.getElementById("back").addEventListener("click", back);
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -52,6 +58,8 @@ function back(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function refresh(){
|
function refresh(){
|
||||||
|
update_menu.style.display = "none";
|
||||||
|
create_menu.style.display = "none";
|
||||||
invoke("get_modpacks").then(addModpacks);
|
invoke("get_modpacks").then(addModpacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,15 +75,70 @@ function addModpacks(modpacks) {
|
|||||||
div.id = modpacks[i].id;
|
div.id = modpacks[i].id;
|
||||||
if(modpacks[i].id == selected_pack){
|
if(modpacks[i].id == selected_pack){
|
||||||
div.classList.add("modpack-selected");
|
div.classList.add("modpack-selected");
|
||||||
|
update_menu.style.display = "flex";
|
||||||
|
invoke("get_latest_version", {id: selected_pack}).then(update_version);
|
||||||
}
|
}
|
||||||
div.addEventListener("click", function() { modpackClick(modpacks[i].id) });
|
div.addEventListener("click", function() { modpackClick(modpacks[i].id) });
|
||||||
modpacks_list.appendChild(div);
|
modpacks_list.appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.textContent = "<Create New Pack>";
|
||||||
|
div.className = "modpack";
|
||||||
|
div.id = "*new*";
|
||||||
|
div.addEventListener("click", function() { modpackClick("*new*") });
|
||||||
|
modpacks_list.appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
function modpackClick(id){
|
function modpackClick(id){
|
||||||
var old = selected_pack;
|
var old = selected_pack;
|
||||||
document.getElementById(id).classList.add("modpack-selected");
|
document.getElementById(id).classList.add("modpack-selected");
|
||||||
selected_pack = id;
|
selected_pack = id;
|
||||||
|
if (old == id){
|
||||||
|
selected_pack = "";
|
||||||
|
update_menu.style.display = "none";
|
||||||
|
create_menu.style.display = "none";
|
||||||
|
}else if (id == "*new*"){
|
||||||
|
update_menu.style.display = "none";
|
||||||
|
create_menu.style.display = "flex";
|
||||||
|
}else{
|
||||||
|
update_menu.style.display = "flex";
|
||||||
|
create_menu.style.display = "none";
|
||||||
|
invoke("get_latest_version", {id: selected_pack}).then(update_version);
|
||||||
|
}
|
||||||
document.getElementById(old).classList.remove("modpack-selected");
|
document.getElementById(old).classList.remove("modpack-selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function add(){
|
||||||
|
var id = document.getElementById("pack_id").value;
|
||||||
|
var name = document.getElementById("pack_name").value;
|
||||||
|
selected_pack = id;
|
||||||
|
invoke("add_pack", {id: id, name: name}).then(refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(){
|
||||||
|
invoke("remove_pack", {id: selected_pack}).then(refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function browse(){
|
||||||
|
const selected = await open ({
|
||||||
|
multiple: false,
|
||||||
|
filters: [{
|
||||||
|
name: 'Modrinth Modpack',
|
||||||
|
extensions: ['mrpack']
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
if (selected != null){
|
||||||
|
document.getElementById("file_path").value = selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_version(version){
|
||||||
|
document.getElementById("pack_version").value = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_pack(){
|
||||||
|
var version = document.getElementById("pack_version").value;
|
||||||
|
var path = document.getElementById("file_path").value;
|
||||||
|
invoke("update_pack", {id: selected_pack, path: path, version: version}).then(refresh);
|
||||||
|
}
|
@ -359,10 +359,12 @@ button {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#add{
|
#create{
|
||||||
background-image: url('assets/add.png');
|
display: none;
|
||||||
background-size:cover;
|
}
|
||||||
background-repeat: no-repeat;
|
|
||||||
|
#update{
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#remove{
|
#remove{
|
||||||
@ -370,7 +372,3 @@ button {
|
|||||||
background-size:cover;
|
background-size:cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pack_name{
|
|
||||||
width: 13em;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user