7
7
//! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do.
8
8
9
9
use dioxus:: prelude:: * ;
10
- use dioxus_desktop:: { Config , WindowBuilder } ;
11
-
10
+ use log:: LevelFilter ;
12
11
13
12
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
- ) ;
13
+ // Init debug
14
+ dioxus_logger:: init ( LevelFilter :: Info ) . expect ( "failed to init logger" ) ;
15
+
16
+ dioxus:: launch ( App ) ;
21
17
}
22
18
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}" ,
19
+ #[ component]
20
+ fn App ( ) -> Element {
21
+ // Build cool things ✌️
22
+ let mut files = use_signal ( || Files :: new ( ) ) ;
23
+
24
+ rsx ! {
25
+ div {
26
+ link { href: "https://fonts.googleapis.com/icon?family=Material+Icons" , rel: "stylesheet" }
27
+ link { rel: "stylesheet" , href: "main.css" }
28
+ header {
29
+ i { class: "material-icons icon-menu" , "menu" }
30
+ h1 { "Files: {files.read().current()}" }
31
+ span { }
32
+ i { class: "material-icons" , onclick: move |_| files. write( ) . go_up( ) , "logout" }
33
+ }
34
+ main {
35
+ for ( dir_id, path) in files. read( ) . path_names. iter( ) . enumerate( ) {
36
+ div {
37
+ class: "folder" , key: "{path.name}" ,
45
38
i { class: "material-icons" ,
46
39
onclick: move |_| files. write( ) . enter_dir( dir_id) ,
47
- "{icon_type}"
40
+ // Change the icon
41
+ if path. is_directory { "folder" } else { "description" }
42
+ // The tooltip
48
43
p { class: "cooltip" , "0 folders / 0 files" }
49
44
}
50
- h1 { "{path_end }" }
45
+ h1 { "{path.name }" }
51
46
}
52
- )
53
- } )
54
- files. read( ) . err. as_ref( ) . map( |err| {
55
- rsx! (
47
+ }
48
+ if let Some ( err) = files. read( ) . err. as_ref( ) {
56
49
div {
57
50
code { "{err}" }
58
51
button { onclick: move |_| files. write( ) . clear_err( ) , "x" }
59
52
}
60
- )
61
- } )
53
+ }
54
+ }
62
55
}
56
+ }
57
+ }
63
58
64
- } )
59
+ #[ derive( Debug ) ]
60
+ struct File {
61
+ is_directory : bool ,
62
+ name : String ,
65
63
}
66
64
67
65
struct Files {
68
66
path_stack : Vec < String > ,
69
- path_names : Vec < String > ,
67
+ path_names : Vec < File > ,
70
68
err : Option < String > ,
71
69
}
72
70
73
71
impl Files {
74
72
fn new ( ) -> Self {
75
73
let mut files = Self {
76
- path_stack : vec ! [ "./ " . to_string( ) ] ,
74
+ path_stack : vec ! [ "." . to_string( ) ] ,
77
75
path_names : vec ! [ ] ,
78
76
err : None ,
79
77
} ;
@@ -84,26 +82,24 @@ impl Files {
84
82
}
85
83
86
84
fn reload_path_list ( & mut self ) {
87
- let cur_path = self . path_stack . last ( ) . unwrap ( ) ;
85
+ let cur_path = self . path_stack . join ( "/" ) ;
88
86
log:: info!( "Reloading path list for {:?}" , cur_path) ;
89
- let paths = match std:: fs:: read_dir ( cur_path) {
87
+ let paths = match std:: fs:: read_dir ( & cur_path) {
90
88
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
- }
89
+ Err ( err) => {
90
+ // Likely we're trying to open a file, so let's open it!
91
+ if let Ok ( _) = open:: that ( cur_path) {
92
+ log:: info!( "Opened file" ) ;
93
+ return ;
94
+ } else {
95
+ let err = format ! ( "An error occurred: {:?}" , err) ;
96
+ self . err = Some ( err) ;
97
+ self . path_stack . pop ( ) ;
98
+ return ;
103
99
}
104
-
105
100
}
106
101
} ;
102
+
107
103
let collected = paths. collect :: < Vec < _ > > ( ) ;
108
104
log:: info!( "Path list reloaded {:#?}" , collected) ;
109
105
@@ -112,8 +108,11 @@ impl Files {
112
108
self . path_names . clear ( ) ;
113
109
114
110
for path in collected {
115
- self . path_names
116
- . push ( path. unwrap ( ) . path ( ) . display ( ) . to_string ( ) ) ;
111
+ let file = path. unwrap ( ) ;
112
+ self . path_names . push ( File {
113
+ name : file. file_name ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ,
114
+ is_directory : file. file_type ( ) . unwrap ( ) . is_dir ( ) ,
115
+ } ) ;
117
116
}
118
117
log:: info!( "path names are {:#?}" , self . path_names) ;
119
118
}
@@ -127,13 +126,14 @@ impl Files {
127
126
128
127
fn enter_dir ( & mut self , dir_id : usize ) {
129
128
let path = & self . path_names [ dir_id] ;
130
- self . path_stack . push ( path. clone ( ) ) ;
129
+ self . path_stack . push ( path. name . to_string ( ) ) ;
131
130
self . reload_path_list ( ) ;
132
131
}
133
132
134
- fn current ( & self ) -> & str {
135
- self . path_stack . last ( ) . unwrap ( )
133
+ fn current ( & self ) -> String {
134
+ self . path_stack . join ( "/" )
136
135
}
136
+
137
137
fn clear_err ( & mut self ) {
138
138
self . err = None ;
139
139
}
0 commit comments