Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 17d3440

Browse files
committed
feat: file-explorer working example with v0.5
1 parent 0910da5 commit 17d3440

File tree

8 files changed

+141
-113
lines changed

8 files changed

+141
-113
lines changed

file-explorer/.gitignore

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1-
/target
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
/dist/
5+
/static/
6+
/.dioxus/
7+
8+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
9+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
10+
Cargo.lock
11+
12+
# These are backup files generated by rustfmt
13+
**/*.rs.bk

file-explorer/Cargo.toml

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
11
[package]
22
name = "file-explorer"
3-
version = "0.1.1"
4-
edition = "2018"
5-
description = "File Explorer with Dioxus"
3+
edition = "2021"
64

75
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
86

97
[dependencies]
10-
dioxus = { version = "0.4.0" }
11-
dioxus-desktop = { version = "0.4.0" }
12-
log = "0.4.14"
13-
open = "5.0.0"
14-
simple_logger = "4.2.0"
158

9+
dioxus = { version = "0.5", features = ["desktop"] }
10+
11+
# Debug
12+
log = "0.4.19"
13+
dioxus-logger = "0.4.1"
14+
open = "5.1.2"
1615

1716
[package.metadata.bundle]
1817
name = "Dioxus File Explorerer"
1918
identifier = "com.doe.exampleapplication"
2019
icon = ["32x32.png", "128x128.png", "[email protected]"]
21-
version = "1.0.0"
20+
version = "1.1.0"
21+
authors = ["tkr-sh <[email protected]>", "Jonathan Kelley <[email protected]>"]
2222
resources = ["assets", "images/**/*.png", "secrets/public_key.txt"]
2323
copyright = "Copyright (c) Jane Doe 2016. All rights reserved."
2424
category = "Developer Tool"
2525
short_description = "An example application."
26-
long_description = """
27-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
28-
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
29-
enim ad minim veniam, quis nostrud exercitation ullamco laboris
30-
nisi ut aliquip ex ea commodo consequat.
31-
"""
32-
osx_frameworks = []

file-explorer/Dioxus.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[application]
2+
3+
# App (Project) Name
4+
name = "file-explorer"
5+
6+
# Dioxus App Default Platform
7+
# desktop, web
8+
default_platform = "desktop"
9+
10+
# `build` & `serve` dist path
11+
out_dir = "dist"
12+
13+
# assets file folder
14+
asset_dir = "assets"
15+
16+
[web.app]
17+
18+
# HTML title tag content
19+
title = "file-explorer"
20+
21+
[web.watcher]
22+
23+
# when watcher trigger, regenerate the `index.html`
24+
reload_html = true
25+
26+
# which files or dirs will be watcher monitoring
27+
watch_path = ["src", "assets"]
28+
29+
# include `assets` in web platform
30+
[web.resource]
31+
32+
# CSS style file
33+
34+
style = []
35+
36+
# Javascript code file
37+
script = []
38+
39+
[web.resource.dev]
40+
41+
# Javascript code file
42+
# serve: [dev-server] only
43+
script = []

file-explorer/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
This example shows how a Dioxus App can directly leverage system calls and libraries to bridge native functionality with the WebView renderer.
44

5-
![example](./image.png)
5+
![example](./src/image.png)
66

77

88
## To run this example:
99

1010
```
11-
cargo run
11+
dx serve
1212
```
13+

file-explorer/assets/image.png

44.1 KB
Loading

file-explorer/src/style.css renamed to file-explorer/assets/main.css

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,6 @@ body {
1010
padding-top: 77px;
1111
}
1212

13-
/* header {
14-
position: fixed;
15-
top: 0;
16-
left: 0;
17-
right: 0;
18-
z-index: 10;
19-
padding: 20px;
20-
background-color: #2196F3;
21-
color: white;
22-
}
23-
header h1 {
24-
float: left;
25-
font-size: 20px;
26-
font-weight: 400;
27-
}
28-
header .material-icons {
29-
float: right;
30-
cursor: pointer;
31-
}
32-
header .icon-menu {
33-
float: left;
34-
margin-right: 20px;
35-
} */
3613

