77//! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do.
88
99use dioxus:: prelude:: * ;
10- use dioxus_desktop:: { Config , WindowBuilder } ;
11-
10+ use log:: LevelFilter ;
1211
1312fn 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 ) ;
2117}
2218
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}" ,
4538 i { class: "material-icons" ,
4639 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
4843 p { class: "cooltip" , "0 folders / 0 files" }
4944 }
50- h1 { "{path_end }" }
45+ h1 { "{path.name }" }
5146 }
52- )
53- } )
54- files. read( ) . err. as_ref( ) . map( |err| {
55- rsx! (
47+ }
48+ if let Some ( err) = files. read( ) . err. as_ref( ) {
5649 div {
5750 code { "{err}" }
5851 button { onclick: move |_| files. write( ) . clear_err( ) , "x" }
5952 }
60- )
61- } )
53+ }
54+ }
6255 }
56+ }
57+ }
6358
64- } )
59+ #[ derive( Debug ) ]
60+ struct File {
61+ is_directory : bool ,
62+ name : String ,
6563}
6664
6765struct Files {
6866 path_stack : Vec < String > ,
69- path_names : Vec < String > ,
67+ path_names : Vec < File > ,
7068 err : Option < String > ,
7169}
7270
7371impl Files {
7472 fn new ( ) -> Self {
7573 let mut files = Self {
76- path_stack : vec ! [ "./ " . to_string( ) ] ,
74+ path_stack : vec ! [ "." . to_string( ) ] ,
7775 path_names : vec ! [ ] ,
7876 err : None ,
7977 } ;
@@ -84,26 +82,24 @@ impl Files {
8482 }
8583
8684 fn reload_path_list ( & mut self ) {
87- let cur_path = self . path_stack . last ( ) . unwrap ( ) ;
85+ let cur_path = self . path_stack . join ( "/" ) ;
8886 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) {
9088 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 ;
10399 }
104-
105100 }
106101 } ;
102+
107103 let collected = paths. collect :: < Vec < _ > > ( ) ;
108104 log:: info!( "Path list reloaded {:#?}" , collected) ;
109105
@@ -112,8 +108,11 @@ impl Files {
112108 self . path_names . clear ( ) ;
113109
114110 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+ } ) ;
117116 }
118117 log:: info!( "path names are {:#?}" , self . path_names) ;
119118 }
@@ -127,13 +126,14 @@ impl Files {
127126
128127 fn enter_dir ( & mut self , dir_id : usize ) {
129128 let path = & self . path_names [ dir_id] ;
130- self . path_stack . push ( path. clone ( ) ) ;
129+ self . path_stack . push ( path. name . to_string ( ) ) ;
131130 self . reload_path_list ( ) ;
132131 }
133132
134- fn current ( & self ) -> & str {
135- self . path_stack . last ( ) . unwrap ( )
133+ fn current ( & self ) -> String {
134+ self . path_stack . join ( "/" )
136135 }
136+
137137 fn clear_err ( & mut self ) {
138138 self . err = None ;
139139 }
0 commit comments