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

feat: file-explorer working example with v0.5 #47

Merged
merged 6 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
members = [
"dog-app",
"ecommerce-site",
"file-explorer",
"image_generator_open_ai",
"ios_demo",
"jsframework-benchmark",
Expand Down
14 changes: 13 additions & 1 deletion file-explorer/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
/target
# Generated by Cargo
# will have compiled files and executables
/target/
/dist/
/static/
/.dioxus/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk
29 changes: 13 additions & 16 deletions file-explorer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
[package]
name = "file-explorer"
version = "0.1.1"
edition = "2018"
description = "File Explorer with Dioxus"
edition = "2021"
version = "0.1.0"

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

[dependencies]
dioxus = { version = "0.4.0" }
dioxus-desktop = { version = "0.4.0" }
log = "0.4.14"
open = "5.0.0"
simple_logger = "4.2.0"

dioxus = { version = "0.5", features = ["desktop"] }

# Debug
log = "0.4.19"
dioxus-logger = "0.4.1"
open = "5.1.2"

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

# This package is not part of the workspace to avoid dependancy resolution issues between dioxus 0.4 and 0.5
[workspace]
43 changes: 43 additions & 0 deletions file-explorer/Dioxus.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[application]

# App (Project) Name
name = "file-explorer"

# Dioxus App Default Platform
# desktop, web
default_platform = "desktop"

# `build` & `serve` dist path
out_dir = "dist"

# assets file folder
asset_dir = "assets"

[web.app]

# HTML title tag content
title = "file-explorer"

[web.watcher]

# when watcher trigger, regenerate the `index.html`
reload_html = true

# which files or dirs will be watcher monitoring
watch_path = ["src", "assets"]

# include `assets` in web platform
[web.resource]

# CSS style file

style = []

# Javascript code file
script = []

[web.resource.dev]

# Javascript code file
# serve: [dev-server] only
script = []
5 changes: 3 additions & 2 deletions file-explorer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

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

![example](./image.png)
![example](./src/image.png)


## To run this example:

```
cargo run
dx serve
```

Binary file added file-explorer/assets/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 0 additions & 23 deletions file-explorer/src/style.css → file-explorer/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,6 @@ body {
padding-top: 77px;
}

/* header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10;
padding: 20px;
background-color: #2196F3;
color: white;
}
header h1 {
float: left;
font-size: 20px;
font-weight: 400;
}
header .material-icons {
float: right;
cursor: pointer;
}
header .icon-menu {
float: left;
margin-right: 20px;
} */

main {
padding: 20px 50px;
Expand Down
Binary file removed file-explorer/image.png
Binary file not shown.
124 changes: 62 additions & 62 deletions file-explorer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,73 +7,71 @@
//! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do.

use dioxus::prelude::*;
use dioxus_desktop::{Config, WindowBuilder};

use log::LevelFilter;

fn main() {
// simple_logger::init_with_level(log::Level::Debug).unwrap();
dioxus_desktop::launch_cfg(
App,
Config::default().with_window(WindowBuilder::new().with_resizable(true).with_inner_size(
dioxus_desktop::wry::application::dpi::LogicalSize::new(400.0, 800.0),
)),
);
// Init debug
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");

dioxus::launch(App);
}

fn App(cx: Scope) -> Element {
let files = use_ref(cx, Files::new);

render!(div {
link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet" }
style { include_str!("./style.css") }
header {
i { class: "material-icons icon-menu", "menu" }
h1 { "Files: " "{files.read().current()}" }
span { }
i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
}
main {
files.read().path_names.iter().enumerate().map(|(dir_id, path)| {
let path_end = path.split('/').last().unwrap_or(path.as_str());
let icon_type = if path_end.contains('.') {
"description"
} else {
"folder"
};
rsx! (
div { class: "folder", key: "{path}",
#[component]
fn App() -> Element {
// Build cool things ✌️
let mut files = use_signal(|| Files::new());

rsx! {
div {
link { href: "https://fonts.googleapis.com/icon?family=Material+Icons", rel: "stylesheet" }
link { rel: "stylesheet", href: "main.css" }
header {
i { class: "material-icons icon-menu", "menu" }
h1 { "Files: {files.read().current()}" }
span { }
i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
}
main {
for (dir_id, path) in files.read().path_names.iter().enumerate() {
div {
class: "folder", key: "{path.name}",
i { class: "material-icons",
onclick: move |_| files.write().enter_dir(dir_id),
"{icon_type}"
// Change the icon
if path.is_directory { "folder" } else { "description" }
// The tooltip
p { class: "cooltip", "0 folders / 0 files" }
}
h1 { "{path_end}" }
h1 { "{path.name}" }
}
)
})
files.read().err.as_ref().map(|err| {
rsx! (
}
if let Some(err) = files.read().err.as_ref() {
div {
code { "{err}" }
button { onclick: move |_| files.write().clear_err(), "x" }
}
)
})
}
}
}
}
}

})
#[derive(Debug)]
struct File {
is_directory: bool,
name: String,
}

struct Files {
path_stack: Vec<String>,
path_names: Vec<String>,
path_names: Vec<File>,
err: Option<String>,
}

impl Files {
fn new() -> Self {
let mut files = Self {
path_stack: vec!["./".to_string()],
path_stack: vec![".".to_string()],
path_names: vec![],
err: None,
};
Expand All @@ -84,26 +82,24 @@ impl Files {
}

fn reload_path_list(&mut self) {
let cur_path = self.path_stack.last().unwrap();
let cur_path = self.path_stack.join("/");
log::info!("Reloading path list for {:?}", cur_path);
let paths = match std::fs::read_dir(cur_path) {
let paths = match std::fs::read_dir(&cur_path) {
Ok(e) => e,
Err(err) => { //Likely we're trying to open a file, so let's open it!
match open::that(cur_path){
Ok(_) => {
log::info!("Opened file");
return;
},
Err(err) => {
let err = format!("An error occurred: {:?}", err);
self.err = Some(err);
self.path_stack.pop();
return;
}
Err(err) => {
// Likely we're trying to open a file, so let's open it!
if let Ok(_) = open::that(cur_path) {
log::info!("Opened file");
return;
} else {
let err = format!("An error occurred: {:?}", err);
self.err = Some(err);
self.path_stack.pop();
return;
}

}
};

let collected = paths.collect::<Vec<_>>();
log::info!("Path list reloaded {:#?}", collected);

Expand All @@ -112,8 +108,11 @@ impl Files {
self.path_names.clear();

for path in collected {
self.path_names
.push(path.unwrap().path().display().to_string());
let file = path.unwrap();
self.path_names.push(File {
name: file.file_name().to_str().unwrap().to_string(),
is_directory: file.file_type().unwrap().is_dir(),
});
}
log::info!("path names are {:#?}", self.path_names);
}
Expand All @@ -127,13 +126,14 @@ impl Files {

fn enter_dir(&mut self, dir_id: usize) {
let path = &self.path_names[dir_id];
self.path_stack.push(path.clone());
self.path_stack.push(path.name.to_string());
self.reload_path_list();
}

fn current(&self) -> &str {
self.path_stack.last().unwrap()
fn current(&self) -> String {
self.path_stack.join("/")
}

fn clear_err(&mut self) {
self.err = None;
}
Expand Down
Loading