chore: init project
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
16
index.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
|
||||||
|
/>
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
30
package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "clash-verge",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tauri dev",
|
||||||
|
"build": "tauri build",
|
||||||
|
"web:dev": "vite",
|
||||||
|
"web:build": "tsc && vite build",
|
||||||
|
"web:serve": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.7.0",
|
||||||
|
"@emotion/styled": "^11.6.0",
|
||||||
|
"@material-ui/core": "^5.0.0-beta.5",
|
||||||
|
"@tauri-apps/api": "^1.0.0-beta.8",
|
||||||
|
"axios": "^0.24.0",
|
||||||
|
"react": "^17.0.0",
|
||||||
|
"react-dom": "^17.0.0",
|
||||||
|
"react-router-dom": "^6.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tauri-apps/cli": "^1.0.0-beta.10",
|
||||||
|
"@types/react": "^17.0.0",
|
||||||
|
"@types/react-dom": "^17.0.0",
|
||||||
|
"@vitejs/plugin-react": "^1.0.0",
|
||||||
|
"sass": "^1.44.0",
|
||||||
|
"typescript": "^4.5.2",
|
||||||
|
"vite": "^2.6.14"
|
||||||
|
}
|
||||||
|
}
|
4
src-tauri/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
WixTools
|
4066
src-tauri/Cargo.lock
generated
Normal file
29
src-tauri/Cargo.toml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[package]
|
||||||
|
name = "app"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "clash verge"
|
||||||
|
authors = ["zzzgydi"]
|
||||||
|
license = "MIT"
|
||||||
|
repository = ""
|
||||||
|
default-run = "app"
|
||||||
|
edition = "2021"
|
||||||
|
build = "src/build.rs"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { version = "1.0.0-beta.4" }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dirs = "4.0.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde_yaml = "0.8"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
tauri = { version = "1.0.0-beta.8", features = ["api-all", "system-tray"] }
|
||||||
|
winreg = { version = "0.10", features = ["transactions"] }
|
||||||
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "custom-protocol" ]
|
||||||
|
custom-protocol = [ "tauri/custom-protocol" ]
|
BIN
src-tauri/bin/clash-x86_64-pc-windows-msvc.exe
Normal file
BIN
src-tauri/icons/128x128.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
src-tauri/icons/128x128@2x.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
src-tauri/icons/32x32.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
src-tauri/icons/Square107x107Logo.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
src-tauri/icons/Square142x142Logo.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
src-tauri/icons/Square150x150Logo.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
src-tauri/icons/Square284x284Logo.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
src-tauri/icons/Square30x30Logo.png
Normal file
After Width: | Height: | Size: 903 B |
BIN
src-tauri/icons/Square310x310Logo.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
src-tauri/icons/Square44x44Logo.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src-tauri/icons/Square71x71Logo.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
src-tauri/icons/Square89x89Logo.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src-tauri/icons/StoreLogo.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src-tauri/icons/icon.icns
Normal file
BIN
src-tauri/icons/icon.ico
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
src-tauri/icons/icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
14
src-tauri/rustfmt.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
max_width = 100
|
||||||
|
hard_tabs = false
|
||||||
|
tab_spaces = 2
|
||||||
|
newline_style = "Auto"
|
||||||
|
use_small_heuristics = "Default"
|
||||||
|
reorder_imports = true
|
||||||
|
reorder_modules = true
|
||||||
|
remove_nested_parens = true
|
||||||
|
edition = "2018"
|
||||||
|
merge_derives = true
|
||||||
|
use_try_shorthand = false
|
||||||
|
use_field_init_shorthand = false
|
||||||
|
force_explicit_abi = true
|
||||||
|
imports_granularity = "Crate"
|
3
src-tauri/src/build.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
69
src-tauri/src/clash.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
extern crate reqwest;
|
||||||
|
extern crate serde_yaml;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use tauri::api::path::home_dir;
|
||||||
|
use tauri::api::process::{Command, CommandEvent};
|
||||||
|
|
||||||
|
/// Get the clash config dir
|
||||||
|
pub fn get_config_dir() -> PathBuf {
|
||||||
|
home_dir()
|
||||||
|
.unwrap()
|
||||||
|
.join(Path::new(".config"))
|
||||||
|
.join(Path::new("clash-verge"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize the default config dir for clash
|
||||||
|
pub fn init_clash_config() {
|
||||||
|
let config_dir = get_config_dir();
|
||||||
|
let conifg_yaml = config_dir.join("config.yaml");
|
||||||
|
|
||||||
|
let default_yaml =
|
||||||
|
"mixed-port: 7890\nallow-lan: false\nexternal-controller: 127.0.0.1:9090\nsecret: ''\n";
|
||||||
|
let mut yaml_obj = serde_yaml::from_str::<serde_yaml::Value>(&default_yaml).unwrap();
|
||||||
|
|
||||||
|
if !config_dir.exists() {
|
||||||
|
let config_dir = config_dir.clone();
|
||||||
|
fs::create_dir(config_dir).unwrap();
|
||||||
|
let mut file = fs::File::create(conifg_yaml).unwrap();
|
||||||
|
file.write(default_yaml.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let yaml_path = &config_dir.join("config.yaml");
|
||||||
|
let yaml_str = fs::read_to_string(yaml_path).unwrap();
|
||||||
|
yaml_obj = serde_yaml::from_str::<serde_yaml::Value>(&yaml_str).unwrap();
|
||||||
|
|
||||||
|
println!("{:?}", yaml_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the clash bin
|
||||||
|
pub fn run_clash_bin(config_dirs: &str) {
|
||||||
|
let (mut rx, mut _child) = Command::new_sidecar("clash")
|
||||||
|
.expect("failed to create clash binary")
|
||||||
|
.args(["-d", config_dirs])
|
||||||
|
.spawn()
|
||||||
|
.expect("failed to spawn sidecar");
|
||||||
|
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
// read events such as stdout
|
||||||
|
while let Some(event) = rx.recv().await {
|
||||||
|
if let CommandEvent::Stdout(line) = event {
|
||||||
|
println!("{:?}", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_url(profile_url: &str) -> Result<(), reqwest::Error> {
|
||||||
|
let resp = reqwest::get(profile_url).await?;
|
||||||
|
println!("{:#?}", resp);
|
||||||
|
|
||||||
|
let header = resp.headers().clone();
|
||||||
|
println!("{:?}", header);
|
||||||
|
|
||||||
|
let data = resp.text_with_charset("utf-8").await?;
|
||||||
|
println!("{:#?}", data);
|
||||||
|
Ok(())
|
||||||
|
}
|
4
src-tauri/src/cmd.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
use tauri::api::process::CommandChild;
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn set_clash_port(process: Option<CommandChild>, port: i32) {}
|
62
src-tauri/src/main.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#![cfg_attr(
|
||||||
|
all(not(debug_assertions), target_os = "windows"),
|
||||||
|
windows_subsystem = "windows"
|
||||||
|
)]
|
||||||
|
|
||||||
|
extern crate tauri;
|
||||||
|
|
||||||
|
mod clash;
|
||||||
|
mod sysopt;
|
||||||
|
|
||||||
|
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu};
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn get_config_data(url: String) -> Result<String, String> {
|
||||||
|
match clash::fetch_url(&url).await {
|
||||||
|
Ok(_) => Ok(String::from("success")),
|
||||||
|
Err(_) => Err(String::from("error")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let config = sysopt::get_proxy_config()?;
|
||||||
|
println!("{:?}", config);
|
||||||
|
|
||||||
|
let app = tauri::Builder::default()
|
||||||
|
.system_tray(
|
||||||
|
SystemTray::new()
|
||||||
|
.with_menu(SystemTrayMenu::new().add_item(CustomMenuItem::new("tray_event_quit", "Quit"))),
|
||||||
|
)
|
||||||
|
.on_system_tray_event(move |app, event| match event {
|
||||||
|
SystemTrayEvent::LeftClick { .. } => {
|
||||||
|
let window = app.get_window("main").unwrap();
|
||||||
|
window.show().unwrap();
|
||||||
|
window.set_focus().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
||||||
|
"tray_event_quit" => {
|
||||||
|
app.exit(0);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
})
|
||||||
|
.invoke_handler(tauri::generate_handler![get_config_data])
|
||||||
|
.build(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application");
|
||||||
|
|
||||||
|
app.run(|app_handle, e| match e {
|
||||||
|
tauri::Event::CloseRequested { label, api, .. } => {
|
||||||
|
let app_handle = app_handle.clone();
|
||||||
|
api.prevent_close();
|
||||||
|
app_handle.get_window(&label).unwrap().hide().unwrap();
|
||||||
|
}
|
||||||
|
tauri::Event::ExitRequested { api, .. } => {
|
||||||
|
api.prevent_exit();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
43
src-tauri/src/sysopt.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::io;
|
||||||
|
use winreg::enums::*;
|
||||||
|
use winreg::RegKey;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct ProxyConfig {
|
||||||
|
enable: u32,
|
||||||
|
server: String,
|
||||||
|
bypass: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
/// Get the windows system proxy config
|
||||||
|
pub fn get_proxy_config() -> io::Result<ProxyConfig> {
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
let cur_var = hkcu.open_subkey_with_flags(
|
||||||
|
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
||||||
|
KEY_READ,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(ProxyConfig {
|
||||||
|
enable: cur_var.get_value("ProxyEnable")?,
|
||||||
|
server: cur_var.get_value("ProxyServer")?,
|
||||||
|
bypass: cur_var.get_value("ProxyOverride")?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
/// Set the windows system proxy config
|
||||||
|
pub fn set_proxy_config(config: &ProxyConfig) -> io::Result<()> {
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
let cur_var = hkcu.open_subkey_with_flags(
|
||||||
|
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
|
||||||
|
KEY_SET_VALUE,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
cur_var.set_value("ProxyEnable", &config.enable)?;
|
||||||
|
cur_var.set_value("ProxyServer", &config.server)?;
|
||||||
|
cur_var.set_value("ProxyOverride", &config.bypass)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
71
src-tauri/tauri.conf.json
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"package": {
|
||||||
|
"productName": "clash-verge",
|
||||||
|
"version": "0.1.0"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"distDir": "../dist",
|
||||||
|
"devPath": "http://localhost:3000",
|
||||||
|
"beforeDevCommand": "npm run web:dev",
|
||||||
|
"beforeBuildCommand": "npm run web:build"
|
||||||
|
},
|
||||||
|
"tauri": {
|
||||||
|
"systemTray": {
|
||||||
|
"iconPath": "icons/icon.png",
|
||||||
|
"iconAsTemplate": true
|
||||||
|
},
|
||||||
|
"bundle": {
|
||||||
|
"active": true,
|
||||||
|
"targets": "all",
|
||||||
|
"identifier": "com.tauri.dev",
|
||||||
|
"icon": [
|
||||||
|
"icons/32x32.png",
|
||||||
|
"icons/128x128.png",
|
||||||
|
"icons/128x128@2x.png",
|
||||||
|
"icons/icon.icns",
|
||||||
|
"icons/icon.ico"
|
||||||
|
],
|
||||||
|
"resources": [],
|
||||||
|
"externalBin": ["bin/clash"],
|
||||||
|
"copyright": "",
|
||||||
|
"category": "DeveloperTool",
|
||||||
|
"shortDescription": "",
|
||||||
|
"longDescription": "",
|
||||||
|
"deb": {
|
||||||
|
"depends": [],
|
||||||
|
"useBootstrapper": false
|
||||||
|
},
|
||||||
|
"macOS": {
|
||||||
|
"frameworks": [],
|
||||||
|
"minimumSystemVersion": "",
|
||||||
|
"useBootstrapper": false,
|
||||||
|
"exceptionDomain": "",
|
||||||
|
"signingIdentity": null,
|
||||||
|
"entitlements": null
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"certificateThumbprint": null,
|
||||||
|
"digestAlgorithm": "sha256",
|
||||||
|
"timestampUrl": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"active": false
|
||||||
|
},
|
||||||
|
"allowlist": {
|
||||||
|
"all": true
|
||||||
|
},
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"title": "Clash Verge",
|
||||||
|
"width": 800,
|
||||||
|
"height": 600,
|
||||||
|
"resizable": true,
|
||||||
|
"fullscreen": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"security": {
|
||||||
|
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
src/assets/styles/index.scss
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
html {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||||
|
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
|
sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||||
|
monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&__sidebar {
|
||||||
|
height: 100vh;
|
||||||
|
flex: 1 1 25%;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
|
||||||
|
> h1 {
|
||||||
|
text-align: center;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
> h3 {
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__links {
|
||||||
|
$link-height: 60px;
|
||||||
|
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
|
||||||
|
> a {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: $link-height;
|
||||||
|
line-height: $link-height;
|
||||||
|
text-align: center;
|
||||||
|
user-select: none;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #606266;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
flex: 1 1 75%;
|
||||||
|
padding: 20px 30px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
40
src/main.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import "./assets/styles/index.scss";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import { BrowserRouter, NavLink, Route, Routes } from "react-router-dom";
|
||||||
|
import HomePage from "./pages/home";
|
||||||
|
import ProfilesPage from "./pages/profiles";
|
||||||
|
import { version } from "../package.json";
|
||||||
|
|
||||||
|
function Layout() {
|
||||||
|
return (
|
||||||
|
<div className="layout">
|
||||||
|
<div className="layout__sidebar">
|
||||||
|
<h1>Clash Verge</h1>
|
||||||
|
<h3>{version}</h3>
|
||||||
|
|
||||||
|
<div className="layout__links">
|
||||||
|
<NavLink to="/">Home</NavLink>
|
||||||
|
<NavLink to="/profiles">Profiles</NavLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="layout__content">
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<HomePage />} />
|
||||||
|
<Route path="/profiles" element={<ProfilesPage />} />
|
||||||
|
</Routes>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<BrowserRouter>
|
||||||
|
<Layout />
|
||||||
|
</BrowserRouter>
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById("root")
|
||||||
|
);
|
19
src/pages/home.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { TextField } from "@material-ui/core";
|
||||||
|
|
||||||
|
const HomePage = () => {
|
||||||
|
const [port, setPort] = useState("7890");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TextField
|
||||||
|
label="Port"
|
||||||
|
fullWidth
|
||||||
|
value={port}
|
||||||
|
onChange={(e) => setPort(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HomePage;
|
40
src/pages/profiles.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { invoke } from "@tauri-apps/api";
|
||||||
|
import { Button, Grid, TextField } from "@material-ui/core";
|
||||||
|
|
||||||
|
const ProfilesPage = () => {
|
||||||
|
const [url, setUrl] = useState("");
|
||||||
|
|
||||||
|
const onClick = async () => {
|
||||||
|
if (!url) return;
|
||||||
|
const data = await invoke("get_config_data", { url });
|
||||||
|
console.log(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
justifyContent="space-between"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Grid item xs={9}>
|
||||||
|
<TextField
|
||||||
|
label="Profile Url"
|
||||||
|
fullWidth
|
||||||
|
value={url}
|
||||||
|
onChange={(e) => setUrl(e.target.value)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Button size="large" variant="contained" onClick={onClick}>
|
||||||
|
View
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProfilesPage;
|
1
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
20
tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||||
|
"allowJs": false,
|
||||||
|
"skipLibCheck": false,
|
||||||
|
"esModuleInterop": false,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx"
|
||||||
|
},
|
||||||
|
"include": ["./src"]
|
||||||
|
}
|
7
vite.config.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
});
|