Compare commits
1 Commits
temp-andro
...
404dca86e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
404dca86e1
|
8
.github/workflows/rust-check.yaml
vendored
8
.github/workflows/rust-check.yaml
vendored
@@ -21,9 +21,9 @@ jobs:
|
|||||||
run: >
|
run: >
|
||||||
apt-get update && apt-get install -y
|
apt-get update && apt-get install -y
|
||||||
libgtk-3-dev=3.24.33-1ubuntu2.2
|
libgtk-3-dev=3.24.33-1ubuntu2.2
|
||||||
libjavascriptcoregtk-4.1-dev=2.50.4-0ubuntu0.22.04.1
|
libjavascriptcoregtk-4.1-dev=2.50.3-0ubuntu0.22.04.1
|
||||||
libsoup-3.0-dev=3.0.7-0ubuntu1
|
libsoup-3.0-dev=3.0.7-0ubuntu1
|
||||||
libwebkit2gtk-4.1-dev=2.50.4-0ubuntu0.22.04.1
|
libwebkit2gtk-4.1-dev=2.50.3-0ubuntu0.22.04.1
|
||||||
libxdo-dev=1:3.20160805.1-4
|
libxdo-dev=1:3.20160805.1-4
|
||||||
- name: Rust toolchain installation
|
- name: Rust toolchain installation
|
||||||
uses: dtolnay/rust-toolchain@9bc92bc5598b4f3bec5d910d352094982cb0c3b9 # 1.92.0
|
uses: dtolnay/rust-toolchain@9bc92bc5598b4f3bec5d910d352094982cb0c3b9 # 1.92.0
|
||||||
@@ -40,6 +40,6 @@ jobs:
|
|||||||
- name: rustfmt check
|
- name: rustfmt check
|
||||||
run: cargo fmt --all --check
|
run: cargo fmt --all --check
|
||||||
- name: Clippy check
|
- name: Clippy check
|
||||||
run: cargo clippy --locked --all-targets --all-features -- --deny warnings
|
run: cargo clippy --all-targets --all-features -- --deny warnings
|
||||||
- name: test check
|
- name: test check
|
||||||
run: cargo --locked test --all --all-targets --all-features
|
run: cargo test --all --all-targets --all-features
|
||||||
|
|||||||
54
Cargo.lock
generated
54
Cargo.lock
generated
@@ -534,9 +534,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.43"
|
version = "0.4.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -1014,9 +1014,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel"
|
name = "diesel"
|
||||||
version = "2.3.6"
|
version = "2.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b6c2fc184a6fb6ebcf5f9a5e3bbfa84d8fd268cdfcce4ed508979a6259494d"
|
checksum = "0c415189028b232660655e4893e8bc25ca7aee8e96888db66d9edb400535456a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@@ -1285,13 +1285,6 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dioxus-free-icons"
|
|
||||||
version = "0.10.0"
|
|
||||||
dependencies = [
|
|
||||||
"dioxus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dioxus-fullstack"
|
name = "dioxus-fullstack"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
@@ -4775,15 +4768,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.149"
|
version = "1.0.145"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
"zmij",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5341,30 +5334,30 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.45"
|
version = "0.3.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
|
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
"itoa",
|
"itoa",
|
||||||
"num-conv",
|
"num-conv",
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
"serde_core",
|
"serde",
|
||||||
"time-core",
|
"time-core",
|
||||||
"time-macros",
|
"time-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-core"
|
name = "time-core"
|
||||||
version = "0.1.7"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
|
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-macros"
|
name = "time-macros"
|
||||||
version = "0.2.25"
|
version = "0.2.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
|
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-conv",
|
"num-conv",
|
||||||
"time-core",
|
"time-core",
|
||||||
@@ -5405,7 +5398,6 @@ dependencies = [
|
|||||||
"diesel",
|
"diesel",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-free-icons",
|
|
||||||
"dioxus-html",
|
"dioxus-html",
|
||||||
"dioxus-i18n",
|
"dioxus-i18n",
|
||||||
"feruca",
|
"feruca",
|
||||||
@@ -5424,9 +5416,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.49.0"
|
version = "1.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -5655,9 +5647,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.44"
|
version = "0.1.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@@ -5678,9 +5670,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.36"
|
version = "0.1.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
@@ -6904,9 +6896,3 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zmij"
|
|
||||||
version = "1.0.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
|
|
||||||
|
|||||||
19
Cargo.toml
19
Cargo.toml
@@ -7,21 +7,19 @@ edition = "2024"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { version = "0.4.43", features = ["serde", "unstable-locales"] }
|
chrono = { version = "0.4.42", features = ["serde", "unstable-locales"] }
|
||||||
# Remember to update the CLI as well.
|
|
||||||
dioxus = { git = "https://github.com/matous-volf/dioxus", rev = "627d5ca5b80aeed57c23e253024665f103117f5e", features = ["fullstack", "router"] }
|
dioxus = { git = "https://github.com/matous-volf/dioxus", rev = "627d5ca5b80aeed57c23e253024665f103117f5e", features = ["fullstack", "router"] }
|
||||||
# TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/4765 is resolved.
|
# TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/4765 is resolved.
|
||||||
dioxus-html = { git = "https://github.com/matous-volf/dioxus", rev = "627d5ca5b80aeed57c23e253024665f103117f5e", features = ["serialize"] }
|
dioxus-html = { git = "https://github.com/matous-volf/dioxus", rev = "627d5ca5b80aeed57c23e253024665f103117f5e", features = ["serialize"] }
|
||||||
feruca = { version = "0.11.5" }
|
feruca = { version = "0.11.5" }
|
||||||
serde = { version = "1.0.228" }
|
serde = { version = "1.0.228" }
|
||||||
serde_json = { version = "1.0.149" }
|
serde_json = { version = "1.0.145" }
|
||||||
serde_with = { version = "3.16.1", features = ["chrono_0_4"] }
|
serde_with = { version = "3.16.1", features = ["chrono_0_4"] }
|
||||||
tracing = "0.1.44"
|
tracing = "0.1.43"
|
||||||
unic-langid-impl = { version = "0.9.6", features = ["serde"] }
|
unic-langid-impl = { version = "0.9.6", features = ["serde"] }
|
||||||
validator = { version = "0.20.0", features = ["derive"] }
|
validator = { version = "0.20.0", features = ["derive"] }
|
||||||
|
|
||||||
# Remember to update the CLI as well.
|
diesel = { version = "2.3.4", features = [
|
||||||
diesel = { version = "2.3.6", features = [
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"postgres",
|
"postgres",
|
||||||
"postgres_backend",
|
"postgres_backend",
|
||||||
@@ -31,18 +29,13 @@ diesel_migrations = { version = "2.3.1", features = [
|
|||||||
"postgres",
|
"postgres",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
rand = { version = "0.9.2", optional = true }
|
rand = { version = "0.9.2", optional = true }
|
||||||
time = { version = "0.3.45", optional = true }
|
time = { version = "0.3.44", optional = true }
|
||||||
tokio = { version = "1.49.0", optional = true }
|
tokio = { version = "1.48.0", optional = true }
|
||||||
|
|
||||||
async-std = { version = "1.13.2", optional = true }
|
async-std = { version = "1.13.2", optional = true }
|
||||||
dioxus-i18n = { path = "dioxus-i18n" }
|
dioxus-i18n = { path = "dioxus-i18n" }
|
||||||
voca_rs = "1.15.2"
|
voca_rs = "1.15.2"
|
||||||
load-dotenv = "0.1.2"
|
load-dotenv = "0.1.2"
|
||||||
# TODO: Switch to upstream once it merges the changes.
|
|
||||||
dioxus-free-icons = { path = "dioxus-free-icons/packages/lib", features = [
|
|
||||||
"font-awesome-regular",
|
|
||||||
"font-awesome-solid",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["web"]
|
default = ["web"]
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 108 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 22 KiB |
203
assets/images/icon.svg
Normal file
203
assets/images/icon.svg
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="icon.svg"
|
||||||
|
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:zoom="1.1020922"
|
||||||
|
inkscape:cx="188.27826"
|
||||||
|
inkscape:cy="204.15715"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1011"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect2"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect1"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:#27272a;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect1"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
inkscape:label="background"
|
||||||
|
ry="128.00018"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
rx="129.98714" />
|
||||||
|
<g
|
||||||
|
id="g17"
|
||||||
|
inkscape:label="logo"
|
||||||
|
transform="translate(8)">
|
||||||
|
<g
|
||||||
|
id="g8"
|
||||||
|
inkscape:label="ring">
|
||||||
|
<g
|
||||||
|
id="g7"
|
||||||
|
inkscape:label="back">
|
||||||
|
<circle
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:#d97706;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1"
|
||||||
|
cx="224"
|
||||||
|
cy="256"
|
||||||
|
r="128"
|
||||||
|
inkscape:label="ring back" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:21.8936;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect2"
|
||||||
|
width="48"
|
||||||
|
height="288"
|
||||||
|
x="224"
|
||||||
|
y="112"
|
||||||
|
inkscape:label="rect2" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
transform="translate(-4.163147,-0.69235229)"
|
||||||
|
inkscape:label="front">
|
||||||
|
<circle
|
||||||
|
style="fill:#27272a;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1-5-2"
|
||||||
|
cx="276.16315"
|
||||||
|
cy="256.69235"
|
||||||
|
r="128" />
|
||||||
|
<circle
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#fbbf24;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1-5"
|
||||||
|
cx="276.16315"
|
||||||
|
cy="256.69235"
|
||||||
|
r="128" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g16"
|
||||||
|
inkscape:label="tick"
|
||||||
|
transform="translate(16.000231,-8.3918418e-5)">
|
||||||
|
<g
|
||||||
|
id="g6"
|
||||||
|
transform="rotate(45,-57.96574,415.4208)"
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
|
inkscape:label="back">
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect9"
|
||||||
|
width="32.000458"
|
||||||
|
height="32"
|
||||||
|
x="273.94067"
|
||||||
|
y="210.74516"
|
||||||
|
transform="rotate(-45,-57.96574,415.4208)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect8"
|
||||||
|
width="32.000458"
|
||||||
|
height="32"
|
||||||
|
x="206.05841"
|
||||||
|
y="233.37257"
|
||||||
|
transform="rotate(-45,-57.96574,415.4208)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect7"
|
||||||
|
height="16"
|
||||||
|
x="228.686"
|
||||||
|
y="285.255"
|
||||||
|
width="32"
|
||||||
|
transform="rotate(-45,-57.96574,415.4208)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect5"
|
||||||
|
width="64"
|
||||||
|
height="32"
|
||||||
|
x="0"
|
||||||
|
y="100" />
|
||||||
|
<rect
|
||||||
|
style="fill:#d97706;fill-opacity:1;stroke:none;stroke-width:39.1918;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect6"
|
||||||
|
width="32"
|
||||||
|
height="96"
|
||||||
|
x="32"
|
||||||
|
y="36" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4"
|
||||||
|
transform="rotate(45,-41.965512,454.04877)"
|
||||||
|
style="fill:#fbbf24;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
|
inkscape:label="front">
|
||||||
|
<rect
|
||||||
|
style="fill:#fbbf24;fill-opacity:1;stroke:none;stroke-width:32;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect3"
|
||||||
|
width="64"
|
||||||
|
height="32"
|
||||||
|
x="0"
|
||||||
|
y="100" />
|
||||||
|
<rect
|
||||||
|
style="fill:#fbbf24;fill-opacity:1;stroke:none;stroke-width:39.1918;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4"
|
||||||
|
width="32"
|
||||||
|
height="96"
|
||||||
|
x="32"
|
||||||
|
y="36" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.4 KiB |
@@ -3,8 +3,8 @@
|
|||||||
"short_name": "Todo Baggins",
|
"short_name": "Todo Baggins",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#101828",
|
"background_color": "#27272a",
|
||||||
"theme_color": "#b89a2e",
|
"theme_color": "#27272a",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/assets/images/icon.png",
|
"src": "/assets/images/icon.png",
|
||||||
|
|||||||
17
assets/styles/fonts.css
Normal file
17
assets/styles/fonts.css
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@layer base {
|
||||||
|
@font-face {
|
||||||
|
font-family: Inter;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url("/assets/fonts/inter_variable.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Inter;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url("/assets/fonts/inter_variable_italic.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,37 +8,56 @@ input[type="range"] {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-moz-range-thumb,
|
input[type="range"]::-moz-range-thumb {
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
background: var(--color-gray-400);
|
background: rgba(228 228 231);
|
||||||
filter: drop-shadow(0 var(--spacing) 0 var(--color-gray-500));
|
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
input[type="range"]::-moz-range-progress {
|
||||||
position: relative;
|
background: #525259;
|
||||||
top: -9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"]::-moz-range-track,
|
|
||||||
input[type="range"]::-webkit-slider-runnable-track {
|
|
||||||
background: var(--color-gray-800-muted);
|
|
||||||
height: 0.5rem;
|
height: 0.5rem;
|
||||||
filter: drop-shadow(
|
|
||||||
0 calc(0px - var(--spacing)) 0 var(--color-gray-900-muted)
|
|
||||||
);
|
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-moz-range-track {
|
input[type="range"]::-moz-range-track {
|
||||||
transform: translateY(3px);
|
background: rgba(39 39 42 / 50%);
|
||||||
|
height: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"].input-range-reverse::-moz-range-progress {
|
||||||
|
background: #2d2d31;
|
||||||
|
height: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"].input-range-reverse::-moz-range-track {
|
||||||
|
background: rgba(113 113 122 / 50%);
|
||||||
|
height: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
background: rgba(228 228 231);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
position: relative;
|
||||||
|
top: -0.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-runnable-track {
|
input[type="range"]::-webkit-slider-runnable-track {
|
||||||
position: relative;
|
background: rgba(39 39 42 / 50%);
|
||||||
top: 3px;
|
height: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"].input-range-reverse::-webkit-slider-runnable-track {
|
||||||
|
background: rgba(39 39 42 / 50%);
|
||||||
|
height: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
select {
|
|
||||||
appearance: none;
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 640'%3E%3Cpath fill='%239ca3af' d='M300.3 440.8C312.9 451 331.4 450.3 343.1 438.6L471.1 310.6C480.3 301.4 483 287.7 478 275.7C473 263.7 461.4 256 448.5 256L192.5 256C179.6 256 167.9 263.8 162.9 275.8C157.9 287.8 160.7 301.5 169.9 310.6L297.9 438.6L300.3 440.8z'/%3E%3C/svg%3E");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 2rem;
|
|
||||||
background-position: right 0.5rem center;
|
|
||||||
}
|
|
||||||
48
dioxus-free-icons/.github/release-drafter.yml
vendored
48
dioxus-free-icons/.github/release-drafter.yml
vendored
@@ -1,48 +0,0 @@
|
|||||||
name-template: "Release v$RESOLVED_VERSION 🦀"
|
|
||||||
tag-template: "v$RESOLVED_VERSION"
|
|
||||||
categories:
|
|
||||||
- title: "🚀 Features"
|
|
||||||
label: "feature"
|
|
||||||
- title: "🐛 Bug Fixes"
|
|
||||||
label: "bug"
|
|
||||||
- title: "♻️ Refactor"
|
|
||||||
label: "refactor"
|
|
||||||
- title: "📝 Documentation"
|
|
||||||
label: "documentation"
|
|
||||||
- title: "🧰 Maintenance"
|
|
||||||
labels:
|
|
||||||
- "chore"
|
|
||||||
- "dependencies"
|
|
||||||
change-template: "- $TITLE @$AUTHOR (#$NUMBER)"
|
|
||||||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
|
||||||
version-resolver:
|
|
||||||
major:
|
|
||||||
labels:
|
|
||||||
- "major"
|
|
||||||
minor:
|
|
||||||
labels:
|
|
||||||
- "minor"
|
|
||||||
patch:
|
|
||||||
labels:
|
|
||||||
- "patch"
|
|
||||||
default: patch
|
|
||||||
template: |
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
$CHANGES
|
|
||||||
autolabeler:
|
|
||||||
- label: feature
|
|
||||||
branch:
|
|
||||||
- "/^feat(ure)?[/-].+/"
|
|
||||||
- label: bug
|
|
||||||
branch:
|
|
||||||
- "/^fix[/-].+/"
|
|
||||||
- label: refactor
|
|
||||||
branch:
|
|
||||||
- "/(refactor|refactoring)[/-].+/"
|
|
||||||
- label: documentation
|
|
||||||
branch:
|
|
||||||
- "/doc(s|umentation)[/-].+/"
|
|
||||||
- label: chore
|
|
||||||
branch:
|
|
||||||
- "/^chore[/-].+/"
|
|
||||||
25
dioxus-free-icons/.github/workflows/ci.yml
vendored
25
dioxus-free-icons/.github/workflows/ci.yml
vendored
@@ -1,25 +0,0 @@
|
|||||||
name: Cargo Build & Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches: [ "main" ]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_and_test:
|
|
||||||
name: Rust project - latest
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Install the nightly toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@nightly
|
|
||||||
- name: Install linux dependencies
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: |
|
|
||||||
sudo apt update && sudo apt install build-essential libssl-dev pkg-config libglib2.0-dev libgtk-3-dev
|
|
||||||
- run: cargo build --verbose
|
|
||||||
- run: cargo test --verbose
|
|
||||||
19
dioxus-free-icons/.github/workflows/publish.yml
vendored
19
dioxus-free-icons/.github/workflows/publish.yml
vendored
@@ -1,19 +0,0 @@
|
|||||||
name: Cargo Publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
name: Publish to crate.io
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- run: cargo publish
|
|
||||||
working-directory: ./packages/lib
|
|
||||||
env:
|
|
||||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
name: Release Drafter
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
# pull_request event is required only for autolabeler
|
|
||||||
pull_request:
|
|
||||||
# Only following types are handled by the action, but one can default to all as well
|
|
||||||
types: [opened, reopened, synchronize]
|
|
||||||
# pull_request_target event is required for autolabeler to support PRs from forks
|
|
||||||
# pull_request_target:
|
|
||||||
# types: [opened, reopened, synchronize]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update_release_draft:
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: release-drafter/release-drafter@v5
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
16
dioxus-free-icons/.gitignore
vendored
16
dioxus-free-icons/.gitignore
vendored
@@ -1,16 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
||||||
# Added by cargo
|
|
||||||
|
|
||||||
/target
|
|
||||||
/Cargo.lock
|
|
||||||
27
dioxus-free-icons/.gitmodules
vendored
27
dioxus-free-icons/.gitmodules
vendored
@@ -1,27 +0,0 @@
|
|||||||
[submodule "icon_resources/font-awesome"]
|
|
||||||
path = icon_resources/font-awesome
|
|
||||||
url = https://github.com/FortAwesome/Font-Awesome
|
|
||||||
[submodule "icon_resources/heroicons"]
|
|
||||||
path = icon_resources/heroicons
|
|
||||||
url = https://github.com/tailwindlabs/heroicons
|
|
||||||
[submodule "icon_resources/ionicons"]
|
|
||||||
path = icon_resources/ionicons
|
|
||||||
url = https://github.com/ionic-team/ionicons
|
|
||||||
[submodule "icon_resources/octicons"]
|
|
||||||
path = icon_resources/octicons
|
|
||||||
url = https://github.com/primer/octicons
|
|
||||||
[submodule "icon_resources/bootstrap"]
|
|
||||||
path = icon_resources/bootstrap
|
|
||||||
url = https://github.com/twbs/icons
|
|
||||||
[submodule "icon_resources/feather"]
|
|
||||||
path = icon_resources/feather
|
|
||||||
url = https://github.com/feathericons/feather
|
|
||||||
[submodule "icon_resources/lucide"]
|
|
||||||
path = icon_resources/lucide
|
|
||||||
url = https://github.com/lucide-icons/lucide
|
|
||||||
[submodule "icon_resources/material-design-icons"]
|
|
||||||
path = icon_resources/material-design-icons
|
|
||||||
url = https://github.com/google/material-design-icons
|
|
||||||
[submodule "icon_resources/vscode-codicons"]
|
|
||||||
path = icon_resources/vscode-codicons
|
|
||||||
url = https://github.com/microsoft/vscode-codicons.git
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# monorepo only work when using virtual manifest
|
|
||||||
# see: https://github.com/rust-lang/cargo/issues/7467#issuecomment-867632379
|
|
||||||
[workspace]
|
|
||||||
resolver = "2"
|
|
||||||
members = ["packages/codegen", "packages/example", "packages/lib"]
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
|
||||||
dioxus = { git = "https://github.com/matous-volf/dioxus", rev = "627d5ca5b80aeed57c23e253024665f103117f5e", default-features = false, features = [
|
|
||||||
"html",
|
|
||||||
"macro",
|
|
||||||
"signals",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[profile]
|
|
||||||
|
|
||||||
[profile.wasm-dev]
|
|
||||||
inherits = "dev"
|
|
||||||
opt-level = 1
|
|
||||||
|
|
||||||
[profile.server-dev]
|
|
||||||
inherits = "dev"
|
|
||||||
|
|
||||||
[profile.android-dev]
|
|
||||||
inherits = "dev"
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022-Present Daiki Nishikawa
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
---
|
|
||||||
Icons are taken from the other projects
|
|
||||||
so please check each project licences accordingly.
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
[](https://discord.gg/sKJSVNSCDJ)
|
|
||||||
[](https://crates.io/crates/dioxus-free-icons)
|
|
||||||
|
|
||||||
# dioxus-free-icons 🙂
|
|
||||||
|
|
||||||
Use free svg icons in your [Dioxus](https://dioxuslabs.com/) projects easily with dioxus-free-icons.
|
|
||||||
|
|
||||||
More information about this crate can be found in the [crate documentation](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/).
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
To use `dioxus-free-icons`, add this to your Cargo.toml:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
dioxus-free-icons = { version = "0.9", features = ["font-awesome-brands"] }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Support features
|
|
||||||
|
|
||||||
The following features are available. Please see [react-icons site](https://react-icons.github.io/react-icons) to check the icon name and icon design.
|
|
||||||
|
|
||||||
- [bootstrap](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/bs_icons/index.html)
|
|
||||||
- [codicons](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/vs_icons/index.html)
|
|
||||||
- [font-awesome-brands](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/fa_brands_icons/index.html)
|
|
||||||
- [font-awesome-regular](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/fa_regular_icons/index.html)
|
|
||||||
- [font-awesome-solid](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/fa_solid_icons/index.html)
|
|
||||||
- [feather](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/fi_icons/index.html)
|
|
||||||
- [octicons](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/go_icons/index.html)
|
|
||||||
- [hero-icons-outline](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/hi_outline_icons/index.html)
|
|
||||||
- [hero-icons-solid](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/hi_solid_icons/index.html)
|
|
||||||
- [ionicons](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/io_icons/index.html)
|
|
||||||
- [lucide](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/ld_icons/index.html)
|
|
||||||
- [material-design-icons-action](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_action_icons/index.html)
|
|
||||||
- [material-design-icons-alert](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_alert_icons/index.html)
|
|
||||||
- [material-design-icons-av](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_av_icons/index.html)
|
|
||||||
- [material-design-icons-communication](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_communication_icons/index.html)
|
|
||||||
- [material-design-icons-content](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_content_icons/index.html)
|
|
||||||
- [material-design-icons-device](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/io_icons/index.html)
|
|
||||||
- [material-design-icons-editor](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_editor_icons/index.html)
|
|
||||||
- [material-design-icons-file](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_file_icons/index.html)
|
|
||||||
- [material-design-icons-hardware](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_hardware_icons/index.html)
|
|
||||||
- [material-design-icons-home](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_home_icons/index.html)
|
|
||||||
- [material-design-icons-image](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_image_icons/index.html)
|
|
||||||
- [material-design-icons-maps](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_maps_icons/index.html)
|
|
||||||
- [material-design-icons-navigation](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_navigation_icons/index.html)
|
|
||||||
- [material-design-icons-notification](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_notification_icons/index.html)
|
|
||||||
- [material-design-icons-places](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_places_icons/index.html)
|
|
||||||
- [material-design-icons-social](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_social_icons/index.html)
|
|
||||||
- [material-design-icons-toggle](https://docs.rs/dioxus-free-icons/latest/dioxus_free_icons/icons/md_toggle_icons/index.html)
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
This library provides Icon component, which will generate SVG for a Font Awesome icon.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::icons::fa_brands_icons::FaRust;
|
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
|
|
||||||
fn RustIcon() -> Element {
|
|
||||||
rsx!(
|
|
||||||
Icon {
|
|
||||||
width: 30,
|
|
||||||
height: 30,
|
|
||||||
fill: "black",
|
|
||||||
icon: FaRust,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the MIT license.
|
|
||||||
|
|
||||||
### Icon
|
|
||||||
|
|
||||||
Icon Library|License|Version
|
|
||||||
---|---|---
|
|
||||||
[Bootstrap Icons](https://icons.getbootstrap.com/)|[MIT License](https://github.com/twbs/icons/blob/main/LICENSE.md)| [1.8.3](https://github.com/twbs/icons/tree/v1.8.3)
|
|
||||||
[Codicons](https://microsoft.github.io/vscode-codicons/dist/codicon.html)|[MIT License](https://github.com/microsoft/vscode-codicons/blob/main/LICENSE-CODE) & [CC BY 4.0 License](https://github.com/microsoft/vscode-codicons/blob/main/LICENSE) | [0.0.36](https://github.com/microsoft/vscode-codicons/tree/0.0.36)
|
|
||||||
[Feather](https://feathericons.com/)|[MIT License](https://github.com/feathericons/feather/blob/master/LICENSE)| [4.29.0](https://github.com/feathericons/feather/tree/v4.29.0)
|
|
||||||
[Font Awesome](https://fontawesome.com/)|[CC BY 4.0 License](https://creativecommons.org/licenses/by/4.0/)| [7.1.0](https://github.com/FortAwesome/Font-Awesome/tree/7.1.0)
|
|
||||||
[Heroicons](https://heroicons.com/)|[MIT License](https://github.com/tailwindlabs/heroicons/blob/master/LICENSE)| [1.0.6](https://github.com/tailwindlabs/heroicons/tree/v1.0.6)
|
|
||||||
[Ionicons](https://ionic.io/ionicons)|[MIT License](https://github.com/ionic-team/ionicons/blob/main/LICENSE)| [6.0.2](https://github.com/ionic-team/ionicons/tree/v6.0.2)
|
|
||||||
[Lucide](https://lucide.dev)|[ISC License](https://github.com/lucide-icons/lucide/blob/main/LICENSE)| [0.555.0](https://github.com/lucide-icons/lucide/tree/v0.555.0)
|
|
||||||
[Material Design icons](https://developers.google.com/fonts/docs/material_icons)|[Apache License 2.0](https://github.com/google/material-design-icons/blob/master/LICENSE)| [4.0.0](https://github.com/google/material-design-icons/tree/4.0.0)
|
|
||||||
[Octicons](https://primer.style/octicons/)|[MIT License](https://github.com/primer/octicons/blob/main/LICENSE)| [17.3.0](https://github.com/primer/octicons/tree/v17.3.0)
|
|
||||||
|
|
||||||
## Contribution
|
|
||||||
|
|
||||||
The project welcomes all contributions from anyone willing to work in good faith with other contributors and the community.
|
|
||||||
In particular, contributions regarding support for other free icons such as Material Design icons or Ionicons are welcome.
|
|
||||||
This library aims to be a react-icons-like library for dioxus projects.
|
|
||||||
|
|
||||||
### Development
|
|
||||||
|
|
||||||
```sh
|
|
||||||
// generate icon files
|
|
||||||
cd packages/codegen
|
|
||||||
cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
### Preview
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd packages/exmaple
|
|
||||||
cargo install dioxus-cli
|
|
||||||
dx serve
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update icons
|
|
||||||
|
|
||||||
1. checkout a new tag in the icon resource submodule
|
|
||||||
2. create new icon files
|
|
||||||
3. Update README.md and check the LICENSE
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "dioxus-fontawesome-examples"
|
|
||||||
version = "0.2.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
codegen = "0.1.3"
|
|
||||||
heck = "0.4.0"
|
|
||||||
regex = "1.6.0"
|
|
||||||
scraper = "0.13.0"
|
|
||||||
walkdir = "2.3.2"
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
use std::fs;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::{ffi::OsStr, path::Path};
|
|
||||||
|
|
||||||
use heck::ToSnakeCase;
|
|
||||||
use heck::ToUpperCamelCase;
|
|
||||||
use regex::Regex;
|
|
||||||
use scraper::node::Element;
|
|
||||||
use scraper::ElementRef;
|
|
||||||
use scraper::Html;
|
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
const ICON_TEMPLATE: &str = r#"#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct {ICON_NAME};
|
|
||||||
impl IconShape for {ICON_NAME} {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"{VIEW_BOX}"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"{XMLNS}"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
({FILL_COLOR}, {STROKE_COLOR}, {STROKE_WIDTH})
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"{STROKE_LINECAP}"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"{STROKE_LINEJOIN}"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
{CHILD_ELEMENTS}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
pub fn create_icon_file(svg_path: &str, output_path: &str, icon_prefix: &str) {
|
|
||||||
let files = collect_svg_files(svg_path, icon_prefix);
|
|
||||||
|
|
||||||
let icon_file = files
|
|
||||||
.into_iter()
|
|
||||||
.map(|file| {
|
|
||||||
let svg_str = fs::read_to_string(&file).unwrap();
|
|
||||||
let fragment = Html::parse_fragment(&svg_str);
|
|
||||||
|
|
||||||
let elements = fragment
|
|
||||||
.tree
|
|
||||||
.nodes()
|
|
||||||
.filter_map(|node| {
|
|
||||||
if node.value().is_element() {
|
|
||||||
let element = ElementRef::wrap(node).unwrap().value();
|
|
||||||
if !element.attrs.is_empty() {
|
|
||||||
return Some(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let svg_element = &elements[0];
|
|
||||||
let svg_child_elements = &elements[1..];
|
|
||||||
let icon_name = icon_name(&file, icon_prefix);
|
|
||||||
let (view_box, xmlns) = extract_svg_attrs(svg_element);
|
|
||||||
let child_elements = extract_svg_child_elements(svg_child_elements, icon_prefix);
|
|
||||||
let (fill_color, stroke_color, stroke_width) = extract_svg_colors(icon_prefix);
|
|
||||||
let stroke_linecap = extract_stroke_linecap(icon_prefix);
|
|
||||||
let stroke_linejoin = extract_stroke_linejoin(icon_prefix);
|
|
||||||
|
|
||||||
ICON_TEMPLATE
|
|
||||||
.replace("{ICON_NAME}", &format!("{}{}", icon_prefix, &icon_name))
|
|
||||||
.replace("{VIEW_BOX}", &view_box)
|
|
||||||
.replace("{XMLNS}", &xmlns)
|
|
||||||
.replace("{CHILD_ELEMENTS}", &child_elements)
|
|
||||||
.replace("{FILL_COLOR}", &fill_color)
|
|
||||||
.replace("{STROKE_COLOR}", &stroke_color)
|
|
||||||
.replace("{STROKE_WIDTH}", &stroke_width)
|
|
||||||
.replace("{STROKE_LINECAP}", &stroke_linecap)
|
|
||||||
.replace("{STROKE_LINEJOIN}", &stroke_linejoin)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n");
|
|
||||||
|
|
||||||
// write to file
|
|
||||||
let mut file = File::create(output_path).unwrap();
|
|
||||||
file.write_all(
|
|
||||||
format!(
|
|
||||||
"{}\n\n{}",
|
|
||||||
"use super::super::IconShape;\nuse dioxus::prelude::*;", icon_file
|
|
||||||
)
|
|
||||||
.as_bytes(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
file.flush().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_svg_files(svg_path: &str, icon_prefix: &str) -> Vec<PathBuf> {
|
|
||||||
let dir_entries = WalkDir::new(svg_path)
|
|
||||||
.sort_by_file_name()
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.ok())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
dir_entries
|
|
||||||
.into_iter()
|
|
||||||
.filter(|e| match icon_prefix {
|
|
||||||
"Go" => {
|
|
||||||
let re = Regex::new(r".*-16.svg$").unwrap();
|
|
||||||
return re.is_match(e.path().to_str().unwrap());
|
|
||||||
}
|
|
||||||
"Md" => {
|
|
||||||
let split_vec = e.path().components().collect::<Vec<_>>();
|
|
||||||
return split_vec.iter().any(|c| c.as_os_str() == "materialicons")
|
|
||||||
&& e.file_name().to_str().unwrap() == "24px.svg";
|
|
||||||
}
|
|
||||||
_ => return e.path().extension() == Some(OsStr::new("svg")),
|
|
||||||
})
|
|
||||||
.map(|dir| PathBuf::from(dir.path()))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn icon_name(path: &Path, icon_prefix: &str) -> String {
|
|
||||||
match icon_prefix {
|
|
||||||
"Go" => {
|
|
||||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
|
||||||
let name = filename.split('.').next().unwrap();
|
|
||||||
name.replace("-16", "").to_upper_camel_case()
|
|
||||||
}
|
|
||||||
"Md" => {
|
|
||||||
let split_vec = path.components().collect::<Vec<_>>();
|
|
||||||
let name = split_vec[split_vec.len() - 3];
|
|
||||||
name.as_os_str().to_str().unwrap().to_upper_camel_case()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
|
||||||
let name = filename.split('.').next().unwrap();
|
|
||||||
name.to_upper_camel_case()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_svg_attrs(element: &Element) -> (String, String) {
|
|
||||||
let view_box = element.attr("viewBox").unwrap_or("0 0 16 16");
|
|
||||||
let xmlns = element
|
|
||||||
.attr("xmlns")
|
|
||||||
.unwrap_or("http://www.w3.org/2000/svg");
|
|
||||||
(String::from(view_box), String::from(xmlns))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_svg_colors(icon_prefix: &str) -> (&str, &str, &str) {
|
|
||||||
match icon_prefix {
|
|
||||||
"Fi" => ("\"none\"", "user_color", "\"2\""),
|
|
||||||
"Ld" => ("\"none\"", "user_color", "\"2\""),
|
|
||||||
"Io" => ("user_color", "user_color", "\"0\""),
|
|
||||||
_ => ("user_color", "\"none\"", "\"0\""),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_stroke_linecap(icon_prefix: &str) -> &str {
|
|
||||||
match icon_prefix {
|
|
||||||
"Ld" => "round",
|
|
||||||
"Fi" => "round",
|
|
||||||
_ => "butt",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_stroke_linejoin(icon_prefix: &str) -> &str {
|
|
||||||
match icon_prefix {
|
|
||||||
"Ld" => "round",
|
|
||||||
"Fi" => "round",
|
|
||||||
_ => "miter",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_svg_child_elements(elements: &[&Element], icon_prefix: &str) -> String {
|
|
||||||
let elements = match icon_prefix {
|
|
||||||
"Md" => &elements[1..],
|
|
||||||
_ => elements,
|
|
||||||
};
|
|
||||||
elements
|
|
||||||
.iter()
|
|
||||||
.map(|element| {
|
|
||||||
let tag_name = element.name();
|
|
||||||
let mut element_attrs = element
|
|
||||||
.attrs()
|
|
||||||
.filter_map(|(name, value)| {
|
|
||||||
let value = if icon_prefix == "Io" {
|
|
||||||
value.replace("fill:none;stroke:#000;", "")
|
|
||||||
} else {
|
|
||||||
value.to_string()
|
|
||||||
};
|
|
||||||
let re = Regex::new(r"^data-.*$").unwrap();
|
|
||||||
if !re.is_match(name) && name != "fill" {
|
|
||||||
Some(format!(
|
|
||||||
" {}: \"{}\",",
|
|
||||||
name.to_snake_case(),
|
|
||||||
value
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
element_attrs.sort();
|
|
||||||
let attrs_str = element_attrs.join("\n");
|
|
||||||
" {TAG_NAME} {\n{ATTRS}\n }"
|
|
||||||
.replace("{TAG_NAME}", tag_name)
|
|
||||||
.replace("{ATTRS}", &attrs_str)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
mod create_icon_file;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
const OUTPUT_BASE_PATH: &str = "../lib/src/icons";
|
|
||||||
|
|
||||||
// create font awesome icons
|
|
||||||
const FA_SVG_BASE_PATH: &str = "../../icon_resources/font-awesome/svgs";
|
|
||||||
for icon_type in vec!["brands", "regular", "solid"].into_iter() {
|
|
||||||
let svg_path = format!("{}/{}", FA_SVG_BASE_PATH, icon_type);
|
|
||||||
let output_path = format!("{}/fa_{}_icons.rs", OUTPUT_BASE_PATH, icon_type);
|
|
||||||
create_icon_file::create_icon_file(&svg_path, &output_path, "Fa");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create hero icons
|
|
||||||
const HI_SVG_BASE_PATH: &str = "../../icon_resources/heroicons/src";
|
|
||||||
for icon_type in vec!["outline", "solid"].into_iter() {
|
|
||||||
let svg_path = format!("{}/{}", HI_SVG_BASE_PATH, icon_type);
|
|
||||||
let output_path = format!("{}/hi_{}_icons.rs", OUTPUT_BASE_PATH, icon_type);
|
|
||||||
create_icon_file::create_icon_file(&svg_path, &output_path, "Hi");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create ionicons
|
|
||||||
const IO_SVG_BASE_PATH: &str = "../../icon_resources/ionicons/src/svg";
|
|
||||||
let output_path = format!("{}/io_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(IO_SVG_BASE_PATH, &output_path, "Io");
|
|
||||||
|
|
||||||
// create octicons
|
|
||||||
const GO_SVG_BASE_PATH: &str = "../../icon_resources/octicons/icons";
|
|
||||||
let go_output_path = format!("{}/go_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(GO_SVG_BASE_PATH, &go_output_path, "Go");
|
|
||||||
|
|
||||||
// create bootstrap icons
|
|
||||||
const BS_SVG_BASE_PATH: &str = "../../icon_resources/bootstrap/icons";
|
|
||||||
let bs_output_path = format!("{}/bs_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(BS_SVG_BASE_PATH, &bs_output_path, "Bs");
|
|
||||||
|
|
||||||
// create feather icons
|
|
||||||
const FI_SVG_BASE_PATH: &str = "../../icon_resources/feather/icons";
|
|
||||||
let fi_output_path = format!("{}/fi_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(FI_SVG_BASE_PATH, &fi_output_path, "Fi");
|
|
||||||
|
|
||||||
// create feather icons
|
|
||||||
const LD_SVG_BASE_PATH: &str = "../../icon_resources/lucide/icons";
|
|
||||||
let ld_output_path = format!("{}/ld_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(LD_SVG_BASE_PATH, &ld_output_path, "Ld");
|
|
||||||
|
|
||||||
// create material design icons
|
|
||||||
const MI_SVG_BASE_PATH: &str = "../../icon_resources/material-design-icons/src";
|
|
||||||
for icon_type in vec![
|
|
||||||
"action",
|
|
||||||
"alert",
|
|
||||||
"av",
|
|
||||||
"communication",
|
|
||||||
"content",
|
|
||||||
"device",
|
|
||||||
"editor",
|
|
||||||
"file",
|
|
||||||
"hardware",
|
|
||||||
"home",
|
|
||||||
"image",
|
|
||||||
"maps",
|
|
||||||
"navigation",
|
|
||||||
"notification",
|
|
||||||
"places",
|
|
||||||
"social",
|
|
||||||
"toggle",
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
{
|
|
||||||
let svg_path = format!("{}/{}", MI_SVG_BASE_PATH, icon_type);
|
|
||||||
let output_path = format!("{}/md_{}_icons.rs", OUTPUT_BASE_PATH, icon_type);
|
|
||||||
create_icon_file::create_icon_file(&svg_path, &output_path, "Md");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create vscode-codicons
|
|
||||||
const VS_SVG_BASE_PATH: &str = "../../icon_resources/vscode-codicons/src/icons";
|
|
||||||
let vs_output_path = format!("{}/vsc_icons.rs", OUTPUT_BASE_PATH);
|
|
||||||
create_icon_file::create_icon_file(VS_SVG_BASE_PATH, &vs_output_path, "Vsc");
|
|
||||||
}
|
|
||||||
17
dioxus-free-icons/packages/example/.gitignore
vendored
17
dioxus-free-icons/packages/example/.gitignore
vendored
@@ -1,17 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
||||||
# Added by cargo
|
|
||||||
|
|
||||||
/target
|
|
||||||
|
|
||||||
/dist
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "hello-dioxus"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["nissy-dev <nd.12021218@gmail.com>"]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
dioxus = { workspace = true, features = ["launch", "web"] }
|
|
||||||
dioxus-free-icons = { path = "../lib", features = ["font-awesome-brands"] }
|
|
||||||
|
|
||||||
log = "0.4.6"
|
|
||||||
|
|
||||||
# WebAssembly Debug
|
|
||||||
wasm-logger = "0.2.0"
|
|
||||||
console_error_panic_hook = "0.1.7"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
lto = true
|
|
||||||
opt-level = 's'
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
[application]
|
|
||||||
|
|
||||||
# App (Project) Name
|
|
||||||
name = "hello-dioxus"
|
|
||||||
|
|
||||||
# Dioxus App Default Platform
|
|
||||||
# desktop, web, mobile, ssr
|
|
||||||
default_platform = "web"
|
|
||||||
|
|
||||||
# `build` & `serve` dist path
|
|
||||||
out_dir = "dist"
|
|
||||||
|
|
||||||
# resource (public) file folder
|
|
||||||
asset_dir = "public"
|
|
||||||
|
|
||||||
[web.app]
|
|
||||||
|
|
||||||
# HTML title tag content
|
|
||||||
title = "dioxus | ⛺"
|
|
||||||
|
|
||||||
[web.watcher]
|
|
||||||
|
|
||||||
# when watcher trigger, regenerate the `index.html`
|
|
||||||
reload_html = true
|
|
||||||
|
|
||||||
# which files or dirs will be watcher monitoring
|
|
||||||
watch_path = ["src", "public"]
|
|
||||||
|
|
||||||
# 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 = []
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022-Present Daiki Nishikawa
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Example
|
|
||||||
|
|
||||||
> a template for starting a dioxus project to be used with [dioxus-cli](https://github.com/DioxusLabs/cli)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
#### Start a `dev-server` for the project:
|
|
||||||
|
|
||||||
```
|
|
||||||
dioxus serve
|
|
||||||
```
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
use dioxus_free_icons::icons::fa_brands_icons::FaRust;
|
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// init debug tool for WebAssembly
|
|
||||||
wasm_logger::init(wasm_logger::Config::default());
|
|
||||||
console_error_panic_hook::set_once();
|
|
||||||
|
|
||||||
launch(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn app() -> Element {
|
|
||||||
rsx! (
|
|
||||||
div {
|
|
||||||
style: "text-align: center;",
|
|
||||||
h1 { "🌗 Dioxus 🚀" }
|
|
||||||
h3 { "Frontend that scales." }
|
|
||||||
p { "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." },
|
|
||||||
Icon {
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
icon: FaRust,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "dioxus-free-icons"
|
|
||||||
version = "0.10.0"
|
|
||||||
edition = "2021"
|
|
||||||
authors = ["Daiki Nishikawa <nd.12021218@gmail.com>", "Marc Espín <mespinsanz@gmail.com>"]
|
|
||||||
description = "Use free svg icons in your Dioxus projects easily with dioxus-free-icons."
|
|
||||||
license = "MIT"
|
|
||||||
repository = "https://github.com/dioxus-community/dioxus-free-icons"
|
|
||||||
readme = "../../README.md"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
dioxus = { workspace = true }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
font-awesome-brands = []
|
|
||||||
font-awesome-regular = []
|
|
||||||
font-awesome-solid = []
|
|
||||||
bootstrap = []
|
|
||||||
feather = []
|
|
||||||
octicons = []
|
|
||||||
hero-icons-outline = []
|
|
||||||
hero-icons-solid = []
|
|
||||||
ionicons = []
|
|
||||||
lucide = []
|
|
||||||
material-design-icons-action = []
|
|
||||||
material-design-icons-alert = []
|
|
||||||
material-design-icons-av = []
|
|
||||||
material-design-icons-communication = []
|
|
||||||
material-design-icons-content = []
|
|
||||||
material-design-icons-device = []
|
|
||||||
material-design-icons-editor = []
|
|
||||||
material-design-icons-file = []
|
|
||||||
material-design-icons-hardware = []
|
|
||||||
material-design-icons-home = []
|
|
||||||
material-design-icons-image = []
|
|
||||||
material-design-icons-maps = []
|
|
||||||
material-design-icons-navigation = []
|
|
||||||
material-design-icons-notification = []
|
|
||||||
material-design-icons-places = []
|
|
||||||
material-design-icons-social = []
|
|
||||||
material-design-icons-toggle = []
|
|
||||||
codicons = []
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
all-features = true
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022-Present Daiki Nishikawa
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
---
|
|
||||||
Icons are taken from the Font Awesome projects,
|
|
||||||
so please check the project license accordingly.
|
|
||||||
|
|
||||||
Bootstrap Icons - https://github.com/twbs/icons
|
|
||||||
License: MIT License https://github.com/twbs/icons/blob/main/LICENSE.md
|
|
||||||
|
|
||||||
Feather - https://feathericons.com/
|
|
||||||
License: MIT https://github.com/feathericons/feather/blob/master/LICENSE
|
|
||||||
|
|
||||||
Font Awesome - https://fontawesome.com/
|
|
||||||
License: CC BY 4.0 License https://fontawesome.com/license/free
|
|
||||||
|
|
||||||
Heroicons - https://heroicons.com/
|
|
||||||
License: MIT License https://github.com/tailwindlabs/heroicons/blob/master/LICENSE
|
|
||||||
|
|
||||||
Ionicons - https://ionic.io/ionicons/
|
|
||||||
License: MIT License https://github.com/ionic-team/ionicons/blob/main/LICENSE
|
|
||||||
|
|
||||||
Material Design icons - https://developers.google.com/fonts/docs/material_icons
|
|
||||||
License: Apache License 2.0 https://github.com/google/material-design-icons/blob/master/LICENSE
|
|
||||||
|
|
||||||
Octicons - https://primer.style/octicons/
|
|
||||||
License: MIT https://github.com/primer/octicons/blob/master/LICENSE
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
/// Icon shape trait
|
|
||||||
pub trait IconShape {
|
|
||||||
fn view_box(&self) -> &str;
|
|
||||||
fn xmlns(&self) -> &str;
|
|
||||||
fn child_elements(&self) -> Element;
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
("none", user_color, "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Icon component Props
|
|
||||||
#[derive(PartialEq, Props, Clone)]
|
|
||||||
pub struct IconProps<T: IconShape + Clone + PartialEq + 'static> {
|
|
||||||
/// The icon shape to use.
|
|
||||||
pub icon: T,
|
|
||||||
/// The height of the `<svg>` element. Defaults to 20. Pass None to omit.
|
|
||||||
#[props(default = Some(20))]
|
|
||||||
pub height: Option<u32>,
|
|
||||||
/// The width of the `<svg>` element. Defaults to 20. Pass None to omit.
|
|
||||||
#[props(default = Some(20))]
|
|
||||||
pub width: Option<u32>,
|
|
||||||
/// The color to use for filling the icon. Defaults to "currentColor".
|
|
||||||
#[props(default = "currentColor".to_string())]
|
|
||||||
pub fill: String,
|
|
||||||
/// An class for the `<svg>` element.
|
|
||||||
#[props(default = "".to_string())]
|
|
||||||
pub class: String,
|
|
||||||
/// An accessible, short-text description for the icon.
|
|
||||||
pub title: Option<String>,
|
|
||||||
/// The style of the `<svg>` element.
|
|
||||||
pub style: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Icon component which generates SVG elements
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn Icon<T: IconShape + Clone + PartialEq + 'static>(props: IconProps<T>) -> Element {
|
|
||||||
let (fill, stroke, stroke_width) = props.icon.fill_and_stroke(&props.fill);
|
|
||||||
rsx!(
|
|
||||||
svg {
|
|
||||||
class: "{props.class}",
|
|
||||||
style: props.style,
|
|
||||||
height: props.height.map(|height| height.to_string()),
|
|
||||||
width: props.width.map(|width| width.to_string()),
|
|
||||||
view_box: "{props.icon.view_box()}",
|
|
||||||
xmlns: "{props.icon.xmlns()}",
|
|
||||||
fill,
|
|
||||||
stroke,
|
|
||||||
stroke_width,
|
|
||||||
stroke_linecap: "{props.icon.stroke_linecap()}",
|
|
||||||
stroke_linejoin: "{props.icon.stroke_linejoin()}",
|
|
||||||
if let Some(title_text) = props.title {
|
|
||||||
title { "{title_text}" }
|
|
||||||
}
|
|
||||||
{props.icon.child_elements()}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#[cfg(feature = "bootstrap")]
|
|
||||||
pub mod bs_icons;
|
|
||||||
#[cfg(feature = "font-awesome-brands")]
|
|
||||||
pub mod fa_brands_icons;
|
|
||||||
#[cfg(feature = "font-awesome-regular")]
|
|
||||||
pub mod fa_regular_icons;
|
|
||||||
#[cfg(feature = "font-awesome-solid")]
|
|
||||||
pub mod fa_solid_icons;
|
|
||||||
#[cfg(feature = "feather")]
|
|
||||||
pub mod fi_icons;
|
|
||||||
#[cfg(feature = "octicons")]
|
|
||||||
pub mod go_icons;
|
|
||||||
#[cfg(feature = "hero-icons-outline")]
|
|
||||||
pub mod hi_outline_icons;
|
|
||||||
#[cfg(feature = "hero-icons-solid")]
|
|
||||||
pub mod hi_solid_icons;
|
|
||||||
#[cfg(feature = "ionicons")]
|
|
||||||
pub mod io_icons;
|
|
||||||
#[cfg(feature = "lucide")]
|
|
||||||
pub mod ld_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-action")]
|
|
||||||
pub mod md_action_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-alert")]
|
|
||||||
pub mod md_alert_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-av")]
|
|
||||||
pub mod md_av_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-communication")]
|
|
||||||
pub mod md_communication_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-content")]
|
|
||||||
pub mod md_content_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-device")]
|
|
||||||
pub mod md_device_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-editor")]
|
|
||||||
pub mod md_editor_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-file")]
|
|
||||||
pub mod md_file_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-hardware")]
|
|
||||||
pub mod md_hardware_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-home")]
|
|
||||||
pub mod md_home_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-image")]
|
|
||||||
pub mod md_image_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-maps")]
|
|
||||||
pub mod md_maps_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-navigation")]
|
|
||||||
pub mod md_navigation_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-notification")]
|
|
||||||
pub mod md_notification_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-places")]
|
|
||||||
pub mod md_places_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-social")]
|
|
||||||
pub mod md_social_icons;
|
|
||||||
#[cfg(feature = "material-design-icons-toggle")]
|
|
||||||
pub mod md_toggle_icons;
|
|
||||||
#[cfg(feature = "codicons")]
|
|
||||||
pub mod vsc_icons;
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,170 +0,0 @@
|
|||||||
use super::super::IconShape;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdAddAlert;
|
|
||||||
impl IconShape for MdAddAlert {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdAutoDelete;
|
|
||||||
impl IconShape for MdAutoDelete {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
polygon {
|
|
||||||
points: "15,2 11.5,2 10.5,1 5.5,1 4.5,2 1,2 1,4 15,4",
|
|
||||||
}
|
|
||||||
path {
|
|
||||||
d: "M16,9c-0.7,0-1.37,0.1-2,0.29V5H2v12c0,1.1,0.9,2,2,2h5.68c1.12,2.36,3.53,4,6.32,4c3.87,0,7-3.13,7-7 C23,12.13,19.87,9,16,9z M16,21c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S18.76,21,16,21z",
|
|
||||||
}
|
|
||||||
polygon {
|
|
||||||
points: "16.5,12 15,12 15,17 18.6,19.1 19.4,17.9 16.5,16.2",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdError;
|
|
||||||
impl IconShape for MdError {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdErrorOutline;
|
|
||||||
impl IconShape for MdErrorOutline {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdNotificationImportant;
|
|
||||||
impl IconShape for MdNotificationImportant {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M18 16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2zm-5 0h-2v-2h2v2zm0-4h-2V8h2v4zm-1 10c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdWarning;
|
|
||||||
impl IconShape for MdWarning {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,818 +0,0 @@
|
|||||||
use super::super::IconShape;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdApproval;
|
|
||||||
impl IconShape for MdApproval {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M4 16v6h16v-6c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2zm14 2H6v-2h12v2zM12 2C9.24 2 7 4.24 7 7l5 7 5-7c0-2.76-2.24-5-5-5zm0 9L9 7c0-1.66 1.34-3 3-3s3 1.34 3 3l-3 4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdAttachEmail;
|
|
||||||
impl IconShape for MdAttachEmail {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M21,10V4c0-1.1-0.9-2-2-2H3C1.9,2,1.01,2.9,1.01,4L1,16c0,1.1,0.9,2,2,2h11v-5c0-1.66,1.34-3,3-3H21z M11,11L3,6V4l8,5 l8-5v2L11,11z",
|
|
||||||
}
|
|
||||||
path {
|
|
||||||
d: "M21,14v4c0,1.1-0.9,2-2,2s-2-0.9-2-2v-4.5c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5V18h2v-4.5c0-1.38-1.12-2.5-2.5-2.5 S15,12.12,15,13.5V18c0,2.21,1.79,4,4,4s4-1.79,4-4v-4H21z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdAttachment;
|
|
||||||
impl IconShape for MdAttachment {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloud;
|
|
||||||
impl IconShape for MdCloud {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudCircle;
|
|
||||||
impl IconShape for MdCloudCircle {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudDone;
|
|
||||||
impl IconShape for MdCloudDone {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudDownload;
|
|
||||||
impl IconShape for MdCloudDownload {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudOff;
|
|
||||||
impl IconShape for MdCloudOff {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudQueue;
|
|
||||||
impl IconShape for MdCloudQueue {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCloudUpload;
|
|
||||||
impl IconShape for MdCloudUpload {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCreateNewFolder;
|
|
||||||
impl IconShape for MdCreateNewFolder {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdDriveFileMove;
|
|
||||||
impl IconShape for MdDriveFileMove {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-6 12v-3h-4v-4h4V8l5 5-5 5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdDriveFileMoveOutline;
|
|
||||||
impl IconShape for MdDriveFileMoveOutline {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10zm-8.01-9l-1.41 1.41L12.16 12H8v2h4.16l-1.59 1.59L11.99 17 16 13.01 11.99 9z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdDriveFileRenameOutline;
|
|
||||||
impl IconShape for MdDriveFileRenameOutline {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M18.41 5.8L17.2 4.59c-.78-.78-2.05-.78-2.83 0l-2.68 2.68L3 15.96V20h4.04l8.74-8.74 2.63-2.63c.79-.78.79-2.05 0-2.83zM6.21 18H5v-1.21l8.66-8.66 1.21 1.21L6.21 18zM11 20l4-4h6v4H11z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdDriveFolderUpload;
|
|
||||||
impl IconShape for MdDriveFolderUpload {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10zM8 13.01l1.41 1.41L11 12.84V17h2v-4.16l1.59 1.59L16 13.01 12.01 9 8 13.01z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFileDownload;
|
|
||||||
impl IconShape for MdFileDownload {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFileDownloadDone;
|
|
||||||
impl IconShape for MdFileDownloadDone {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M5 18h14v2H5v-2zm4.6-2.7L5 10.7l2-1.9 2.6 2.6L17 4l2 2-9.4 9.3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFileUpload;
|
|
||||||
impl IconShape for MdFileUpload {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFolder;
|
|
||||||
impl IconShape for MdFolder {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFolderOpen;
|
|
||||||
impl IconShape for MdFolderOpen {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdFolderShared;
|
|
||||||
impl IconShape for MdFolderShared {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdGridView;
|
|
||||||
impl IconShape for MdGridView {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M0 0h24v24H0z",
|
|
||||||
}
|
|
||||||
path {
|
|
||||||
d: "M3 3v8h8V3H3zm6 6H5V5h4v4zm-6 4v8h8v-8H3zm6 6H5v-4h4v4zm4-16v8h8V3h-8zm6 6h-4V5h4v4zm-6 4v8h8v-8h-8zm6 6h-4v-4h4v4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdRequestQuote;
|
|
||||||
impl IconShape for MdRequestQuote {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M14,2H6C4.9,2,4.01,2.9,4.01,4L4,20c0,1.1,0.89,2,1.99,2H18c1.1,0,2-0.9,2-2V8L14,2z M15,12h-4v1h3c0.55,0,1,0.45,1,1v3 c0,0.55-0.45,1-1,1h-1v1h-2v-1H9v-2h4v-1h-3c-0.55,0-1-0.45-1-1v-3c0-0.55,0.45-1,1-1h1V9h2v1h2V12z M13,8V3.5L17.5,8H13z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdRuleFolder;
|
|
||||||
impl IconShape for MdRuleFolder {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M7.83,16L5,13.17 l1.41-1.41l1.41,1.41l3.54-3.54l1.41,1.41L7.83,16z M17.41,13L19,14.59L17.59,16L16,14.41L14.41,16L13,14.59L14.59,13L13,11.41 L14.41,10L16,11.59L17.59,10L19,11.41L17.41,13z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdSnippetFolder;
|
|
||||||
impl IconShape for MdSnippetFolder {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M15.88,10.5l1.62,1.62v3.38l-3,0v-5H15.88z M22,8v10c0,1.1-0.9,2-2,2H4c-1.1,0-2-0.9-2-2L2.01,6C2.01,4.9,2.9,4,4,4h6l2,2 h8C21.1,6,22,6.9,22,8z M19,11.5L16.5,9H13v8l6,0V11.5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdTextSnippet;
|
|
||||||
impl IconShape for MdTextSnippet {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20.41,8.41l-4.83-4.83C15.21,3.21,14.7,3,14.17,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V9.83 C21,9.3,20.79,8.79,20.41,8.41z M7,7h7v2H7V7z M17,17H7v-2h10V17z M17,13H7v-2h10V13z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdTopic;
|
|
||||||
impl IconShape for MdTopic {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M20,6h-8l-2-2H4C2.9,4,2.01,4.9,2.01,6L2,18c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M14,16H6v-2h8V16z M18,12H6v-2h12V12z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdUploadFile;
|
|
||||||
impl IconShape for MdUploadFile {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11zM8 15.01l1.41 1.41L11 14.84V19h2v-4.16l1.59 1.59L16 15.01 12.01 11z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdWorkspacesFilled;
|
|
||||||
impl IconShape for MdWorkspacesFilled {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdWorkspacesOutline;
|
|
||||||
impl IconShape for MdWorkspacesOutline {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M6 15c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0-2c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-8c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0-2C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 12c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0-2c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
|||||||
use super::super::IconShape;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdSensorDoor;
|
|
||||||
impl IconShape for MdSensorDoor {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M18,2H6C4.9,2,4,2.9,4,4v18h16V4C20,2.9,19.1,2,18,2z M15.5,13.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 S17,11.17,17,12S16.33,13.5,15.5,13.5z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdSensorWindow;
|
|
||||||
impl IconShape for MdSensorWindow {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M18,4v16H6V4H18 M18,2H6C4.9,2,4,2.9,4,4v16c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2L18,2z M7,19h10v-6H7 V19z M10,10h4v1h3V5H7v6h3V10z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,298 +0,0 @@
|
|||||||
use super::super::IconShape;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCheckBox;
|
|
||||||
impl IconShape for MdCheckBox {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdCheckBoxOutlineBlank;
|
|
||||||
impl IconShape for MdCheckBoxOutlineBlank {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdIndeterminateCheckBox;
|
|
||||||
impl IconShape for MdIndeterminateCheckBox {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M17,13H7v-2h10V13z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdRadioButtonChecked;
|
|
||||||
impl IconShape for MdRadioButtonChecked {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdRadioButtonUnchecked;
|
|
||||||
impl IconShape for MdRadioButtonUnchecked {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdStar;
|
|
||||||
impl IconShape for MdStar {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M0 0h24v24H0z",
|
|
||||||
}
|
|
||||||
path {
|
|
||||||
d: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdStarBorder;
|
|
||||||
impl IconShape for MdStarBorder {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdStarHalf;
|
|
||||||
impl IconShape for MdStarHalf {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M22,9.24l-7.19-0.62L12,2L9.19,8.63L2,9.24l5.46,4.73L5.82,21L12,17.27L18.18,21l-1.63-7.03L22,9.24z M12,15.4V6.1 l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28L12,15.4z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdStarOutline;
|
|
||||||
impl IconShape for MdStarOutline {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdToggleOff;
|
|
||||||
impl IconShape for MdToggleOff {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M17 7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h10c2.76 0 5-2.24 5-5s-2.24-5-5-5zM7 15c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct MdToggleOn;
|
|
||||||
impl IconShape for MdToggleOn {
|
|
||||||
fn view_box(&self) -> &str {
|
|
||||||
"0 0 24 24"
|
|
||||||
}
|
|
||||||
fn xmlns(&self) -> &str {
|
|
||||||
"http://www.w3.org/2000/svg"
|
|
||||||
}
|
|
||||||
fn fill_and_stroke<'a>(&self, user_color: &'a str) -> (&'a str, &'a str, &'a str) {
|
|
||||||
(user_color, "none", "0")
|
|
||||||
}
|
|
||||||
fn stroke_linecap(&self) -> &str {
|
|
||||||
"butt"
|
|
||||||
}
|
|
||||||
fn stroke_linejoin(&self) -> &str {
|
|
||||||
"miter"
|
|
||||||
}
|
|
||||||
fn child_elements(&self) -> Element {
|
|
||||||
rsx! {
|
|
||||||
path {
|
|
||||||
d: "M17 7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h10c2.76 0 5-2.24 5-5s-2.24-5-5-5zm0 8c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,27 +0,0 @@
|
|||||||
//! # dioxus-free-icons
|
|
||||||
//!
|
|
||||||
//! Use free svg icons in your Dioxus projects easily with dioxus-free-icons.
|
|
||||||
//! This library provides Icon component, which will generate SVG for a Font Awesome icon.
|
|
||||||
//!
|
|
||||||
//! Basic usage:
|
|
||||||
//! ```ignore
|
|
||||||
//! use dioxus::prelude::*;
|
|
||||||
//! use dioxus_free_icons::icons::fa_brands_icons::FaRust;
|
|
||||||
//! use dioxus_free_icons::Icon;
|
|
||||||
//!
|
|
||||||
//! fn RustIcon() -> Element {
|
|
||||||
//! rsx!(
|
|
||||||
//! Icon {
|
|
||||||
//! width: 30,
|
|
||||||
//! height: 30,
|
|
||||||
//! fill: "black",
|
|
||||||
//! icon: Icon::FaRust,
|
|
||||||
//! }
|
|
||||||
//! )
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
mod icon_component;
|
|
||||||
|
|
||||||
/// a collections of free icons
|
|
||||||
pub mod icons;
|
|
||||||
pub use crate::icon_component::{Icon, IconProps, IconShape};
|
|
||||||
@@ -2,5 +2,4 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
dockerfile: docker/prod/app/Dockerfile
|
|
||||||
target: builder_android
|
target: builder_android
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ services:
|
|||||||
- ./Cargo.toml:/srv/app/Cargo.toml
|
- ./Cargo.toml:/srv/app/Cargo.toml
|
||||||
- ./diesel.toml:/srv/app/diesel.toml
|
- ./diesel.toml:/srv/app/diesel.toml
|
||||||
- ./Dioxus.toml:/srv/app/Dioxus.toml
|
- ./Dioxus.toml:/srv/app/Dioxus.toml
|
||||||
- ./tailwind.css:/srv/app/tailwind.css
|
|
||||||
restart: always
|
restart: always
|
||||||
ports: ["8000:8000"]
|
ports: ["8000:8000"]
|
||||||
depends_on: ["db"]
|
depends_on: ["db"]
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- default
|
- default
|
||||||
- web-server-network
|
- web-server-network
|
||||||
ports: ["8000:80"]
|
|
||||||
restart: always
|
restart: always
|
||||||
depends_on: ["db"]
|
depends_on: ["db"]
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ RUN useradd -m -u 1000 -s /bin/bash app_user \
|
|||||||
|
|
||||||
USER app_user
|
USER app_user
|
||||||
|
|
||||||
RUN cargo install --git https://github.com/diesel-rs/diesel --rev 207604888d28a490061698f07a25090438be42fe --locked diesel_cli \
|
RUN cargo install --git https://github.com/diesel-rs/diesel --rev 2e85ba060d3d70ea605ea58a79b8a435749a7adc --locked diesel_cli \
|
||||||
&& cargo install --git https://github.com/DioxusLabs/dioxus --rev 22b06badde44ba1af0fcf339c91b66483175b660 --locked dioxus-cli
|
&& cargo install --git https://github.com/DioxusLabs/dioxus --rev 22b06badde44ba1af0fcf339c91b66483175b660 --locked dioxus-cli
|
||||||
|
|
||||||
COPY --chown=app_user . /srv/app
|
COPY --chown=app_user . /srv/app
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM rust:1.92.0-bookworm@sha256:9676d0547a259997add8f5924eb6b959c589ed39055338e23b99aba7958d6d31 AS builder_base
|
FROM rust:1.92.0-bookworm@sha256:9676d0547a259997add8f5924eb6b959c589ed39055338e23b99aba7958d6d31 AS builder_base
|
||||||
|
|
||||||
RUN cargo install --git https://github.com/diesel-rs/diesel --rev 207604888d28a490061698f07a25090438be42fe --locked diesel_cli \
|
RUN cargo install --git https://github.com/diesel-rs/diesel --rev 2e85ba060d3d70ea605ea58a79b8a435749a7adc --locked diesel_cli \
|
||||||
&& cargo install --git https://github.com/DioxusLabs/dioxus --rev 22b06badde44ba1af0fcf339c91b66483175b660 --locked dioxus-cli --features disable-telemetry
|
&& cargo install --git https://github.com/DioxusLabs/dioxus --rev 22b06badde44ba1af0fcf339c91b66483175b660 --locked dioxus-cli --features disable-telemetry
|
||||||
|
|
||||||
COPY . /srv/app
|
COPY . /srv/app
|
||||||
@@ -21,7 +21,7 @@ ENV ANDROID_SDK_ROOT=/opt/android-sdk
|
|||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
openjdk-17-jdk-headless=17.0.18+8-1~deb12u1 \
|
openjdk-17-jdk-headless=17.0.17+10-1~deb12u1 \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& rustup target add aarch64-linux-android \
|
&& rustup target add aarch64-linux-android \
|
||||||
@@ -39,7 +39,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& keytool -genkeypair -noprompt -keystore /tmp/android_keystore.jks -alias key -keyalg RSA -keysize 2048 -validity 3660 -dname "CN=" -storepass 123456 -keypass 123456 \
|
&& keytool -genkeypair -noprompt -keystore /tmp/android_keystore.jks -alias key -keyalg RSA -keysize 2048 -validity 3660 -dname "CN=" -storepass 123456 -keypass 123456 \
|
||||||
&& export ANDROID_HOME="$ANDROID_SDK_ROOT" \
|
&& export ANDROID_HOME="$ANDROID_SDK_ROOT" \
|
||||||
&& export ANDROID_NDK_HOME="$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION" \
|
&& export ANDROID_NDK_HOME="$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION" \
|
||||||
&& dx bundle --locked --platform android --target aarch64-linux-android --release \
|
&& dx bundle --platform android --target aarch64-linux-android --release \
|
||||||
&& java -jar /tmp/bundletool-all.jar build-apks --bundle=/srv/app/target/dx/todo_baggins/release/android/app/app/build/outputs/bundle/release/TodoBaggins-aarch64-linux-android.aab --output=/tmp/todo_baggins.apks --mode=universal --ks=/tmp/android_keystore.jks --ks-key-alias=key --ks-pass=pass:123456 \
|
&& java -jar /tmp/bundletool-all.jar build-apks --bundle=/srv/app/target/dx/todo_baggins/release/android/app/app/build/outputs/bundle/release/TodoBaggins-aarch64-linux-android.aab --output=/tmp/todo_baggins.apks --mode=universal --ks=/tmp/android_keystore.jks --ks-key-alias=key --ks-pass=pass:123456 \
|
||||||
&& mkdir -p /srv/app/bundle \
|
&& mkdir -p /srv/app/bundle \
|
||||||
&& unzip -qp /tmp/todo_baggins.apks universal.apk > /srv/app/bundle/todo_baggins.apk
|
&& unzip -qp /tmp/todo_baggins.apks universal.apk > /srv/app/bundle/todo_baggins.apk
|
||||||
@@ -47,7 +47,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
|
|
||||||
FROM builder_base AS builder_web
|
FROM builder_base AS builder_web
|
||||||
|
|
||||||
RUN dx bundle --locked --release
|
RUN dx bundle --release
|
||||||
|
|
||||||
|
|
||||||
FROM debian:bookworm@sha256:b877a1a3fdf02469440f1768cf69c9771338a875b7add5e80c45b756c92ac20a AS runner_web
|
FROM debian:bookworm@sha256:b877a1a3fdf02469440f1768cf69c9771338a875b7add5e80c45b756c92ac20a AS runner_web
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# About this branch
|
|
||||||
|
|
||||||
This branch is just about the changes made to Dioxus in my fork. It was also required to add dioxus-free-icons and dioxus-i18n with the Dioxus dependency edited to the fork. Once the changes from https://github.com/DioxusLabs/dioxus/pull/5248 get released, just set the dependency on the main branch to the released version and then it is safe to delete this branch.
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
use crate::internationalization::get_language_identifier;
|
use crate::internationalization::get_language_identifier;
|
||||||
|
|
||||||
use crate::route::Route;
|
use crate::route::Route;
|
||||||
use dioxus::core_macro::rsx;
|
use dioxus::core_macro::rsx;
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
@@ -8,15 +7,15 @@ use dioxus_i18n::prelude::*;
|
|||||||
use dioxus_i18n::unic_langid::langid;
|
use dioxus_i18n::unic_langid::langid;
|
||||||
|
|
||||||
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
||||||
|
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
|
||||||
#[used]
|
#[used]
|
||||||
static FONTS_DIRECTORY: Asset = asset!(
|
static FONTS_DIRECTORY: Asset = asset!(
|
||||||
"/assets/fonts",
|
"/assets/fonts",
|
||||||
AssetOptions::builder().with_hash_suffix(false)
|
AssetOptions::builder().with_hash_suffix(false)
|
||||||
);
|
);
|
||||||
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
|
const FONTS_CSS: Asset = asset!("/assets/styles/fonts.css");
|
||||||
const INPUT_NUMBER_ARROWS_CSS: Asset = asset!("/assets/styles/input_number_arrows.css");
|
const INPUT_NUMBER_ARROWS_CSS: Asset = asset!("/assets/styles/input_number_arrows.css");
|
||||||
const INPUT_RANGE_CSS: Asset = asset!("/assets/styles/input_range.css");
|
const INPUT_RANGE_CSS: Asset = asset!("/assets/styles/input_range.css");
|
||||||
const SELECT_ARROW_CSS: Asset = asset!("/assets/styles/select_arrow.css");
|
|
||||||
const MANIFEST: Asset = asset!("/assets/manifest.json");
|
const MANIFEST: Asset = asset!("/assets/manifest.json");
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
@@ -36,13 +35,14 @@ pub(crate) fn App() -> Element {
|
|||||||
rsx! {
|
rsx! {
|
||||||
document::Link { rel: "icon", href: FAVICON }
|
document::Link { rel: "icon", href: FAVICON }
|
||||||
document::Stylesheet { href: TAILWIND_CSS }
|
document::Stylesheet { href: TAILWIND_CSS }
|
||||||
|
document::Stylesheet { href: FONTS_CSS }
|
||||||
document::Stylesheet { href: INPUT_NUMBER_ARROWS_CSS }
|
document::Stylesheet { href: INPUT_NUMBER_ARROWS_CSS }
|
||||||
document::Stylesheet { href: INPUT_RANGE_CSS }
|
document::Stylesheet { href: INPUT_RANGE_CSS }
|
||||||
document::Stylesheet { href: SELECT_ARROW_CSS }
|
|
||||||
document::Link { rel: "manifest", href: MANIFEST, crossorigin: "use-credentials" }
|
document::Link { rel: "manifest", href: MANIFEST, crossorigin: "use-credentials" }
|
||||||
|
document::Script { src: "https://kit.fontawesome.com/3c1b409f8f.js" }
|
||||||
|
|
||||||
div {
|
div {
|
||||||
class: "min-h-screen py-4 flex flex-col text-gray-300 bg-gray-900",
|
class: "min-h-screen pt-4 pb-36 flex flex-col text-zinc-200 bg-zinc-800",
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,78 @@
|
|||||||
|
use crate::components::error_boundary_message::ErrorBoundaryMessage;
|
||||||
use crate::components::navigation::Navigation;
|
use crate::components::navigation::Navigation;
|
||||||
|
use crate::components::project_form::ProjectForm;
|
||||||
|
use crate::components::task_form::TaskForm;
|
||||||
|
use crate::models::project::Project;
|
||||||
|
use crate::models::task::Task;
|
||||||
|
use crate::route::Route;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn BottomPanel() -> Element {
|
pub(crate) fn BottomPanel(display_form: Signal<bool>) -> Element {
|
||||||
|
// A signal for delaying the application of styles.
|
||||||
|
#[allow(clippy::redundant_closure)]
|
||||||
|
let mut expanded = use_signal(|| display_form());
|
||||||
let navigation_expanded = use_signal(|| false);
|
let navigation_expanded = use_signal(|| false);
|
||||||
|
let current_route = use_route();
|
||||||
|
|
||||||
|
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
|
||||||
|
let mut task_being_edited = use_context::<Signal<Option<Task>>>();
|
||||||
|
|
||||||
|
use_effect(use_reactive(&display_form, move |display_form| {
|
||||||
|
if display_form() {
|
||||||
|
expanded.set(true);
|
||||||
|
} else {
|
||||||
|
spawn(async move {
|
||||||
|
// Necessary for a smooth – not instant – height transition.
|
||||||
|
#[cfg(not(feature = "server"))]
|
||||||
|
async_std::task::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
|
/* The check is necessary for the situation when the user expands the panel while
|
||||||
|
it is being closed. */
|
||||||
|
if !display_form() {
|
||||||
|
expanded.set(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: format!(
|
class: format!(
|
||||||
"flex flex-col pointer-events-auto bg-gray-800 transition-[height] duration-[500ms] ease-[cubic-bezier(0.79,0.14,0.15,0.86)] overflow-y-scroll {}",
|
"flex flex-col pointer-events-auto bg-zinc-700/50 rounded-t-xl border-t-zinc-600 border-t backdrop-blur drop-shadow-[0_-5px_10px_rgba(0,0,0,0.2)] transition-[height] duration-[500ms] ease-[cubic-bezier(0.79,0.14,0.15,0.86)] overflow-y-scroll {}",
|
||||||
if navigation_expanded() {
|
match (display_form(), current_route, navigation_expanded()) {
|
||||||
"h-[130px]"
|
(false, _, false) => "h-[66px]",
|
||||||
} else {
|
(false, _, true) => "h-[130px]",
|
||||||
"h-[66px]"
|
(true, Route::ProjectsPage, _) => "h-[130px]",
|
||||||
|
(true, _, _) => "h-[506px]",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
if expanded() {
|
||||||
|
ErrorBoundaryMessage {
|
||||||
|
match current_route {
|
||||||
|
Route::ProjectsPage => rsx! {
|
||||||
|
ProjectForm {
|
||||||
|
project: project_being_edited(),
|
||||||
|
on_successful_submit: move |_| {
|
||||||
|
display_form.set(false);
|
||||||
|
project_being_edited.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => rsx! {
|
||||||
|
TaskForm {
|
||||||
|
task: task_being_edited(),
|
||||||
|
on_successful_submit: move |_| {
|
||||||
|
display_form.set(false);
|
||||||
|
task_being_edited.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Navigation {
|
Navigation {
|
||||||
is_expanded: navigation_expanded,
|
expanded: navigation_expanded,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn ButtonPrimary(
|
|
||||||
class: Option<String>,
|
|
||||||
children: Element,
|
|
||||||
#[props(extends = GlobalAttributes, extends = button)] attributes: Vec<Attribute>,
|
|
||||||
// TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/4019 gets resolved.
|
|
||||||
onclick: Option<Callback<Event<MouseData>>>,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
button {
|
|
||||||
class: format!(
|
|
||||||
"cursor-pointer pb-[6px] hover:pb-[7px] active:pb-[2px] mt-[1px] hover:mt-0 active:mt-[5px] hover:*:drop-shadow-[0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted)] active:*:drop-shadow-[0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted)] transition-all duration-150 {}",
|
|
||||||
class.unwrap_or("".to_owned())
|
|
||||||
),
|
|
||||||
onclick: move |event| {
|
|
||||||
if let Some(onclick) = onclick {
|
|
||||||
onclick.call(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
..attributes,
|
|
||||||
div {
|
|
||||||
class: "py-3.5 px-4 flex flex-row justify-center items-center bg-amber-300-muted drop-shadow-[0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted)] text-amber-700-muted rounded-xl transition-all duration-150",
|
|
||||||
{children}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn ButtonSecondary(
|
|
||||||
class: Option<String>,
|
|
||||||
children: Element,
|
|
||||||
#[props(extends = GlobalAttributes, extends = button)] attributes: Vec<Attribute>,
|
|
||||||
// TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/4019 gets resolved.
|
|
||||||
onclick: Option<Callback<Event<MouseData>>>,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
button {
|
|
||||||
class: format!(
|
|
||||||
"cursor-pointer pb-[6px] hover:pb-[7px] active:pb-[2px] mt-[1px] hover:mt-0 active:mt-[5px] hover:*:drop-shadow-[0_7px_0_var(--color-gray-800)] active:*:drop-shadow-[0_2px_0_var(--color-gray-800)] transition-all duration-150 {}",
|
|
||||||
class.unwrap_or("".to_owned())
|
|
||||||
),
|
|
||||||
onclick: move |event| {
|
|
||||||
if let Some(onclick) = onclick {
|
|
||||||
onclick.call(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
..attributes,
|
|
||||||
div {
|
|
||||||
class: "py-3.5 px-4 flex flex-row justify-center items-center bg-gray-600 drop-shadow-[0_6px_0_var(--color-gray-800)] rounded-xl transition-all duration-150",
|
|
||||||
{children}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,12 +28,11 @@ pub(crate) fn CategoryCalendarTaskList() -> Element {
|
|||||||
div {
|
div {
|
||||||
class: "flex flex-col gap-4",
|
class: "flex flex-col gap-4",
|
||||||
div {
|
div {
|
||||||
class: "px-7 flex flex-row items-center gap-2 text-gray-500 font-bold",
|
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||||
div {
|
div {
|
||||||
class: "pt-1",
|
class: "pt-1",
|
||||||
{
|
{
|
||||||
date_current.format_localized(
|
date_current.format_localized(t!(
|
||||||
t!(
|
|
||||||
if date_current.year() == Local::now().year() {
|
if date_current.year() == Local::now().year() {
|
||||||
"date-weekday-format"
|
"date-weekday-format"
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
use crate::components::select_button::SelectButton;
|
|
||||||
use crate::models::category::Category;
|
use crate::models::category::Category;
|
||||||
use dioxus::core_macro::rsx;
|
use dioxus::core_macro::rsx;
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::icons::fa_regular_icons::FaLightbulb;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{
|
|
||||||
FaCalendarDays, FaHourglassHalf, FaInbox, FaSignsPost, FaWater,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn CategoryInput(
|
pub(crate) fn CategoryInput(
|
||||||
@@ -15,51 +10,93 @@ pub(crate) fn CategoryInput(
|
|||||||
) -> Element {
|
) -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: format!("grid grid-cols-3 gap-3 {}", class.unwrap_or("")),
|
class: format!("flex flex-row gap-2 {}", class.unwrap_or("")),
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaLightbulb,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::SomedayMaybe),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if selected_category() == Category::SomedayMaybe { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::SomedayMaybe);
|
selected_category.set(Category::SomedayMaybe);
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-question"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaWater,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::LongTerm),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if selected_category() == Category::LongTerm { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::LongTerm);
|
selected_category.set(Category::LongTerm);
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-water"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaHourglassHalf,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::WaitingFor(_)),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if let Category::WaitingFor(_) = selected_category() { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::WaitingFor(String::new()));
|
selected_category.set(Category::WaitingFor(String::new()));
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-hourglass-half"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaSignsPost,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::NextSteps),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if selected_category() == Category::NextSteps { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::NextSteps);
|
selected_category.set(Category::NextSteps);
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-forward"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaCalendarDays,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::Calendar { .. }),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if let Category::Calendar { .. } = selected_category() { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::Calendar {
|
selected_category.set(Category::Calendar {
|
||||||
date: chrono::Local::now().date_naive(),
|
date: chrono::Local::now().date_naive(),
|
||||||
reoccurrence: None,
|
reoccurrence: None,
|
||||||
time: None,
|
time: None,
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-calendar-days"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
SelectButton {
|
button {
|
||||||
icon: FaInbox,
|
r#type: "button",
|
||||||
is_selected: matches!(selected_category(), Category::Inbox),
|
class: format!(
|
||||||
on_select: move |_| {
|
"py-2 rounded-lg grow basis-0 {} cursor-pointer",
|
||||||
|
if selected_category() == Category::Inbox { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
selected_category.set(Category::Inbox);
|
selected_category.set(Category::Inbox);
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-inbox"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use crate::components::task_list::TaskList;
|
use crate::components::task_list::TaskList;
|
||||||
|
use crate::components::task_list_item::TaskListItem;
|
||||||
use crate::hooks::use_tasks_with_subtasks_in_category;
|
use crate::hooks::use_tasks_with_subtasks_in_category;
|
||||||
use crate::internationalization::LocaleFromLanguageIdentifier;
|
use crate::internationalization::LocaleFromLanguageIdentifier;
|
||||||
use crate::models::category::Category;
|
use crate::models::category::Category;
|
||||||
use crate::models::task::TaskWithSubtasks;
|
use crate::models::task::TaskWithSubtasks;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{FaCalendarCheck, FaCalendarXmark, FaWater};
|
|
||||||
use dioxus_i18n::t;
|
use dioxus_i18n::t;
|
||||||
use dioxus_i18n::use_i18n::i18n;
|
use dioxus_i18n::use_i18n::i18n;
|
||||||
use voca_rs::Voca;
|
use voca_rs::Voca;
|
||||||
@@ -46,21 +45,34 @@ pub(crate) fn CategoryTodayTaskList() -> Element {
|
|||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "pt-4 flex flex-col gap-8",
|
class: "pt-4 flex flex-col gap-8",
|
||||||
if !long_term_tasks.is_empty() {
|
|
||||||
div {
|
div {
|
||||||
class: "flex flex-col gap-4",
|
class: "flex flex-col gap-4",
|
||||||
div {
|
div {
|
||||||
class: "px-7 flex flex-row items-center gap-2 text-gray-500 font-bold",
|
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||||
Icon {
|
i {
|
||||||
class: "mx-1.5",
|
class: "fa-solid fa-water text-xl w-6 text-center"
|
||||||
icon: FaWater
|
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
|
class: "mt-1",
|
||||||
{t!("long-term")._upper_first()}
|
{t!("long-term")._upper_first()}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TaskList {
|
div {
|
||||||
tasks: long_term_tasks
|
for task in long_term_tasks {
|
||||||
|
div {
|
||||||
|
key: "{task.task.id}",
|
||||||
|
class: format!(
|
||||||
|
"px-8 pt-5 {} flex flex-row gap-4",
|
||||||
|
if task.task.deadline.is_some() {
|
||||||
|
"pb-0.5"
|
||||||
|
} else {
|
||||||
|
"pb-5"
|
||||||
|
}
|
||||||
|
),
|
||||||
|
TaskListItem {
|
||||||
|
task: task.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,14 +80,12 @@ pub(crate) fn CategoryTodayTaskList() -> Element {
|
|||||||
div {
|
div {
|
||||||
class: "flex flex-col gap-4",
|
class: "flex flex-col gap-4",
|
||||||
div {
|
div {
|
||||||
class: "px-7 flex flex-row items-center gap-2 text-gray-500 font-bold",
|
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||||
Icon {
|
i {
|
||||||
class: "mx-1.25",
|
class: "fa-solid fa-calendar-xmark text-xl w-6 text-center"
|
||||||
height: 22,
|
|
||||||
width: 22,
|
|
||||||
icon: FaCalendarXmark
|
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
|
class: "mt-1",
|
||||||
{t!("overdue")._upper_first()}
|
{t!("overdue")._upper_first()}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,14 +98,12 @@ pub(crate) fn CategoryTodayTaskList() -> Element {
|
|||||||
div {
|
div {
|
||||||
class: "flex flex-col gap-4",
|
class: "flex flex-col gap-4",
|
||||||
div {
|
div {
|
||||||
class: "px-7 flex flex-row items-center gap-2 text-gray-500 font-bold",
|
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||||
Icon {
|
i {
|
||||||
class: "mx-1.25",
|
class: "fa-solid fa-calendar-check text-xl w-6 text-center"
|
||||||
height: 22,
|
|
||||||
width: 22,
|
|
||||||
icon: FaCalendarCheck
|
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
|
class: "mt-1",
|
||||||
{
|
{
|
||||||
let format = t!("date-weekday-format");
|
let format = t!("date-weekday-format");
|
||||||
let today_date = today_date.format_localized(
|
let today_date = today_date.format_localized(
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
use crate::components::project_form::PROJECT_BEING_EDITED;
|
|
||||||
use crate::components::{button_primary::ButtonPrimary, task_form::TASK_BEING_EDITED};
|
|
||||||
use crate::route::Route;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::{Icon, icons::fa_solid_icons::FaGavel};
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn CreateButton() -> Element {
|
|
||||||
let navigator = use_navigator();
|
|
||||||
let current_route = use_route();
|
|
||||||
rsx! {
|
|
||||||
ButtonPrimary {
|
|
||||||
class: "pointer-events-auto m-4 self-end *:rounded-full! *:p-4",
|
|
||||||
onclick: move |_| {
|
|
||||||
*TASK_BEING_EDITED.write() = None;
|
|
||||||
*PROJECT_BEING_EDITED.write() = None;
|
|
||||||
navigator.push(
|
|
||||||
match current_route {
|
|
||||||
Route::ProjectsPage => Route::ProjectFormPage,
|
|
||||||
_ => Route::TaskFormPage,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
Icon {
|
|
||||||
icon: FaGavel,
|
|
||||||
height: 24,
|
|
||||||
width: 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
use dioxus::core_macro::rsx;
|
use dioxus::core_macro::rsx;
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::FaTriangleExclamation;
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn ErrorBoundaryMessage(children: Element, class: Option<String>) -> Element {
|
pub(crate) fn ErrorBoundaryMessage(children: Element, class: Option<String>) -> Element {
|
||||||
@@ -13,11 +11,8 @@ pub(crate) fn ErrorBoundaryMessage(children: Element, class: Option<String>) ->
|
|||||||
div {
|
div {
|
||||||
class: "grow flex flex-col justify-center items-center",
|
class: "grow flex flex-col justify-center items-center",
|
||||||
div {
|
div {
|
||||||
Icon {
|
i {
|
||||||
class: "text-gray-500",
|
class: "text-3xl fa-solid fa-triangle-exclamation"
|
||||||
icon: FaTriangleExclamation,
|
|
||||||
height: 32,
|
|
||||||
width: 32
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/components/form_open_button.rs
Normal file
25
src/components/form_open_button.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use crate::models::project::Project;
|
||||||
|
use crate::models::task::Task;
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub(crate) fn FormOpenButton(opened: Signal<bool>) -> Element {
|
||||||
|
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
|
||||||
|
let mut task_being_edited = use_context::<Signal<Option<Task>>>();
|
||||||
|
|
||||||
|
rsx! {
|
||||||
|
button {
|
||||||
|
class: "pointer-events-auto m-4 py-3 px-5 self-end text-center bg-zinc-300/50 rounded-xl border-t-zinc-200 border-t backdrop-blur drop-shadow-[0_-5px_10px_rgba(0,0,0,0.2)] text-2xl text-zinc-200 cursor-pointer",
|
||||||
|
onclick: move |_| {
|
||||||
|
if opened() {
|
||||||
|
project_being_edited.set(None);
|
||||||
|
task_being_edited.set(None);
|
||||||
|
}
|
||||||
|
opened.set(!opened());
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: format!("min-w-6 fa-solid {}", if opened() { "fa-xmark" } else { "fa-plus" }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn Input(
|
|
||||||
class: Option<String>,
|
|
||||||
name: String,
|
|
||||||
r#type: String,
|
|
||||||
id: Option<String>,
|
|
||||||
#[props(extends = GlobalAttributes, extends = input)] attributes: Vec<Attribute>,
|
|
||||||
// TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/5271 gets resolved.
|
|
||||||
autofocus: Option<bool>,
|
|
||||||
// TODO: Remove this once https://github.com/DioxusLabs/dioxus/issues/4019 gets resolved.
|
|
||||||
oninput: Option<Callback<Event<FormData>>>,
|
|
||||||
onchange: Option<Callback<Event<FormData>>>,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
input {
|
|
||||||
class: format!(
|
|
||||||
/* `w-full` is required for the Chromium renderer to allow the input to shrink
|
|
||||||
properly. */
|
|
||||||
"pt-3 pb-2.25 w-full {} bg-gray-800-muted enabled:hover:bg-gray-800 enabled:focus:bg-gray-800 drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-900-muted)] rounded-xl outline-0 {} transition-all duration-150 {}",
|
|
||||||
match r#type.as_str() {
|
|
||||||
"date" => "ps-3.25 pe-3",
|
|
||||||
_ => "px-4"
|
|
||||||
},
|
|
||||||
match r#type.as_str() {
|
|
||||||
"text" | "number" => "",
|
|
||||||
_ => "enabled:cursor-pointer"
|
|
||||||
},
|
|
||||||
class.unwrap_or("".to_owned())
|
|
||||||
),
|
|
||||||
name: name.clone(),
|
|
||||||
r#type,
|
|
||||||
id: id.unwrap_or(format!("input_{}", name)),
|
|
||||||
autofocus,
|
|
||||||
oninput: move |event| {
|
|
||||||
if let Some(oninput) = oninput {
|
|
||||||
oninput.call(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onchange: move |event| {
|
|
||||||
if let Some(onchange) = oninput {
|
|
||||||
onchange.call(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
..attributes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::{Icon, IconShape};
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn InputLabel<I: IconShape + Clone + PartialEq + 'static>(
|
|
||||||
icon: I,
|
|
||||||
r#for: Option<String>,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
label {
|
|
||||||
r#for,
|
|
||||||
class: "mt-0.5 min-w-7 flex flex-row justify-center items-center",
|
|
||||||
Icon {
|
|
||||||
class: "text-gray-600",
|
|
||||||
icon,
|
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,16 @@
|
|||||||
pub(crate) mod app;
|
pub(crate) mod app;
|
||||||
pub(crate) mod bottom_panel;
|
pub(crate) mod bottom_panel;
|
||||||
pub(crate) mod button_primary;
|
|
||||||
pub(crate) mod button_secondary;
|
|
||||||
pub(crate) mod category_calendar_task_list;
|
pub(crate) mod category_calendar_task_list;
|
||||||
pub(crate) mod category_input;
|
pub(crate) mod category_input;
|
||||||
pub(crate) mod category_today_task_list;
|
pub(crate) mod category_today_task_list;
|
||||||
pub(crate) mod create_button;
|
|
||||||
pub(crate) mod error_boundary_message;
|
pub(crate) mod error_boundary_message;
|
||||||
pub(crate) mod input;
|
pub(crate) mod form_open_button;
|
||||||
pub(crate) mod input_label;
|
|
||||||
pub(crate) mod navigation;
|
pub(crate) mod navigation;
|
||||||
pub(crate) mod navigation_item;
|
pub(crate) mod navigation_item;
|
||||||
pub(crate) mod project_form;
|
pub(crate) mod project_form;
|
||||||
pub(crate) mod project_list;
|
pub(crate) mod project_list;
|
||||||
pub(crate) mod project_select;
|
pub(crate) mod project_select;
|
||||||
pub(crate) mod reoccurrence_interval_input;
|
pub(crate) mod reoccurrence_input;
|
||||||
pub(crate) mod select_button;
|
|
||||||
pub(crate) mod sticky_bottom;
|
pub(crate) mod sticky_bottom;
|
||||||
pub(crate) mod subtasks_form;
|
pub(crate) mod subtasks_form;
|
||||||
pub(crate) mod task_form;
|
pub(crate) mod task_form;
|
||||||
|
|||||||
@@ -1,72 +1,78 @@
|
|||||||
use crate::components::navigation_item::NavigationItem;
|
use crate::components::navigation_item::NavigationItem;
|
||||||
use crate::route::Route;
|
use crate::route::Route;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_regular_icons::FaLightbulb;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{
|
|
||||||
FaBars, FaCalendarDay, FaCalendarDays, FaHourglassHalf, FaInbox, FaList, FaSignsPost,
|
|
||||||
FaTrashCan, FaVolcano,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn Navigation(is_expanded: Signal<bool>) -> Element {
|
pub(crate) fn Navigation(expanded: Signal<bool>) -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "grid grid-cols-5 justify-stretch",
|
class: "grid grid-cols-5 justify-stretch",
|
||||||
button {
|
button {
|
||||||
class: format!(
|
class: format!(
|
||||||
"py-2 flex flex-row justify-center items-center cursor-pointer",
|
"py-4 text-center text-2xl {} cursor-pointer",
|
||||||
|
if expanded() { "text-zinc-200" }
|
||||||
|
else { "text-zinc-500" }
|
||||||
),
|
),
|
||||||
onclick: move |_| is_expanded.set(!is_expanded()),
|
onclick: move |_| expanded.set(!expanded()),
|
||||||
div {
|
i {
|
||||||
class: format!("pt-2.5 px-4 {} transition-all duration-150",
|
class: "fa-solid fa-bars"
|
||||||
if is_expanded() { "pb-2 mt-1 bg-gray-900 text-gray-400 rounded-xl drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-950)]" }
|
|
||||||
else { "pb-3 bg-gray-800 rounded-xl drop-shadow-[0_0_0_var(--color-gray-950)] text-gray-600" }
|
|
||||||
),
|
|
||||||
Icon {
|
|
||||||
icon: FaBars,
|
|
||||||
height: 24,
|
|
||||||
width: 24
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryNextStepsPage,
|
route: Route::CategoryNextStepsPage,
|
||||||
icon: FaSignsPost
|
i {
|
||||||
|
class: "fa-solid fa-forward"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryCalendarPage,
|
route: Route::CategoryCalendarPage,
|
||||||
icon: FaCalendarDays
|
i {
|
||||||
|
class: "fa-solid fa-calendar-days"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryTodayPage,
|
route: Route::CategoryTodayPage,
|
||||||
icon: FaCalendarDay
|
i {
|
||||||
|
class: "fa-solid fa-calendar-day"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryInboxPage,
|
route: Route::CategoryInboxPage,
|
||||||
icon: FaInbox
|
i {
|
||||||
|
class: "fa-solid fa-inbox"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{if is_expanded() {
|
{if expanded() {
|
||||||
rsx! {
|
rsx! {
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::ProjectsPage,
|
route: Route::ProjectsPage,
|
||||||
icon: FaList
|
i {
|
||||||
|
class: "fa-solid fa-list"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryTrashPage,
|
route: Route::CategoryTrashPage,
|
||||||
icon: FaTrashCan
|
i {
|
||||||
|
class: "fa-solid fa-trash-can"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryDonePage,
|
route: Route::CategoryDonePage,
|
||||||
icon: FaVolcano
|
i {
|
||||||
|
class: "fa-solid fa-check"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategorySomedayMaybePage,
|
route: Route::CategoryLongTermPage,
|
||||||
icon: FaLightbulb
|
i {
|
||||||
|
class: "fa-solid fa-water"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NavigationItem {
|
NavigationItem {
|
||||||
route: Route::CategoryWaitingForPage,
|
route: Route::CategoryWaitingForPage,
|
||||||
icon: FaHourglassHalf
|
i {
|
||||||
|
class: "fa-solid fa-hourglass-half"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { VNode::empty() }}
|
} else { VNode::empty() }}
|
||||||
|
|||||||
@@ -1,31 +1,19 @@
|
|||||||
use crate::route::Route;
|
use crate::route::Route;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::{Icon, IconShape};
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn NavigationItem<I: IconShape + Clone + PartialEq + 'static>(
|
pub(crate) fn NavigationItem(route: Route, children: Element) -> Element {
|
||||||
route: Route,
|
|
||||||
icon: I,
|
|
||||||
) -> Element {
|
|
||||||
let current_route = use_route::<Route>();
|
let current_route = use_route::<Route>();
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
Link {
|
Link {
|
||||||
to: route.clone(),
|
to: route.clone(),
|
||||||
class: format!(
|
class: format!(
|
||||||
"py-2.5 flex flex-row justify-center items-center hover:*:bg-gray-900 active:*:text-gray-400",
|
"py-4 text-center text-2xl {}",
|
||||||
|
if current_route == route { "text-zinc-200" }
|
||||||
|
else { "text-zinc-500" }
|
||||||
),
|
),
|
||||||
div {
|
children
|
||||||
class: format!("pt-2.5 px-4 {} transition-all duration-150",
|
|
||||||
if current_route == route { "pb-2 mt-1 bg-gray-900 text-gray-400 rounded-xl drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-950)]" }
|
|
||||||
else { "pb-3 bg-gray-800 rounded-xl drop-shadow-[0_0_0_var(--color-gray-950)] text-gray-600" }
|
|
||||||
),
|
|
||||||
Icon {
|
|
||||||
icon,
|
|
||||||
height: 24,
|
|
||||||
width: 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,113 +1,73 @@
|
|||||||
use crate::components::button_primary::ButtonPrimary;
|
|
||||||
use crate::components::button_secondary::ButtonSecondary;
|
|
||||||
use crate::components::input::Input;
|
|
||||||
use crate::components::input_label::InputLabel;
|
|
||||||
use crate::models::project::Project;
|
use crate::models::project::Project;
|
||||||
use crate::server::projects::{create_project, delete_project, edit_project};
|
use crate::server::projects::{create_project, delete_project, edit_project};
|
||||||
use dioxus::core_macro::{component, rsx};
|
use dioxus::core_macro::{component, rsx};
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{FaFeatherPointed, FaStamp, FaTrashCan, FaXmark};
|
|
||||||
|
|
||||||
pub(crate) static PROJECT_BEING_EDITED: GlobalSignal<Option<Project>> = Signal::global(|| None);
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn ProjectForm() -> Element {
|
pub(crate) fn ProjectForm(
|
||||||
let navigator = use_navigator();
|
project: Option<Project>,
|
||||||
let project = PROJECT_BEING_EDITED();
|
on_successful_submit: EventHandler<()>,
|
||||||
|
) -> Element {
|
||||||
let project_for_submit = project.clone();
|
let project_for_submit = project.clone();
|
||||||
rsx! {
|
rsx! {
|
||||||
form {
|
form {
|
||||||
class: "px-4 flex flex-col gap-4",
|
|
||||||
onsubmit: move |event| {
|
onsubmit: move |event| {
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
let project = project_for_submit.clone();
|
let project = project_for_submit.clone();
|
||||||
async move {
|
async move {
|
||||||
let new_project = event.parsed_values().unwrap();
|
let new_project = event.parsed_values().unwrap();
|
||||||
let result = if let Some(project) = project {
|
if let Some(project) = project {
|
||||||
edit_project(project.id, new_project).await
|
let _ = edit_project(project.id, new_project).await;
|
||||||
} else {
|
} else {
|
||||||
create_project(new_project).await
|
let _ = create_project(new_project).await;
|
||||||
};
|
|
||||||
if result.is_ok() {
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
}
|
||||||
|
on_successful_submit.call(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
id: "form_project",
|
class: "p-4 flex flex-col gap-4",
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaFeatherPointed,
|
r#for: "input_title",
|
||||||
r#for: "input_title"
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-pen-clip text-zinc-400/50"
|
||||||
}
|
}
|
||||||
Input {
|
}
|
||||||
class: "grow",
|
input {
|
||||||
name: "title",
|
name: "title",
|
||||||
required: true,
|
required: true,
|
||||||
r#type: "text",
|
|
||||||
initial_value: project.as_ref().map(|project| project.title.to_owned()),
|
initial_value: project.as_ref().map(|project| project.title.to_owned()),
|
||||||
}
|
r#type: "text",
|
||||||
|
class: "py-2 px-3 grow bg-zinc-800/50 rounded-lg",
|
||||||
|
id: "input_title"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class: "px-4 grid grid-cols-3 gap-3 mt-auto",
|
class: "flex flex-row justify-between mt-auto",
|
||||||
ButtonSecondary {
|
button {
|
||||||
r#type: "button",
|
r#type: "button",
|
||||||
class: "grow",
|
class: "py-2 px-4 bg-zinc-300/50 rounded-lg cursor-pointer",
|
||||||
onclick: {
|
onclick: move |_| {
|
||||||
let project = project.clone();
|
|
||||||
move |_| {
|
|
||||||
let project = project.clone();
|
let project = project.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Some(project) = project {
|
if let Some(project) = project {
|
||||||
let result = delete_project(project.id).await;
|
let _ = delete_project(project.id).await;
|
||||||
if result.is_ok() {
|
|
||||||
/* TODO: Might not work on mobile due to
|
|
||||||
https://dioxuslabs.com/learn/0.7/essentials/router/navigation#history-buttons.
|
|
||||||
*/
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
on_successful_submit.call(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Icon {
|
i {
|
||||||
icon: FaTrashCan,
|
class: "fa-solid fa-trash-can"
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if project.is_some() {
|
button {
|
||||||
div {
|
|
||||||
class: "grow flex flex-col items-stretch",
|
|
||||||
GoBackButton {
|
|
||||||
ButtonSecondary {
|
|
||||||
/* TODO: Replace w-full` with proper flexbox styling once
|
|
||||||
https://github.com/DioxusLabs/dioxus/issues/5269 is solved. */
|
|
||||||
class: "w-full",
|
|
||||||
r#type: "button",
|
|
||||||
Icon {
|
|
||||||
icon: FaXmark,
|
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
div {}
|
|
||||||
}
|
|
||||||
ButtonPrimary {
|
|
||||||
form: "form_project",
|
|
||||||
r#type: "submit",
|
r#type: "submit",
|
||||||
Icon {
|
class: "py-2 px-4 bg-zinc-300/50 rounded-lg cursor-pointer",
|
||||||
icon: FaStamp,
|
i {
|
||||||
height: 16,
|
class: "fa-solid fa-floppy-disk"
|
||||||
width: 16
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
use crate::route::Route;
|
use crate::{hooks::use_projects, models::project::Project};
|
||||||
use crate::{components::project_form::PROJECT_BEING_EDITED, hooks::use_projects};
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn ProjectList() -> Element {
|
pub(crate) fn ProjectList() -> Element {
|
||||||
let navigator = use_navigator();
|
|
||||||
let projects = use_projects()?;
|
let projects = use_projects()?;
|
||||||
|
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-col",
|
class: "flex flex-col",
|
||||||
for project in projects {
|
for project in projects {
|
||||||
div {
|
div {
|
||||||
class: "px-7 py-4 hover:bg-gray-800 font-medium text-pretty wrap-anywhere select-none transition-all duration-150 cursor-pointer",
|
|
||||||
key: "{project.id}",
|
key: "{project.id}",
|
||||||
onclick: move |_| {
|
class: format!(
|
||||||
*PROJECT_BEING_EDITED.write() = Some(project.clone());
|
"px-8 py-4 select-none {}",
|
||||||
navigator.push(Route::ProjectFormPage);
|
if project_being_edited().is_some_and(|p| p.id == project.id) {
|
||||||
},
|
"bg-zinc-700"
|
||||||
|
} else { "" }
|
||||||
|
),
|
||||||
|
onclick: move |_| project_being_edited.set(Some(project.clone())),
|
||||||
{project.title.clone()}
|
{project.title.clone()}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ pub(crate) fn ProjectSelect(initial_selected_id: Option<i32>) -> Element {
|
|||||||
rsx! {
|
rsx! {
|
||||||
select {
|
select {
|
||||||
name: "project_id",
|
name: "project_id",
|
||||||
class: "px-4 pt-3 pb-2.25 bg-gray-800-muted enabled:hover:bg-gray-800 enabled:active:bg-gray-800 drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-900-muted)] rounded-xl grow cursor-pointer",
|
class: "px-3.5 py-2.5 bg-zinc-800/50 rounded-lg grow cursor-pointer",
|
||||||
id: "input_project_id",
|
id: "input_project",
|
||||||
option {
|
option {
|
||||||
value: 0,
|
value: 0,
|
||||||
{t!("none")}
|
{t!("none")}
|
||||||
|
|||||||
76
src/components/reoccurrence_input.rs
Normal file
76
src/components/reoccurrence_input.rs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
use crate::models::category::ReoccurrenceInterval;
|
||||||
|
use dioxus::core_macro::rsx;
|
||||||
|
use dioxus::dioxus_core::Element;
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub(crate) fn ReoccurrenceIntervalInput(
|
||||||
|
reoccurrence_interval: Signal<Option<ReoccurrenceInterval>>,
|
||||||
|
class_buttons: Option<&'static str>,
|
||||||
|
) -> Element {
|
||||||
|
rsx! {
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
class: format!(
|
||||||
|
"py-2 rounded-lg {} {} cursor-pointer",
|
||||||
|
class_buttons.unwrap_or(""),
|
||||||
|
if reoccurrence_interval().is_none() { "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
|
reoccurrence_interval.set(None);
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-ban"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
class: format!(
|
||||||
|
"py-2 rounded-lg {} {} cursor-pointer",
|
||||||
|
class_buttons.unwrap_or(""),
|
||||||
|
if let Some(ReoccurrenceInterval::Day) = reoccurrence_interval()
|
||||||
|
{ "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
|
reoccurrence_interval.set(Some(ReoccurrenceInterval::Day))
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-sun"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
class: format!(
|
||||||
|
"py-2 rounded-lg {} {} cursor-pointer",
|
||||||
|
class_buttons.unwrap_or(""),
|
||||||
|
if let Some(ReoccurrenceInterval::Month) = reoccurrence_interval()
|
||||||
|
{ "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
|
reoccurrence_interval.set(Some(ReoccurrenceInterval::Month))
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-moon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
class: format!(
|
||||||
|
"py-2 rounded-lg {} {} cursor-pointer",
|
||||||
|
class_buttons.unwrap_or(""),
|
||||||
|
if let Some(ReoccurrenceInterval::Year) = reoccurrence_interval()
|
||||||
|
{ "bg-zinc-500/50" }
|
||||||
|
else { "bg-zinc-800/50" }
|
||||||
|
),
|
||||||
|
onclick: move |_| {
|
||||||
|
reoccurrence_interval.set(Some(ReoccurrenceInterval::Year))
|
||||||
|
},
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-earth-europe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
use crate::components::select_button::SelectButton;
|
|
||||||
use crate::models::category::ReoccurrenceInterval;
|
|
||||||
use dioxus::core_macro::rsx;
|
|
||||||
use dioxus::dioxus_core::Element;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{FaBan, FaEarthEurope, FaMoon, FaSun};
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn ReoccurrenceIntervalInput(
|
|
||||||
reoccurrence_interval: Signal<Option<ReoccurrenceInterval>>,
|
|
||||||
class_buttons: Option<&'static str>,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
// TODO: Abstract into SelectButton. Make it sank into the surface by default, like other inputs (abstract those too haha), and rise it up on selection (rationale: it will influence what is on the surface).
|
|
||||||
SelectButton {
|
|
||||||
icon: FaBan,
|
|
||||||
is_selected: reoccurrence_interval().is_none(),
|
|
||||||
on_select: move |_| {
|
|
||||||
reoccurrence_interval.set(None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SelectButton {
|
|
||||||
icon: FaSun,
|
|
||||||
is_selected: matches!(reoccurrence_interval(), Some(ReoccurrenceInterval::Day)),
|
|
||||||
on_select: move |_| {
|
|
||||||
reoccurrence_interval.set(Some(ReoccurrenceInterval::Day))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SelectButton {
|
|
||||||
icon: FaMoon,
|
|
||||||
is_selected: matches!(reoccurrence_interval(), Some(ReoccurrenceInterval::Month)),
|
|
||||||
on_select: move |_| {
|
|
||||||
reoccurrence_interval.set(Some(ReoccurrenceInterval::Month));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SelectButton {
|
|
||||||
icon: FaEarthEurope,
|
|
||||||
is_selected: matches!(reoccurrence_interval(), Some(ReoccurrenceInterval::Year)),
|
|
||||||
on_select: move |_| {
|
|
||||||
reoccurrence_interval.set(Some(ReoccurrenceInterval::Year));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::{Icon, IconShape};
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn SelectButton<I: IconShape + Clone + PartialEq + 'static>(
|
|
||||||
icon: I,
|
|
||||||
is_selected: bool,
|
|
||||||
on_select: Callback,
|
|
||||||
) -> Element {
|
|
||||||
rsx! {
|
|
||||||
button {
|
|
||||||
r#type: "button",
|
|
||||||
class: format!(
|
|
||||||
"pt-4.5 flex flex-row justify-center items-center {} rounded-xl transition-all duration-150",
|
|
||||||
if is_selected { "pb-3.75 bg-gray-900 drop-shadow-[0_0_0_var(--color-gray-900-muted)]" }
|
|
||||||
else { "pb-2.75 mt-1 bg-gray-800-muted hover:bg-gray-800 drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-900-muted)] text-gray-400 cursor-pointer" }
|
|
||||||
),
|
|
||||||
onclick: move |_| {
|
|
||||||
on_select.call(());
|
|
||||||
},
|
|
||||||
Icon {
|
|
||||||
icon,
|
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
use crate::components::button_secondary::ButtonSecondary;
|
|
||||||
use crate::components::input::Input;
|
|
||||||
use crate::components::input_label::InputLabel;
|
|
||||||
use crate::hooks::use_subtasks_of_task;
|
use crate::hooks::use_subtasks_of_task;
|
||||||
use crate::models::subtask::NewSubtask;
|
use crate::models::subtask::NewSubtask;
|
||||||
use crate::models::task::Task;
|
use crate::models::task::Task;
|
||||||
@@ -8,16 +5,12 @@ use crate::server::subtasks::{create_subtask, delete_subtask, edit_subtask};
|
|||||||
use dioxus::core_macro::{component, rsx};
|
use dioxus::core_macro::{component, rsx};
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{FaGavel, FaListCheck, FaTrashCan};
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn SubtasksForm(task: Task) -> Element {
|
pub(crate) fn SubtasksForm(task: Task) -> Element {
|
||||||
let subtasks = use_subtasks_of_task(task.id)?;
|
let subtasks = use_subtasks_of_task(task.id)?;
|
||||||
let mut new_title = use_signal(String::new);
|
let mut new_title = use_signal(String::new);
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
|
||||||
class: "flex flex-col gap-3",
|
|
||||||
form {
|
form {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
onsubmit: move |event| {
|
onsubmit: move |event| {
|
||||||
@@ -26,7 +19,7 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
async move {
|
async move {
|
||||||
let new_subtask = NewSubtask {
|
let new_subtask = NewSubtask {
|
||||||
task_id: task.id,
|
task_id: task.id,
|
||||||
title: event.get("new_title").first().cloned().and_then(|value| match value {
|
title: event.get("title").first().cloned().and_then(|value| match value {
|
||||||
FormValue::Text(value) => Some(value),
|
FormValue::Text(value) => Some(value),
|
||||||
FormValue::File(_) => None
|
FormValue::File(_) => None
|
||||||
}).unwrap(),
|
}).unwrap(),
|
||||||
@@ -36,26 +29,29 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
new_title.set(String::new());
|
new_title.set(String::new());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaListCheck,
|
r#for: "input_new_title",
|
||||||
r#for: "input_new_title"
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-list-check text-zinc-400/50"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class: "grow flex flex-row items-end gap-3",
|
class: "grow grid grid-cols-6 gap-2",
|
||||||
Input {
|
input {
|
||||||
class: "grow",
|
name: "title",
|
||||||
name: "new_title",
|
|
||||||
r#type: "text",
|
|
||||||
required: true,
|
required: true,
|
||||||
value: new_title,
|
value: new_title,
|
||||||
onchange: move |event: Event<FormData>| new_title.set(event.value())
|
r#type: "text",
|
||||||
|
class: "grow py-2 px-3 col-span-5 bg-zinc-800/50 rounded-lg",
|
||||||
|
id: "input_new_title",
|
||||||
|
onchange: move |event| new_title.set(event.value())
|
||||||
}
|
}
|
||||||
ButtonSecondary {
|
button {
|
||||||
r#type: "submit",
|
r#type: "submit",
|
||||||
Icon {
|
class: "py-2 col-span-1 bg-zinc-800/50 rounded-lg",
|
||||||
icon: FaGavel,
|
i {
|
||||||
height: 16,
|
class: "fa-solid fa-plus"
|
||||||
width: 16
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,8 +60,15 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
div {
|
div {
|
||||||
key: "{subtask.id}",
|
key: "{subtask.id}",
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
button {
|
i {
|
||||||
class: "mt-1.5 hover:mt-1 hover:pb-0.5 min-w-7 cursor-pointer transition-all duration-150",
|
class: format!(
|
||||||
|
"{} min-w-6 text-center text-2xl text-zinc-400/50",
|
||||||
|
if subtask.is_completed {
|
||||||
|
"fa solid fa-square-check"
|
||||||
|
} else {
|
||||||
|
"fa-regular fa-square"
|
||||||
|
}
|
||||||
|
),
|
||||||
onclick: {
|
onclick: {
|
||||||
let subtask = subtask.clone();
|
let subtask = subtask.clone();
|
||||||
move |_| {
|
move |_| {
|
||||||
@@ -82,19 +85,14 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
div {
|
|
||||||
class: format!("grow h-7 w-7 mb-[4px] drop-shadow-[0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800),0_1px_0_var(--color-gray-800)] rounded-full {}",
|
|
||||||
if subtask.is_completed {"bg-gray-600"} else {"border-3 border-gray-600"}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class: "grow flex flex-row items-end gap-3",
|
class: "grow grid grid-cols-6 gap-2",
|
||||||
Input {
|
input {
|
||||||
class: "grow",
|
|
||||||
name: "title_edit_{subtask.id}",
|
|
||||||
r#type: "text",
|
r#type: "text",
|
||||||
|
class: "grow py-2 px-3 col-span-5 bg-zinc-800/50 rounded-lg",
|
||||||
|
id: "input_title_{subtask.id}",
|
||||||
initial_value: subtask.title.clone(),
|
initial_value: subtask.title.clone(),
|
||||||
onchange: {
|
onchange: {
|
||||||
let subtask = subtask.clone();
|
let subtask = subtask.clone();
|
||||||
@@ -118,8 +116,9 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ButtonSecondary {
|
button {
|
||||||
r#type: "button",
|
r#type: "button",
|
||||||
|
class: "py-2 col-span-1 bg-zinc-800/50 rounded-lg",
|
||||||
onclick: {
|
onclick: {
|
||||||
let subtask = subtask.clone();
|
let subtask = subtask.clone();
|
||||||
move |_| {
|
move |_| {
|
||||||
@@ -129,11 +128,8 @@ pub(crate) fn SubtasksForm(task: Task) -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Icon {
|
i {
|
||||||
icon: FaTrashCan,
|
class: "fa-solid fa-trash-can"
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,16 @@
|
|||||||
use crate::components::button_primary::ButtonPrimary;
|
|
||||||
use crate::components::button_secondary::ButtonSecondary;
|
|
||||||
use crate::components::category_input::CategoryInput;
|
use crate::components::category_input::CategoryInput;
|
||||||
use crate::components::input::Input;
|
|
||||||
use crate::components::input_label::InputLabel;
|
|
||||||
use crate::components::project_select::ProjectSelect;
|
use crate::components::project_select::ProjectSelect;
|
||||||
use crate::components::reoccurrence_interval_input::ReoccurrenceIntervalInput;
|
use crate::components::reoccurrence_input::ReoccurrenceIntervalInput;
|
||||||
use crate::components::subtasks_form::SubtasksForm;
|
use crate::components::subtasks_form::SubtasksForm;
|
||||||
use crate::models::category::{CalendarTime, Category, Reoccurrence};
|
use crate::models::category::{CalendarTime, Category, Reoccurrence};
|
||||||
use crate::models::task::NewTask;
|
use crate::models::task::NewTask;
|
||||||
use crate::models::task::Task;
|
use crate::models::task::Task;
|
||||||
|
use crate::route::Route;
|
||||||
use crate::server::tasks::{create_task, delete_task, edit_task};
|
use crate::server::tasks::{create_task, delete_task, edit_task};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use dioxus::core_macro::{component, rsx};
|
use dioxus::core_macro::{component, rsx};
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{
|
|
||||||
FaBell, FaBomb, FaClock, FaFeatherPointed, FaHourglassEnd, FaList, FaRepeat, FaScroll, FaStamp,
|
|
||||||
FaTrashCan, FaXmark,
|
|
||||||
};
|
|
||||||
use dioxus_i18n::t;
|
use dioxus_i18n::t;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -54,19 +46,25 @@ struct InputData {
|
|||||||
project_id: Option<String>,
|
project_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) static TASK_BEING_EDITED: GlobalSignal<Option<Task>> = Signal::global(|| None);
|
|
||||||
pub(crate) static LATEST_VISITED_CATEGORY: GlobalSignal<Category> =
|
|
||||||
Signal::global(|| Category::Inbox);
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn TaskForm() -> Element {
|
pub(crate) fn TaskForm(task: Option<Task>, on_successful_submit: EventHandler<()>) -> Element {
|
||||||
let navigator = use_navigator();
|
let route = use_route::<Route>();
|
||||||
let task = TASK_BEING_EDITED();
|
|
||||||
let selected_category = use_signal(|| {
|
let selected_category = use_signal(|| {
|
||||||
if let Some(task) = &task {
|
if let Some(task) = &task {
|
||||||
task.category.clone()
|
task.category.clone()
|
||||||
} else {
|
} else {
|
||||||
LATEST_VISITED_CATEGORY()
|
match route {
|
||||||
|
Route::CategorySomedayMaybePage => Category::SomedayMaybe,
|
||||||
|
Route::CategoryWaitingForPage => Category::WaitingFor(String::new()),
|
||||||
|
Route::CategoryNextStepsPage => Category::NextSteps,
|
||||||
|
Route::CategoryCalendarPage | Route::CategoryTodayPage => Category::Calendar {
|
||||||
|
date: chrono::Local::now().date_naive(),
|
||||||
|
reoccurrence: None,
|
||||||
|
time: None,
|
||||||
|
},
|
||||||
|
Route::CategoryLongTermPage => Category::LongTerm,
|
||||||
|
_ => Category::Inbox,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let category_calendar_reoccurrence_interval = use_signal(|| {
|
let category_calendar_reoccurrence_interval = use_signal(|| {
|
||||||
@@ -106,9 +104,9 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "grow px-4 flex flex-col gap-6.5",
|
class: "p-4 flex flex-col gap-4",
|
||||||
form {
|
form {
|
||||||
class: "flex flex-col gap-8",
|
class: "flex flex-col gap-4",
|
||||||
id: "form_task",
|
id: "form_task",
|
||||||
onsubmit: move |event| {
|
onsubmit: move |event| {
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
@@ -150,45 +148,50 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
project_id: input_data.project_id
|
project_id: input_data.project_id
|
||||||
.and_then(|deadline| deadline.parse().ok()).filter(|&id| id > 0),
|
.and_then(|deadline| deadline.parse().ok()).filter(|&id| id > 0),
|
||||||
};
|
};
|
||||||
let result = if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
edit_task(task.id, new_task).await
|
let _ = edit_task(task.id, new_task).await;
|
||||||
} else {
|
} else {
|
||||||
create_task(new_task).await
|
let _ = create_task(new_task).await;
|
||||||
};
|
|
||||||
if result.is_ok() {
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
}
|
||||||
|
on_successful_submit.call(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
r#for: "input_title",
|
r#for: "input_title",
|
||||||
icon: FaFeatherPointed
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-pen-clip text-zinc-400/50"
|
||||||
},
|
},
|
||||||
Input {
|
},
|
||||||
class: "grow",
|
input {
|
||||||
name: "title",
|
name: "title",
|
||||||
required: true,
|
required: true,
|
||||||
initial_value: task.as_ref().map(|task| task.title.clone()),
|
initial_value: task.as_ref().map(|task| task.title.clone()),
|
||||||
r#type: "text",
|
r#type: "text",
|
||||||
autofocus: true
|
class: "py-2 px-3 grow bg-zinc-800/50 rounded-lg",
|
||||||
}
|
id: "input_title"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
r#for: "input_project_id",
|
r#for: "input_project",
|
||||||
icon: FaList
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-list text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SuspenseBoundary {
|
SuspenseBoundary {
|
||||||
fallback: |_| {
|
fallback: |_| {
|
||||||
rsx ! {
|
rsx ! {
|
||||||
select {
|
select {
|
||||||
class: "px-4 pt-3 pb-2.25 bg-gray-800-muted drop-shadow-[0_calc(0px_-_var(--spacing))_0_var(--color-gray-900-muted)] rounded-xl grow cursor-pointer",
|
class: "px-3.5 py-2.5 bg-zinc-800/50 rounded-lg grow cursor-pointer",
|
||||||
option {
|
option {
|
||||||
value: 0
|
value: 0,
|
||||||
}
|
{t!("none")}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -199,69 +202,86 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaBomb,
|
r#for: "input_deadline",
|
||||||
r#for: "input_deadline"
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-bomb text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Input {
|
input {
|
||||||
name: "deadline",
|
name: "deadline",
|
||||||
initial_value: task.as_ref().and_then(|task| task.deadline)
|
initial_value: task.as_ref().and_then(|task| task.deadline)
|
||||||
.map(|deadline| deadline.format("%Y-%m-%d").to_string()),
|
.map(|deadline| deadline.format("%Y-%m-%d").to_string()),
|
||||||
r#type: "date",
|
r#type: "date",
|
||||||
class: "grow basis-0"
|
class: "py-2 px-3 bg-zinc-800/50 rounded-lg grow basis-0 cursor-pointer",
|
||||||
|
id: "input_deadline"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaScroll
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-layer-group text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
CategoryInput {
|
CategoryInput {
|
||||||
class: "grow",
|
selected_category: selected_category,
|
||||||
selected_category: selected_category
|
class: "grow"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match selected_category() {
|
match selected_category() {
|
||||||
Category::WaitingFor(waiting_for) => rsx! {
|
Category::WaitingFor(waiting_for) => rsx! {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaHourglassEnd,
|
r#for: "input_deadline",
|
||||||
r#for: "input_category_waiting_for",
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-hourglass-end text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Input {
|
input {
|
||||||
class: "grow",
|
|
||||||
name: "category_waiting_for",
|
name: "category_waiting_for",
|
||||||
required: true,
|
required: true,
|
||||||
initial_value: waiting_for,
|
initial_value: waiting_for,
|
||||||
r#type: "text",
|
r#type: "text",
|
||||||
}
|
class: "py-2 px-3 bg-zinc-800/50 rounded-lg grow",
|
||||||
|
id: "input_category_waiting_for"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Category::Calendar { date, reoccurrence, time } => rsx! {
|
Category::Calendar { date, reoccurrence, time } => rsx! {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaClock,
|
r#for: "input_category_calendar_date",
|
||||||
r#for: "input_category_calendar_date"
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-clock text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "grow grid grid-cols-2 gap-3",
|
class: "grow flex flex-row gap-2",
|
||||||
Input {
|
input {
|
||||||
class: "grow",
|
|
||||||
name: "category_calendar_date",
|
|
||||||
r#type: "date",
|
r#type: "date",
|
||||||
|
name: "category_calendar_date",
|
||||||
required: true,
|
required: true,
|
||||||
initial_value: date.format("%Y-%m-%d").to_string(),
|
initial_value: date.format("%Y-%m-%d").to_string(),
|
||||||
|
class:
|
||||||
|
"py-2 px-3 bg-zinc-800/50 rounded-lg grow cursor-pointer",
|
||||||
|
id: "input_category_calendar_date"
|
||||||
},
|
},
|
||||||
Input {
|
input {
|
||||||
class: "grow",
|
|
||||||
name: "category_calendar_time",
|
|
||||||
r#type: "time",
|
r#type: "time",
|
||||||
|
name: "category_calendar_time",
|
||||||
initial_value: time.map(|calendar_time|
|
initial_value: time.map(|calendar_time|
|
||||||
calendar_time.time.format("%H:%M").to_string()
|
calendar_time.time.format("%H:%M").to_string()
|
||||||
),
|
),
|
||||||
oninput: move |event: Event<FormData>| {
|
class: "py-2 px-3 bg-zinc-800/50 rounded-lg grow cursor-pointer",
|
||||||
|
id: "input_category_calendar_time",
|
||||||
|
oninput: move |event| {
|
||||||
category_calendar_has_time.set(!event.value().is_empty());
|
category_calendar_has_time.set(!event.value().is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,46 +289,54 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
icon: FaRepeat,
|
r#for: "category_calendar_reoccurrence_length",
|
||||||
r#for: "category_calendar_reoccurrence_length"
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-repeat text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "grow grid grid-cols-5 items-end gap-3",
|
class: "grow grid grid-cols-6 gap-2",
|
||||||
ReoccurrenceIntervalInput {
|
ReoccurrenceIntervalInput {
|
||||||
reoccurrence_interval: category_calendar_reoccurrence_interval
|
reoccurrence_interval: category_calendar_reoccurrence_interval
|
||||||
},
|
},
|
||||||
Input {
|
input {
|
||||||
class: "text-right",
|
|
||||||
r#type: "number",
|
r#type: "number",
|
||||||
inputmode: "numeric",
|
inputmode: "numeric",
|
||||||
name: "category_calendar_reoccurrence_length",
|
name: "category_calendar_reoccurrence_length",
|
||||||
disabled: category_calendar_reoccurrence_interval().is_none(),
|
disabled: category_calendar_reoccurrence_interval().is_none(),
|
||||||
required: true,
|
required: true,
|
||||||
min: "1",
|
min: 1,
|
||||||
initial_value: category_calendar_reoccurrence_interval().map_or(
|
initial_value: category_calendar_reoccurrence_interval().map_or(
|
||||||
String::new(),
|
String::new(),
|
||||||
|_| reoccurrence.map_or(1, |reoccurrence|
|
|_| reoccurrence.map_or(1, |reoccurrence|
|
||||||
reoccurrence.length).to_string()
|
reoccurrence.length).to_string()
|
||||||
)
|
),
|
||||||
|
class: "py-2 px-3 bg-zinc-800/50 rounded-lg col-span-2 text-right",
|
||||||
|
id: "category_calendar_reoccurrence_length"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
if category_calendar_has_time() {
|
if category_calendar_has_time() {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-3",
|
class: "flex flex-row items-center gap-3",
|
||||||
InputLabel {
|
label {
|
||||||
r#for: "input_category_calendar_reminder_offset_index",
|
r#for: "category_calendar_reminder_offset_index",
|
||||||
icon: FaBell
|
class: "min-w-6 text-center",
|
||||||
|
i {
|
||||||
|
class: "fa-solid fa-bell text-zinc-400/50"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
input {
|
input {
|
||||||
class: "grow",
|
|
||||||
name: "category_calendar_reminder_offset_index",
|
|
||||||
r#type: "range",
|
r#type: "range",
|
||||||
|
name: "category_calendar_reminder_offset_index",
|
||||||
min: 0,
|
min: 0,
|
||||||
max: REMINDER_OFFSETS.len() as i64 - 1,
|
max: REMINDER_OFFSETS.len() as i64 - 1,
|
||||||
initial_value: category_calendar_reminder_offset_index()
|
initial_value: category_calendar_reminder_offset_index()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
class: "grow input-range-reverse cursor-pointer",
|
||||||
|
id: "category_calendar_has_reminder",
|
||||||
oninput: move |event| {
|
oninput: move |event| {
|
||||||
category_calendar_reminder_offset_index.set(
|
category_calendar_reminder_offset_index.set(
|
||||||
event.value().parse().unwrap()
|
event.value().parse().unwrap()
|
||||||
@@ -316,8 +344,8 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
label {
|
label {
|
||||||
class: "pr-3 min-w-16 text-right",
|
|
||||||
r#for: "category_calendar_reminder_offset_index",
|
r#for: "category_calendar_reminder_offset_index",
|
||||||
|
class: "pr-3 min-w-16 text-right",
|
||||||
{REMINDER_OFFSETS[category_calendar_reminder_offset_index()]
|
{REMINDER_OFFSETS[category_calendar_reminder_offset_index()]
|
||||||
.map(
|
.map(
|
||||||
|offset| if offset.num_hours() < 1 {
|
|offset| if offset.num_hours() < 1 {
|
||||||
@@ -343,20 +371,17 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
div {
|
div {
|
||||||
class: "px-4 grid grid-cols-3 gap-3 mt-auto",
|
class: "flex flex-row justify-between mt-auto",
|
||||||
ButtonSecondary {
|
button {
|
||||||
r#type: "button",
|
r#type: "button",
|
||||||
class: "grow",
|
class: "py-2 px-4 bg-zinc-300/50 rounded-lg cursor-pointer",
|
||||||
onclick: {
|
onclick: move |_| {
|
||||||
let task = task.clone();
|
|
||||||
move |_| {
|
|
||||||
let task = task.clone();
|
let task = task.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
let result = if let Category::Trash = task.category {
|
if let Category::Trash = task.category {
|
||||||
delete_task(task.id).await
|
let _ = delete_task(task.id).await;
|
||||||
} else {
|
} else {
|
||||||
let new_task = NewTask {
|
let new_task = NewTask {
|
||||||
title: task.title.to_owned(),
|
title: task.title.to_owned(),
|
||||||
@@ -364,53 +389,23 @@ pub(crate) fn TaskForm() -> Element {
|
|||||||
category: Category::Trash,
|
category: Category::Trash,
|
||||||
project_id: task.project_id
|
project_id: task.project_id
|
||||||
};
|
};
|
||||||
edit_task(task.id, new_task).await.map(|_| ())
|
let _ = edit_task(task.id, new_task).await;
|
||||||
};
|
|
||||||
if result.is_ok() {
|
|
||||||
/* TODO: Might not work on mobile due to
|
|
||||||
https://dioxuslabs.com/learn/0.7/essentials/router/navigation#history-buttons.
|
|
||||||
*/
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
navigator.go_back();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
on_successful_submit.call(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Icon {
|
i {
|
||||||
icon: FaTrashCan,
|
class: "fa-solid fa-trash-can"
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if task.is_some() {
|
button {
|
||||||
div {
|
|
||||||
class: "grow flex flex-col items-stretch",
|
|
||||||
GoBackButton {
|
|
||||||
ButtonSecondary {
|
|
||||||
/* TODO: Replace w-full` with proper flexbox styling once
|
|
||||||
https://github.com/DioxusLabs/dioxus/issues/5269 is solved. */
|
|
||||||
class: "w-full",
|
|
||||||
r#type: "button",
|
|
||||||
Icon {
|
|
||||||
icon: FaXmark,
|
|
||||||
height: 16,
|
|
||||||
width: 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
div {}
|
|
||||||
}
|
|
||||||
ButtonPrimary {
|
|
||||||
form: "form_task",
|
form: "form_task",
|
||||||
r#type: "submit",
|
r#type: "submit",
|
||||||
Icon {
|
class: "py-2 px-4 bg-zinc-300/50 rounded-lg cursor-pointer",
|
||||||
icon: FaStamp,
|
i {
|
||||||
height: 16,
|
class: "fa-solid fa-floppy-disk"
|
||||||
width: 16
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use crate::components::task_form::TASK_BEING_EDITED;
|
|
||||||
use crate::components::task_list_item::TaskListItem;
|
use crate::components::task_list_item::TaskListItem;
|
||||||
use crate::models::category::Category;
|
use crate::models::category::Category;
|
||||||
use crate::models::task::TaskWithSubtasks;
|
use crate::models::task::{Task, TaskWithSubtasks};
|
||||||
use crate::route::Route;
|
|
||||||
use crate::server::tasks::complete_task;
|
use crate::server::tasks::complete_task;
|
||||||
use dioxus::core_macro::rsx;
|
use dioxus::core_macro::rsx;
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
@@ -10,7 +8,7 @@ use dioxus::prelude::*;
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>) -> Element {
|
pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>) -> Element {
|
||||||
let navigator = use_navigator();
|
let mut task_being_edited = use_context::<Signal<Option<Task>>>();
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: format!("flex flex-col {}", class.unwrap_or("")),
|
class: format!("flex flex-col {}", class.unwrap_or("")),
|
||||||
@@ -18,31 +16,34 @@ pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>
|
|||||||
div {
|
div {
|
||||||
key: "{task.task.id}",
|
key: "{task.task.id}",
|
||||||
class: format!(
|
class: format!(
|
||||||
"px-7 pt-3.75 {} flex flex-row items-start gap-4 hover:bg-gray-800 cursor-pointer select-none transition-all duration-150",
|
"px-8 pt-4 {} flex flex-row gap-4 select-none {}",
|
||||||
if task.task.deadline.is_some() || !task.subtasks.is_empty() {
|
if task.task.deadline.is_some() || !task.subtasks.is_empty() {
|
||||||
"pb-0.25"
|
"pb-0.5"
|
||||||
} else if let Category::Calendar { time, .. } = &task.task.category {
|
} else if let Category::Calendar { time, .. } = &task.task.category {
|
||||||
if time.is_some() {
|
if time.is_some() {
|
||||||
"pb-0.25"
|
"pb-0.5"
|
||||||
} else {
|
} else {
|
||||||
"pb-3.75"
|
"pb-4"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
"pb-3.75"
|
"pb-4"
|
||||||
},
|
},
|
||||||
|
if task_being_edited().is_some_and(|t| t.id == task.task.id) {
|
||||||
|
"bg-zinc-700"
|
||||||
|
} else { "" }
|
||||||
),
|
),
|
||||||
onclick: {
|
onclick: {
|
||||||
let task = task.clone();
|
let task = task.clone();
|
||||||
move |_| {
|
move |_| task_being_edited.set(Some(task.task.clone()))
|
||||||
*TASK_BEING_EDITED.write() = Some(task.task.clone());
|
|
||||||
navigator.push(Route::TaskFormPage);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
button {
|
i {
|
||||||
class: format!(
|
class: format!(
|
||||||
"mt-0.5 hover:mt-0 hover:pb-0.5 transition-all duration-150 cursor-pointer {}",
|
"{} text-3xl align-middle h-9 text-zinc-500",
|
||||||
if let Category::Done = task.task.category { "pointer-events-none" }
|
if let Category::Done = task.task.category {
|
||||||
else { "" }
|
"fa solid fa-square-check"
|
||||||
|
} else {
|
||||||
|
"fa-regular fa-square cursor-pointer"
|
||||||
|
}
|
||||||
),
|
),
|
||||||
onclick: {
|
onclick: {
|
||||||
move |event: Event<MouseData>| {
|
move |event: Event<MouseData>| {
|
||||||
@@ -52,19 +53,8 @@ pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>
|
|||||||
let _ = complete_task(task.task.id).await;
|
let _ = complete_task(task.task.id).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
div {
|
|
||||||
class: format!("h-8 w-8 rounded-full {}",
|
|
||||||
if let Category::Done = task.task.category {
|
|
||||||
"mt-[3px] mb-[2px] bg-amber-300-muted"
|
|
||||||
} else {
|
|
||||||
"mb-[5px] border-3 border-amber-300-muted drop-shadow-[0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted),0_1px_0_var(--color-amber-700-muted)]"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
div {
|
|
||||||
class: "mt-1.5",
|
|
||||||
TaskListItem {
|
TaskListItem {
|
||||||
task: task.clone()
|
task: task.clone()
|
||||||
}
|
}
|
||||||
@@ -73,4 +63,3 @@ pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ use chrono::{Datelike, Local};
|
|||||||
use dioxus::core_macro::rsx;
|
use dioxus::core_macro::rsx;
|
||||||
use dioxus::dioxus_core::Element;
|
use dioxus::dioxus_core::Element;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::{FaBomb, FaClock, FaListCheck};
|
|
||||||
use dioxus_i18n::prelude::i18n;
|
use dioxus_i18n::prelude::i18n;
|
||||||
use dioxus_i18n::t;
|
use dioxus_i18n::t;
|
||||||
use voca_rs::Voca;
|
use voca_rs::Voca;
|
||||||
@@ -16,21 +14,19 @@ pub(crate) fn TaskListItem(task: TaskWithSubtasks) -> Element {
|
|||||||
let today_date = Local::now().date_naive();
|
let today_date = Local::now().date_naive();
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "pt-0.75 flex flex-col",
|
class: "flex flex-col",
|
||||||
div {
|
div {
|
||||||
class: "grow font-medium text-pretty wrap-anywhere",
|
class: "mt-1 grow font-medium",
|
||||||
{task.task.title}
|
{task.task.title}
|
||||||
},
|
},
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row gap-4",
|
class: "flex flex-row gap-4",
|
||||||
if let Some(deadline) = task.task.deadline {
|
if let Some(deadline) = task.task.deadline {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-1 text-sm text-gray-500",
|
class: "text-sm text-zinc-400",
|
||||||
Icon {
|
i {
|
||||||
icon: FaBomb,
|
class: "fa-solid fa-bomb"
|
||||||
height: 14,
|
},
|
||||||
width: 14
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
format!(
|
format!(
|
||||||
" {}",
|
" {}",
|
||||||
@@ -76,12 +72,10 @@ pub(crate) fn TaskListItem(task: TaskWithSubtasks) -> Element {
|
|||||||
if let Category::Calendar { time, .. } = task.task.category {
|
if let Category::Calendar { time, .. } = task.task.category {
|
||||||
if let Some(calendar_time) = time {
|
if let Some(calendar_time) = time {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-1 text-sm text-gray-500",
|
class: "text-sm text-zinc-400",
|
||||||
Icon {
|
i {
|
||||||
icon: FaClock,
|
class: "fa-solid fa-clock"
|
||||||
height: 14,
|
},
|
||||||
width: 14
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
let format = t!("time-format");
|
let format = t!("time-format");
|
||||||
format!(" {}", calendar_time.time.format(format.as_str()))
|
format!(" {}", calendar_time.time.format(format.as_str()))
|
||||||
@@ -91,12 +85,10 @@ pub(crate) fn TaskListItem(task: TaskWithSubtasks) -> Element {
|
|||||||
}
|
}
|
||||||
if !task.subtasks.is_empty() {
|
if !task.subtasks.is_empty() {
|
||||||
div {
|
div {
|
||||||
class: "flex flex-row items-center gap-1 text-sm text-gray-500",
|
class: "text-sm text-zinc-400",
|
||||||
Icon {
|
i {
|
||||||
icon: FaListCheck,
|
class: "fa-solid fa-list-check"
|
||||||
height: 14,
|
},
|
||||||
width: 14
|
|
||||||
}
|
|
||||||
{format!(
|
{format!(
|
||||||
" {}/{}",
|
" {}/{}",
|
||||||
task.subtasks.iter()
|
task.subtasks.iter()
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use dioxus::{
|
use dioxus::{
|
||||||
CapturedError,
|
CapturedError,
|
||||||
fullstack::{Loader, Loading, WebSocketOptions},
|
document::document,
|
||||||
|
fullstack::{Loader, Loading, WebSocketOptions, WebsocketState, use_websocket},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
@@ -13,7 +16,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn use_on_document_become_visible(mut callback: impl FnMut() + 'static) {
|
fn use_on_document_visibility_change(mut callback: impl FnMut() + 'static) {
|
||||||
let callback = use_callback(move |_| callback());
|
let callback = use_callback(move |_| callback());
|
||||||
use_effect(move || {
|
use_effect(move || {
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
@@ -24,6 +27,13 @@ fn use_on_document_become_visible(mut callback: impl FnMut() + 'static) {
|
|||||||
dioxus.send(0);
|
dioxus.send(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// window.addEventListener("focus", () => resume());
|
||||||
|
|
||||||
|
// Keep this eval alive so dioxus.send keeps working.
|
||||||
|
// while (true) {
|
||||||
|
// await new Promise(r => setTimeout(r, 3600_000));
|
||||||
|
// }
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
loop {
|
loop {
|
||||||
@@ -31,6 +41,7 @@ fn use_on_document_become_visible(mut callback: impl FnMut() + 'static) {
|
|||||||
.await
|
.await
|
||||||
.expect("The JS code returned a value not parsable to `u8`.");
|
.expect("The JS code returned a value not parsable to `u8`.");
|
||||||
callback.call(());
|
callback.call(());
|
||||||
|
log("received resume");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -47,6 +58,19 @@ fn sort_loader_result<T: Ord + Clone>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub static LOG_MESSAGES: GlobalSignal<Vec<String>> =
|
||||||
|
Signal::global(|| vec!["=== LOG ===".to_string()]);
|
||||||
|
|
||||||
|
fn log(message: impl Display) {
|
||||||
|
let mut old = LOG_MESSAGES();
|
||||||
|
old.push(format!(
|
||||||
|
"[{}] {}",
|
||||||
|
chrono::Local::now().format("%H:%M:%S"),
|
||||||
|
message.to_string()
|
||||||
|
));
|
||||||
|
*LOG_MESSAGES.write() = old;
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::result_large_err)]
|
#[allow(clippy::result_large_err)]
|
||||||
fn use_loader_with_update_subscription<F, T, E>(
|
fn use_loader_with_update_subscription<F, T, E>(
|
||||||
mut future: impl FnMut() -> F + 'static,
|
mut future: impl FnMut() -> F + 'static,
|
||||||
@@ -67,25 +91,29 @@ where
|
|||||||
use_effect(move || {
|
use_effect(move || {
|
||||||
let initial_websocket_reset_tick = websocket_reset_tick();
|
let initial_websocket_reset_tick = websocket_reset_tick();
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
|
log("spawning based on ws_gen");
|
||||||
let Ok(socket) =
|
let Ok(socket) =
|
||||||
subscribe_to_updates(WebSocketOptions::new().with_automatic_reconnect()).await
|
subscribe_to_updates(WebSocketOptions::new().with_automatic_reconnect()).await
|
||||||
else {
|
else {
|
||||||
|
log("failed to spawn");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
while socket.recv().await.is_ok() {
|
while socket.recv().await.is_ok() {
|
||||||
|
log("running the future recv");
|
||||||
if websocket_reset_tick() != initial_websocket_reset_tick {
|
if websocket_reset_tick() != initial_websocket_reset_tick {
|
||||||
|
log("new WS gen, breaking");
|
||||||
// A new WebSocket has been created (a new task spawned), cleaning this one up.
|
// A new WebSocket has been created (a new task spawned), cleaning this one up.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
refresh_tick += 1;
|
refresh_tick += 1;
|
||||||
}
|
}
|
||||||
|
log("future ending");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/* So that when the device goes to sleep or suspends the app, the WebSocket gets recreated on
|
/* So that when the device goes to sleep or suspends the app, the WebSocket gets recreated on
|
||||||
waking up. It is important to do this only on becoming visible (document.hidden == false),
|
waking up. */
|
||||||
because becoming hidden is the part when network may not work and thus cause errors. */
|
use_on_document_visibility_change(move || {
|
||||||
use_on_document_become_visible(move || {
|
|
||||||
websocket_reset_tick += 1;
|
websocket_reset_tick += 1;
|
||||||
refresh_tick += 1;
|
refresh_tick += 1;
|
||||||
});
|
});
|
||||||
|
|||||||
47
src/layouts/main.rs
Normal file
47
src/layouts/main.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use crate::components::bottom_panel::BottomPanel;
|
||||||
|
use crate::components::form_open_button::FormOpenButton;
|
||||||
|
use crate::components::sticky_bottom::StickyBottom;
|
||||||
|
use crate::models::project::Project;
|
||||||
|
use crate::models::task::Task;
|
||||||
|
use crate::route::Route;
|
||||||
|
use dioxus::core_macro::rsx;
|
||||||
|
use dioxus::dioxus_core::Element;
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub(crate) fn Main() -> Element {
|
||||||
|
let mut display_form = use_signal(|| false);
|
||||||
|
let project_being_edited =
|
||||||
|
use_context_provider::<Signal<Option<Project>>>(|| Signal::new(None));
|
||||||
|
let task_being_edited = use_context_provider::<Signal<Option<Task>>>(|| Signal::new(None));
|
||||||
|
|
||||||
|
use_effect(move || {
|
||||||
|
display_form.set(project_being_edited().is_some() || task_being_edited().is_some());
|
||||||
|
});
|
||||||
|
|
||||||
|
rsx! {
|
||||||
|
SuspenseBoundary {
|
||||||
|
fallback: |_| {
|
||||||
|
rsx! {
|
||||||
|
div {
|
||||||
|
class: "grow flex flex-col justify-center items-center",
|
||||||
|
div {
|
||||||
|
i {
|
||||||
|
class: "text-3xl fa-solid fa-cog fa-spin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Outlet::<Route> {}
|
||||||
|
}
|
||||||
|
StickyBottom {
|
||||||
|
FormOpenButton {
|
||||||
|
opened: display_form,
|
||||||
|
}
|
||||||
|
BottomPanel {
|
||||||
|
display_form: display_form,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
pub(crate) mod navigation;
|
mod main;
|
||||||
pub(crate) mod suspense;
|
pub(crate) use main::Main;
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
use crate::components::bottom_panel::BottomPanel;
|
|
||||||
use crate::components::create_button::CreateButton;
|
|
||||||
use crate::components::sticky_bottom::StickyBottom;
|
|
||||||
use crate::components::task_form::LATEST_VISITED_CATEGORY;
|
|
||||||
use crate::models::category::Category;
|
|
||||||
use crate::route::Route;
|
|
||||||
use dioxus::core_macro::rsx;
|
|
||||||
use dioxus::dioxus_core::Element;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn Navigation() -> Element {
|
|
||||||
let current_route = use_route();
|
|
||||||
use_effect(use_reactive(¤t_route, move |current_route| {
|
|
||||||
*LATEST_VISITED_CATEGORY.write() = match current_route {
|
|
||||||
Route::CategorySomedayMaybePage => Category::SomedayMaybe,
|
|
||||||
Route::CategoryWaitingForPage => Category::WaitingFor(String::new()),
|
|
||||||
Route::CategoryNextStepsPage => Category::NextSteps,
|
|
||||||
Route::CategoryCalendarPage | Route::CategoryTodayPage => Category::Calendar {
|
|
||||||
date: chrono::Local::now().date_naive(),
|
|
||||||
reoccurrence: None,
|
|
||||||
time: None,
|
|
||||||
},
|
|
||||||
_ => Category::Inbox,
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
rsx! {
|
|
||||||
div {
|
|
||||||
class: "grow flex flex-col pb-36",
|
|
||||||
Outlet::<Route> {}
|
|
||||||
}
|
|
||||||
StickyBottom {
|
|
||||||
CreateButton {},
|
|
||||||
BottomPanel {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
use crate::route::Route;
|
|
||||||
use dioxus::core_macro::rsx;
|
|
||||||
use dioxus::dioxus_core::Element;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
use dioxus_free_icons::Icon;
|
|
||||||
use dioxus_free_icons::icons::fa_solid_icons::FaCog;
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn Suspense() -> Element {
|
|
||||||
rsx! {
|
|
||||||
SuspenseBoundary {
|
|
||||||
fallback: |_| {
|
|
||||||
rsx! {
|
|
||||||
div {
|
|
||||||
class: "grow flex flex-col justify-center items-center",
|
|
||||||
Icon {
|
|
||||||
class: "text-gray-500 animate-[spin_3000ms_linear_infinite]",
|
|
||||||
icon: FaCog,
|
|
||||||
height: 32,
|
|
||||||
width: 32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Outlet::<Route> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,14 @@ use crate::layouts;
|
|||||||
use crate::views::category_calendar_page::CategoryCalendarPage;
|
use crate::views::category_calendar_page::CategoryCalendarPage;
|
||||||
use crate::views::category_done_page::CategoryDonePage;
|
use crate::views::category_done_page::CategoryDonePage;
|
||||||
use crate::views::category_inbox_page::CategoryInboxPage;
|
use crate::views::category_inbox_page::CategoryInboxPage;
|
||||||
|
use crate::views::category_long_term_page::CategoryLongTermPage;
|
||||||
use crate::views::category_next_steps_page::CategoryNextStepsPage;
|
use crate::views::category_next_steps_page::CategoryNextStepsPage;
|
||||||
use crate::views::category_someday_maybe_page::CategorySomedayMaybePage;
|
use crate::views::category_someday_maybe_page::CategorySomedayMaybePage;
|
||||||
use crate::views::category_today_page::CategoryTodayPage;
|
use crate::views::category_today_page::CategoryTodayPage;
|
||||||
use crate::views::category_trash_page::CategoryTrashPage;
|
use crate::views::category_trash_page::CategoryTrashPage;
|
||||||
use crate::views::category_waiting_for_page::CategoryWaitingForPage;
|
use crate::views::category_waiting_for_page::CategoryWaitingForPage;
|
||||||
use crate::views::not_found_page::NotFoundPage;
|
use crate::views::not_found_page::NotFoundPage;
|
||||||
use crate::views::project_form_page::ProjectFormPage;
|
|
||||||
use crate::views::projects_page::ProjectsPage;
|
use crate::views::projects_page::ProjectsPage;
|
||||||
use crate::views::task_form_page::TaskFormPage;
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
// All variants have the same postfix because they have to match the component names.
|
// All variants have the same postfix because they have to match the component names.
|
||||||
@@ -18,8 +17,8 @@ use dioxus::prelude::*;
|
|||||||
#[derive(Clone, Routable, Debug, PartialEq)]
|
#[derive(Clone, Routable, Debug, PartialEq)]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) enum Route {
|
pub(crate) enum Route {
|
||||||
#[layout(layouts::navigation::Navigation)]
|
#[layout(layouts::Main)]
|
||||||
#[layout(layouts::suspense::Suspense)]
|
#[redirect("/", || Route::CategoryTodayPage {})]
|
||||||
#[route("/today")]
|
#[route("/today")]
|
||||||
CategoryTodayPage,
|
CategoryTodayPage,
|
||||||
#[route("/inbox")]
|
#[route("/inbox")]
|
||||||
@@ -32,6 +31,8 @@ pub(crate) enum Route {
|
|||||||
CategoryNextStepsPage,
|
CategoryNextStepsPage,
|
||||||
#[route("/calendar")]
|
#[route("/calendar")]
|
||||||
CategoryCalendarPage,
|
CategoryCalendarPage,
|
||||||
|
#[route("/long-term")]
|
||||||
|
CategoryLongTermPage,
|
||||||
#[route("/done")]
|
#[route("/done")]
|
||||||
CategoryDonePage,
|
CategoryDonePage,
|
||||||
#[route("/trash")]
|
#[route("/trash")]
|
||||||
@@ -39,13 +40,6 @@ pub(crate) enum Route {
|
|||||||
#[route("/projects")]
|
#[route("/projects")]
|
||||||
ProjectsPage,
|
ProjectsPage,
|
||||||
#[end_layout]
|
#[end_layout]
|
||||||
#[end_layout]
|
|
||||||
#[layout(layouts::suspense::Suspense)]
|
|
||||||
#[route("/task")]
|
|
||||||
TaskFormPage,
|
|
||||||
#[route("/project")]
|
|
||||||
ProjectFormPage,
|
|
||||||
#[end_layout]
|
|
||||||
#[redirect("/", || Route::CategoryTodayPage)]
|
#[redirect("/", || Route::CategoryTodayPage)]
|
||||||
#[route("/:..route")]
|
#[route("/:..route")]
|
||||||
NotFoundPage {
|
NotFoundPage {
|
||||||
|
|||||||
12
src/styles/tailwind.config.js
Normal file
12
src/styles/tailwind.config.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/** @type {import("tailwindcss").Config} */
|
||||||
|
module.exports = {
|
||||||
|
mode: "all",
|
||||||
|
content: ["./src/**/*.{rs,html,css}"],
|
||||||
|
theme: {
|
||||||
|
fontFamily: {
|
||||||
|
sans: ["Inter", "sans-serif"],
|
||||||
|
},
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user