3714
main {
3815
padding: 20px 50px;

file-explorer/image.png

-46.4 KB
Binary file not shown.

file-explorer/src/main.rs

Lines changed: 73 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,76 @@
11
#![allow(non_snake_case)]
2-
//! Example: File Explorer
3-
//! -------------------------
4-
//!
5-
//! This is a fun little desktop application that lets you explore the file system.
6-
//!
7-
//! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do.
82

93
use dioxus::prelude::*;
10-
use dioxus_desktop::{Config, WindowBuilder};
11-
4+
use log::LevelFilter;
125

136
fn main() {
14-
// simple_logger::init_with_level(log::Level::Debug).unwrap();
15-
dioxus_desktop::launch_cfg(
16-
App,
17-
Config::default().with_window(WindowBuilder::new().with_resizable(true).with_inner_size(
18-
dioxus_desktop::wry::application::dpi::LogicalSize::new(400.0, 800.0),
19-
)),
20-
);
7+
// Init debug
8+
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
9+
10+
dioxus::launch(App);
2111
}
2212

23-
fn App(cx: Scope) -> Element {
24-
let files = use_ref(cx, Files::new);
25-
26-
render!(div {
27-
link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet" }
28-
style { include_str!("./style.css") }
29-
header {
30-
i { class: "material-icons icon-menu", "menu" }
31-
h1 { "Files: " "{files.read().current()}" }
32-
span { }
33-
i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
34-
}
35-
main {
36-
files.read().path_names.iter().enumerate().map(|(dir_id, path)| {
37-
let path_end = path.split('/').last().unwrap_or(path.as_str());
38-
let icon_type = if path_end.contains('.') {
39-
"description"
40-
} else {
41-
"folder"
42-
};
43-
rsx! (
44-
div { class: "folder", key: "{path}",
13+
#[component]
14+
fn App() -> Element {
15+
// Build cool things ✌️
16+
let mut files = use_signal(|| Files::new());
17+
18+
rsx! {
19+
div {
20+
link { href: "https://fonts.googleapis.com/icon?family=Material+Icons", rel: "stylesheet" }
21+
link { rel: "stylesheet", href: "main.css" }
22+
header {
23+
i { class: "material-icons icon-menu", "menu" }
24+
h1 { "Files: " "{files.read().current()}" }
25+
span { }
26+
i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
27+
}
28+
main {
29+
for (dir_id, path) in files.read().path_names.iter().enumerate() {
30+
div {
31+
class: "folder", key: "{path.name}",
4532
i { class: "material-icons",
4633
onclick: move |_| files.write().enter_dir(dir_id),
47-
"{icon_type}"
34+
// Change the icon
35+
if path.is_directory { "folder" } else { "description" }
36+
// The tooltip
4837
p { class: "cooltip", "0 folders / 0 files" }
4938
}
50-
h1 { "{path_end}" }
51-
}
52-
)
53-
})
54-
files.read().err.as_ref().map(|err| {
55-
rsx! (
56-
div {
57-
code { "{err}" }
58-
button { onclick: move |_| files.write().clear_err(), "x" }
39+
h1 { "{path.name}" }
5940
}
60-
)
61-
})
41+
}
42+
{
43+
files.read().err.as_ref().map(|err| {
44+
rsx! (
45+
div {
46+
code { "{err}" }
47+
button { onclick: move |_| files.write().clear_err(), "x" }
48+
}
49+
)
50+
})
51+
}
52+
}
6253
}
54+
}
55+
}
6356

64-
})
57+
58+
#[derive(Debug)]
59+
struct File {
60+
is_directory: bool,
61+
name: String,
6562
}
6663

6764
struct Files {
6865
path_stack: Vec<String>,
69-
path_names: Vec<String>,
66+
path_names: Vec<File>,
7067
err: Option<String>,
7168
}
7269

7370
impl Files {
7471
fn new() -> Self {
7572
let mut files = Self {
76-
path_stack: vec!["./".to_string()],
73+
path_stack: vec![".".to_string()],
7774
path_names: vec![],
7875
err: None,
7976
};
@@ -84,26 +81,23 @@ impl Files {
8481
}
8582

8683
fn reload_path_list(&mut self) {
87-
let cur_path = self.path_stack.last().unwrap();
84+
let cur_path = self.path_stack.join("/");
8885
log::info!("Reloading path list for {:?}", cur_path);
89-
let paths = match std::fs::read_dir(cur_path) {
86+
let paths = match std::fs::read_dir(&cur_path) {
9087
Ok(e) => e,
91-
Err(err) => { //Likely we're trying to open a file, so let's open it!
92-
match open::that(cur_path){
93-
Ok(_) => {
94-
log::info!("Opened file");
95-
return;
96-
},
97-
Err(err) => {
98-
let err = format!("An error occurred: {:?}", err);
99-
self.err = Some(err);
100-
self.path_stack.pop();
101-
return;
102-
}
88+
Err(err) => { // Likely we're trying to open a file, so let's open it!
89+
if let Ok(_) = open::that(cur_path) {
90+
log::info!("Opened file");
91+
return;
92+
} else {
93+
let err = format!("An error occurred: {:?}", err);
94+
self.err = Some(err);
95+
self.path_stack.pop();
96+
return;
10397
}
104-
10598
}
10699
};
100+
107101
let collected = paths.collect::<Vec<_>>();
108102
log::info!("Path list reloaded {:#?}", collected);
109103

@@ -112,8 +106,14 @@ impl Files {
112106
self.path_names.clear();
113107

114108
for path in collected {
109+
let file = path.unwrap();
115110
self.path_names
116-
.push(path.unwrap().path().display().to_string());
111+
.push(
112+
File {
113+
name: file.file_name().to_str().unwrap().to_string(),
114+
is_directory: file.file_type().unwrap().is_dir(),
115+
}
116+
);
117117
}
118118
log::info!("path names are {:#?}", self.path_names);
119119
}
@@ -127,13 +127,15 @@ impl Files {
127127

128128
fn enter_dir(&mut self, dir_id: usize) {
129129
let path = &self.path_names[dir_id];
130-
self.path_stack.push(path.clone());
130+
self.path_stack.push(path.name.to_string());
131+
println!("{:#?}", self.path_stack);
131132
self.reload_path_list();
132133
}
133134

134-
fn current(&self) -> &str {
135-
self.path_stack.last().unwrap()
135+
fn current(&self) -> String {
136+
self.path_stack.join("/")
136137
}
138+
137139
fn clear_err(&mut self) {
138140
self.err = None;
139141
}

0 commit comments

Comments
 (0)