Skip to content

Commit 333c155

Browse files
committed
feat: some styling and command execution
1 parent 12ab085 commit 333c155

File tree

8 files changed

+208
-18
lines changed

8 files changed

+208
-18
lines changed

src-tauri/src/main.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ fn logger(message: String, js_function: String) {
2222
}
2323
}
2424
}
25+
2526
#[allow(non_snake_case)]
2627
#[tauri::command]
27-
fn executeEcho(){
28-
match run_command_with_logging("echo", &["hello"], logger) {
28+
fn executeCommand(command: String, args: Vec<String>) {
29+
// convert from Vec<String> to Vec<&str> (required by run_command_with_logging)
30+
let parsed_args: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
31+
match run_command_with_logging(command.as_str(), parsed_args.as_slice(), logger) {
2932
Ok(_) => println!("Command executed successfully"),
3033
Err(e) => println!("Failed to execute command: {}", e),
3134
}
@@ -36,25 +39,36 @@ fn main() {
3639
// creating a menu for the system tray, with a quit option (add more options later if needed)
3740
let quit = CustomMenuItem::new("quit".to_string(), "Quit").accelerator("Cmd+Q");
3841

42+
// creating the system tray menu with the quit option
3943
let system_tray_menu = SystemTrayMenu::new().add_item(quit);
44+
45+
// title of the system tray
46+
let tray_title = "Hello Node";
47+
48+
// creating the tauri application
4049
tauri::Builder::default()
4150
.setup(|app| {
51+
//saving the main window in a mutex to use it later globally
4252
let main_window = app.get_window("main").unwrap();
4353
*MAIN_WINDOW.lock().unwrap() = Some(main_window);
4454
Ok(())
4555
})
56+
// setting the system tray menu plugin
4657
.plugin(tauri_plugin_autostart::init(
4758
MacosLauncher::LaunchAgent,
4859
Some(vec![]),
4960
))
61+
// hide to tray when the main window is closed
5062
.on_window_event(|event| match event.event() {
5163
tauri::WindowEvent::CloseRequested { api, .. } => {
5264
event.window().hide().unwrap();
5365
api.prevent_close();
5466
}
5567
_ => {}
5668
})
57-
.system_tray(SystemTray::new().with_menu(system_tray_menu))
69+
// setting the system tray
70+
.system_tray(SystemTray::new().with_tooltip(tray_title).with_menu(system_tray_menu))
71+
// opening the main window when the system tray is clicked
5872
.on_system_tray_event(|app, event| match event {
5973
SystemTrayEvent::LeftClick {
6074
position: _,
@@ -70,6 +84,7 @@ fn main() {
7084
window.set_focus().unwrap();
7185
}
7286
}
87+
// handling the quit option
7388
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
7489
"quit" => {
7590
std::process::exit(0);
@@ -78,7 +93,8 @@ fn main() {
7893
},
7994
_ => {}
8095
})
81-
.invoke_handler(tauri::generate_handler![executeEcho])
96+
// tauri commands (to use in the frontend)
97+
.invoke_handler(tauri::generate_handler![executeCommand])
8298
.run(tauri::generate_context!())
8399
.expect("error while running tauri application");
84100
}

src-tauri/src/system_utils/executor.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ pub fn run_command_with_logging(
1111
args: &[&str],
1212
logger: Logger,
1313
) -> std::io::Result<()> {
14-
println!("executing {} {}", command, args.join(" "));
14+
let alert = format!("executing {} {}", command, args.join(" "));
15+
16+
println!("{}", alert);
17+
logger(alert.to_string(), "FunctionOutputLogger".to_string());
1518

1619
let shell = if cfg!(windows) { "cmd" } else { "sh" };
1720

@@ -54,7 +57,6 @@ pub fn run_command_with_logging(
5457
});
5558

5659
for line in rx {
57-
println!("{}", line);
5860
logger(line, "FunctionOutputLogger".to_string());
5961
}
6062

src/App.css

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,37 @@
1313
-moz-osx-font-smoothing: grayscale;
1414
-webkit-text-size-adjust: 100%;
1515
}
16+
17+
18+
.container {
19+
display: flex;
20+
flex-direction: column;
21+
align-items: center;
22+
overflow: hidden;
23+
width: 100vw;
24+
height: 100vh;
25+
}
26+
27+
#logs{
28+
background-color: transparent;
29+
color: white;
30+
border: none;
31+
width: 80vw;
32+
overflow-y: auto;
33+
resize: none;
34+
height: 200px;
35+
36+
&::-webkit-scrollbar {
37+
background: transparent;
38+
width: 10px;
39+
}
40+
&::-webkit-scrollbar-track {
41+
box-shadow: inset 0 0 5px #1e284b79;
42+
border-radius: 10px;
43+
}
44+
&::-webkit-scrollbar-thumb {
45+
background: #3a4b8a;
46+
border-radius: 10px;
47+
}
48+
49+
}

src/App.tsx

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,92 @@
11
import { useEffect, useState } from "react";
2-
import { invoke } from "@tauri-apps/api/tauri";
32
import { enable, isEnabled, disable } from "tauri-plugin-autostart-api";
43
import "./App.css";
4+
import "./assets/styles/wave.css";
5+
import "./assets/styles/card.css";
6+
import { ExecuteCommand } from "./utils/CommandUtils";
57

68
function App() {
7-
const [enabled, setEnabled] = useState(false);
9+
const [enabledAutostart, setEnabledAutostart] = useState(false);
10+
const [logs, setLogs] = useState("");
11+
const executableurl =
12+
"https://github.com/Hello-Storage/hello-ipfs-user-node/releases/download/0.0.1/ipfs-user-node-windows-0.0.1.exe";
813

914
async function greet() {
10-
await invoke("executeEcho");
15+
await ExecuteCommand("echo", ["Hello there from hello.app!"]);
1116
}
1217

1318
useEffect(() => {
19+
window.FunctionOutputLogger = function (msg: string) {
20+
// update logs
21+
setLogs(logs + msg + "\n");
22+
// scroll to bottom
23+
const textarea = document.getElementById("logs");
24+
if (textarea) {
25+
textarea.scrollTop = textarea.scrollHeight + 100;
26+
}
27+
};
28+
}, [logs]);
29+
30+
useEffect(() => {
31+
greet();
32+
33+
// check if hello node is installed (from localstorage)
34+
let helloNodeInstalled = localStorage.getItem("hello-node-installed");
35+
if (!helloNodeInstalled) {
36+
// install hello node
37+
ExecuteCommand("curl", ["-O", "-L", executableurl]).then(() => {
38+
// update localstorage
39+
localStorage.setItem("hello-node-installed", "true");
40+
});
41+
setLogs(logs + "Hello Node installed\n");
42+
} else {
43+
setLogs(logs + "Hello Node already installed\n");
44+
}
45+
46+
// detect if autostart is enabled
1447
isEnabled().then((e) => {
1548
if (e) {
16-
setEnabled(true);
49+
setEnabledAutostart(true);
1750
}
1851
});
52+
//
1953
}, []);
2054

2155
async function switchAutostart() {
2256
if (await isEnabled()) {
2357
await disable();
24-
setEnabled(false);
58+
setEnabledAutostart(false);
2559
alert("Autostart disabled");
2660
} else {
2761
await enable();
28-
setEnabled(true);
62+
setEnabledAutostart(true);
2963
alert("Autostart enabled");
3064
}
3165
}
3266

33-
window.FunctionOutputLogger = function (msg: string) {
34-
console.log(msg);
35-
};
36-
3767
return (
3868
<div className="container">
69+
<section className="wave-background">
70+
<div className="air air1"></div>
71+
<div className="air air2"></div>
72+
<div className="air air3"></div>
73+
<div className="air air4"></div>
74+
</section>
75+
76+
<div className="bgblue">
77+
<div className="card">
78+
<textarea
79+
name="logs"
80+
id="logs"
81+
value={logs}
82+
disabled
83+
></textarea>
84+
</div>
85+
</div>
86+
3987
<button onClick={switchAutostart}>
40-
{enabled ? "Disable autostart" : "Enable autostart"}
88+
{enabledAutostart ? "Disable autostart" : "Enable autostart"}
4189
</button>
42-
<button onClick={greet}>test</button>
4390
</div>
4491
);
4592
}

src/assets/img/wave.png

3.9 KB
Loading

src/assets/styles/card.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.bgblue {
2+
background: linear-gradient(135deg, #fffffff5, #1e284b79, #ffffff98);
3+
padding: 1px;
4+
border-radius: 1.2rem;
5+
box-shadow: 0px 1rem 1.5rem -0.9rem #000000e1;
6+
}
7+
8+
.card {
9+
font-size: 1rem;
10+
color: #bec4cf;
11+
background: linear-gradient(135deg, #3586ffc0 0%, #1e284b79 50%, #3586ffc0 100%);
12+
padding: 1.5rem;
13+
border-radius: 1.2rem;
14+
}

src/assets/styles/wave.css

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.wave-background {
2+
position: relative;
3+
width: 100%;
4+
height: 30vh;
5+
background: linear-gradient(135deg, #3586ffc0 0%, #1e284b79 50%, #3586ffc0 100%);
6+
overflow: hidden;
7+
}
8+
9+
.wave-background .air {
10+
position: absolute;
11+
bottom: 0;
12+
left: 0;
13+
width: 100%;
14+
height: 100px;
15+
background: url(../img/wave.png);
16+
background-size: 1000px 100px
17+
}
18+
19+
.wave-background .air.air1 {
20+
animation: wave 30s linear infinite;
21+
z-index: 1000;
22+
opacity: 1;
23+
animation-delay: 0s;
24+
bottom: 0;
25+
}
26+
27+
.wave-background .air.air2 {
28+
animation: wave2 15s linear infinite;
29+
z-index: 999;
30+
opacity: 0.5;
31+
animation-delay: -5s;
32+
bottom: 10px;
33+
}
34+
35+
.wave-background .air.air3 {
36+
animation: wave 30s linear infinite;
37+
z-index: 998;
38+
opacity: 0.2;
39+
animation-delay: -2s;
40+
bottom: 15px;
41+
}
42+
43+
.wave-background .air.air4 {
44+
animation: wave2 5s linear infinite;
45+
z-index: 997;
46+
opacity: 0.7;
47+
animation-delay: -5s;
48+
bottom: 20px;
49+
}
50+
51+
@keyframes wave {
52+
0% {
53+
background-position-x: 0px;
54+
}
55+
56+
100% {
57+
background-position-x: 1000px;
58+
}
59+
}
60+
61+
@keyframes wave2 {
62+
0% {
63+
background-position-x: 0px;
64+
}
65+
66+
100% {
67+
background-position-x: -1000px;
68+
}
69+
}

src/utils/CommandUtils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { invoke } from "@tauri-apps/api/tauri";
2+
3+
export async function ExecuteCommand(command: string, args: string[]) {
4+
await invoke("executeCommand", {
5+
command: command,
6+
args: args
7+
});
8+
}

0 commit comments

Comments
 (0)