first steps, creating nav bar + inital work on layouts
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@
|
|||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
.env
|
||||||
|
|||||||
6209
Cargo.lock
generated
Normal file
6209
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
13
Cargo.toml
@@ -8,6 +8,19 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dioxus = { version = "0.7.1", features = ["router"] }
|
dioxus = { version = "0.7.1", features = ["router"] }
|
||||||
|
serde = "1.0.219"
|
||||||
|
serde_repr = "0.1.20"
|
||||||
|
tonic = { version = "*", default-features = false, features = [
|
||||||
|
"codegen",
|
||||||
|
"prost",
|
||||||
|
] }
|
||||||
|
prost = "0.13"
|
||||||
|
tonic-web-wasm-client = "0.7"
|
||||||
|
web-sys = { version = "0.3.77", features = ["Storage", "Window"] }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = { version = "*", default-features = false, features = ["prost"] }
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["web"]
|
default = ["web"]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 23 KiB |
@@ -1,8 +0,0 @@
|
|||||||
#blog {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blog a {
|
|
||||||
color: #ffffff;
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
15
assets/styling/colors.scss
Normal file
15
assets/styling/colors.scss
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//Colors
|
||||||
|
$mainAccent: #ff0064;
|
||||||
|
$mainAccentLight: #ff3385;
|
||||||
|
$mainAccentDark: #e0005a;
|
||||||
|
$secondaryAccent: #57c9ef;
|
||||||
|
$secondaryAccentLight: #7cd5f3;
|
||||||
|
$secondaryAccentDark: #32bdec;
|
||||||
|
$mainBackground: #2a2d43;
|
||||||
|
$darkBackground: #0d1821;
|
||||||
|
$lightBackground: #394053;
|
||||||
|
$featureBackround: #073b4c;
|
||||||
|
$featureBackroundDark: #031d25;
|
||||||
|
$mainTextColor: #eee;
|
||||||
|
$lightTextColor: #fff;
|
||||||
|
$darkTextColor: #ccc;
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
body {
|
|
||||||
background-color: #0f1116;
|
|
||||||
color: #ffffff;
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#hero {
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#links {
|
|
||||||
width: 400px;
|
|
||||||
text-align: left;
|
|
||||||
font-size: x-large;
|
|
||||||
color: white;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
#links a {
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin: 10px 0px;
|
|
||||||
border: white 1px solid;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#links a:hover {
|
|
||||||
background-color: #1f1f1f;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header {
|
|
||||||
max-width: 1200px;
|
|
||||||
}
|
|
||||||
46
assets/styling/main.scss
Normal file
46
assets/styling/main.scss
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
@import "mixins";
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
background-color: $mainBackground;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: "Noto Sans", sans-serif;
|
||||||
|
font-optical-sizing: auto;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-variation-settings: "wdth" 100;
|
||||||
|
color: $mainTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main:has(#content) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: $navBarSize 1fr;
|
||||||
|
grid-template-areas: "Nav Content";
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
$contentPad: 10px;
|
||||||
|
grid-area: Content;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: fixed;
|
||||||
|
left: $navBarSize;
|
||||||
|
height: calc(100dvh - (2 * $contentPad));
|
||||||
|
width: calc(100dvw - $navBarSize - (2 * $contentPad));
|
||||||
|
padding: $contentPad;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $secondaryAccent;
|
||||||
|
&:hover {
|
||||||
|
color: $secondaryAccentLight;
|
||||||
|
}
|
||||||
|
&:visited {
|
||||||
|
color: $secondaryAccentDark;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
assets/styling/mixins.scss
Normal file
43
assets/styling/mixins.scss
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
$navBarSize: 64px;
|
||||||
|
|
||||||
|
@mixin mobile {
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin max-screen($size) {
|
||||||
|
@media (max-width: #{$size}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin max-container($size) {
|
||||||
|
@container (max-width: #{$size}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin small-container {
|
||||||
|
@container (max-width: 500px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin medium-container {
|
||||||
|
@container (max-width: 800px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin large-container {
|
||||||
|
@container (max-width: 1000px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xlarge-container {
|
||||||
|
@container (max-width: 1200px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#navbar {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar a {
|
|
||||||
color: #ffffff;
|
|
||||||
margin-right: 20px;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar a:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #91a4d2;
|
|
||||||
}
|
|
||||||
61
assets/styling/navbar.scss
Normal file
61
assets/styling/navbar.scss
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
@import "mixins.scss";
|
||||||
|
@import "colors.scss";
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "Branding" "Nav" "Widgets" "Utils";
|
||||||
|
grid-template-rows: auto 1fr auto auto;
|
||||||
|
background-color: $mainAccent;
|
||||||
|
height: 100dvh;
|
||||||
|
position: fixed;
|
||||||
|
width: $navBarSize;
|
||||||
|
box-shadow: 0 0 3px #000;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.branding {
|
||||||
|
grid-area: Branding;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: $navBarSize;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainNav {
|
||||||
|
grid-area: Nav;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widgets {
|
||||||
|
grid-area: Widgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
.utils {
|
||||||
|
grid-area: Utils;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItem {
|
||||||
|
height: $navBarSize;
|
||||||
|
width: $navBarSize;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transition: 0.2s ease-out background;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&[aria-current="page"] {
|
||||||
|
background-color: $mainAccentDark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $mainAccentLight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
assets/styling/player.scss
Normal file
18
assets/styling/player.scss
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
@import "mixins.scss";
|
||||||
|
@import "colors.scss";
|
||||||
|
#content {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
#player {
|
||||||
|
background-color: $darkBackground;
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "Head ControlPanel" "ViewPort ControlPanel" "Timeline Timeline";
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewport {
|
||||||
|
grid-area: ViewPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
#timeline {
|
||||||
|
grid-area: Timeline;
|
||||||
|
}
|
||||||
38
build.rs
Normal file
38
build.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use dotenv::dotenv;
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// tonic_build::configure()
|
||||||
|
// .build_server(false)
|
||||||
|
// .build_client(true)
|
||||||
|
// .compile_protos(
|
||||||
|
// &[
|
||||||
|
// "",
|
||||||
|
// ],
|
||||||
|
// &[""],
|
||||||
|
// )?;
|
||||||
|
forward_env();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn forward_env() {
|
||||||
|
let dest_path = "./src/env.rs";
|
||||||
|
let mut f = File::create(&dest_path).unwrap();
|
||||||
|
f.write_all(b"// This file is automatically generated by build.rs\n\n")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
dotenv().ok();
|
||||||
|
for (key, value) in env::vars() {
|
||||||
|
if key.starts_with("APP_") {
|
||||||
|
f.write_all("#[allow(dead_code)]\n".as_bytes()).unwrap();
|
||||||
|
let line = format!(
|
||||||
|
"pub const {}: &'static str = \"{}\";\n",
|
||||||
|
key,
|
||||||
|
value.replace("\"", "\\\"")
|
||||||
|
);
|
||||||
|
f.write_all(line.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/app.rs
Normal file
23
src/app.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::route::Route;
|
||||||
|
|
||||||
|
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
||||||
|
const MAIN_CSS: Asset = asset!("/assets/styling/main.scss");
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn App() -> Element {
|
||||||
|
rsx! {
|
||||||
|
document::Link { rel: "icon", href: FAVICON }
|
||||||
|
document::Link { rel: "stylesheet", href: MAIN_CSS }
|
||||||
|
|
||||||
|
document::Link { rel: "preconnect", href: "https://fonts.googleapis.com" }
|
||||||
|
document::Link { rel: "preconnect", href: "https://fonts.gstatic.com" }
|
||||||
|
document::Link {
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap",
|
||||||
|
}
|
||||||
|
|
||||||
|
Router::<Route> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/components/calendar.rs
Normal file
6
src/components/calendar.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Calendar() -> Element {
|
||||||
|
rsx! {}
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
const HEADER_SVG: Asset = asset!("/assets/header.svg");
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub fn Hero() -> Element {
|
|
||||||
rsx! {
|
|
||||||
// We can create elements inside the rsx macro with the element name followed by a block of attributes and children.
|
|
||||||
div {
|
|
||||||
// Attributes should be defined in the element before any children
|
|
||||||
id: "hero",
|
|
||||||
// After all attributes are defined, we can define child elements and components
|
|
||||||
img { src: HEADER_SVG, id: "header" }
|
|
||||||
div { id: "links",
|
|
||||||
// The RSX macro also supports text nodes surrounded by quotes
|
|
||||||
a { href: "https://dioxuslabs.com/learn/0.7/", "📚 Learn Dioxus" }
|
|
||||||
a { href: "https://dioxuslabs.com/awesome", "🚀 Awesome Dioxus" }
|
|
||||||
a { href: "https://github.com/dioxus-community/", "📡 Community Libraries" }
|
|
||||||
a { href: "https://github.com/DioxusLabs/sdk", "⚙️ Dioxus Development Kit" }
|
|
||||||
a { href: "https://marketplace.visualstudio.com/items?itemName=DioxusLabs.dioxus", "💫 VSCode Extension" }
|
|
||||||
a { href: "https://discord.gg/XgGxMSkvUM", "👋 Community Discord" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
//! The components module contains all shared components for our app. Components are the building blocks of dioxus apps.
|
mod calendar;
|
||||||
//! They can be used to defined common UI elements like buttons, forms, and modals. In this template, we define a Hero
|
pub mod playback;
|
||||||
//! component to be used in our app.
|
pub use calendar::*;
|
||||||
|
|
||||||
mod hero;
|
|
||||||
pub use hero::Hero;
|
|
||||||
|
|||||||
6
src/components/playback/mod.rs
Normal file
6
src/components/playback/mod.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
mod player;
|
||||||
|
mod timeline;
|
||||||
|
mod viewport;
|
||||||
|
pub use player::*;
|
||||||
|
pub use timeline::*;
|
||||||
|
pub use viewport::*;
|
||||||
19
src/components/playback/player.rs
Normal file
19
src/components/playback/player.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::playback::{Timeline, Viewport};
|
||||||
|
const PLAYER_CSS: Asset = asset!("/assets/styling/player.scss");
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Player() -> Element {
|
||||||
|
rsx! {
|
||||||
|
document::Link { rel: "stylesheet", href: PLAYER_CSS }
|
||||||
|
div{
|
||||||
|
id: "player",
|
||||||
|
div {
|
||||||
|
id: "head"
|
||||||
|
}
|
||||||
|
Viewport { }
|
||||||
|
Timeline { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/components/playback/timeline.rs
Normal file
10
src/components/playback/timeline.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Timeline() -> Element {
|
||||||
|
rsx! {
|
||||||
|
div{
|
||||||
|
id: "timeline"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/components/playback/viewport.rs
Normal file
10
src/components/playback/viewport.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Viewport() -> Element {
|
||||||
|
rsx! {
|
||||||
|
div{
|
||||||
|
id: "viewport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/env.rs
Normal file
4
src/env.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// This file is automatically generated by build.rs
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const APP_VERSION: &'static str = "Debug";
|
||||||
63
src/main.rs
63
src/main.rs
@@ -1,66 +1,11 @@
|
|||||||
// The dioxus prelude contains a ton of common items used in dioxus apps. It's a good idea to import wherever you
|
use crate::app::App;
|
||||||
// need dioxus
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
use components::Hero;
|
mod app;
|
||||||
use views::{Blog, Home, Navbar};
|
|
||||||
|
|
||||||
/// Define a components module that contains all shared components for our app.
|
|
||||||
mod components;
|
mod components;
|
||||||
/// Define a views module that contains the UI for all Layouts and Routes for our app.
|
mod env;
|
||||||
|
mod route;
|
||||||
mod views;
|
mod views;
|
||||||
|
|
||||||
/// The Route enum is used to define the structure of internal routes in our app. All route enums need to derive
|
|
||||||
/// the [`Routable`] trait, which provides the necessary methods for the router to work.
|
|
||||||
///
|
|
||||||
/// Each variant represents a different URL pattern that can be matched by the router. If that pattern is matched,
|
|
||||||
/// the components for that route will be rendered.
|
|
||||||
#[derive(Debug, Clone, Routable, PartialEq)]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
enum Route {
|
|
||||||
// The layout attribute defines a wrapper for all routes under the layout. Layouts are great for wrapping
|
|
||||||
// many routes with a common UI like a navbar.
|
|
||||||
#[layout(Navbar)]
|
|
||||||
// The route attribute defines the URL pattern that a specific route matches. If that pattern matches the URL,
|
|
||||||
// the component for that route will be rendered. The component name that is rendered defaults to the variant name.
|
|
||||||
#[route("/")]
|
|
||||||
Home {},
|
|
||||||
// The route attribute can include dynamic parameters that implement [`std::str::FromStr`] and [`std::fmt::Display`] with the `:` syntax.
|
|
||||||
// In this case, id will match any integer like `/blog/123` or `/blog/-456`.
|
|
||||||
#[route("/blog/:id")]
|
|
||||||
// Fields of the route variant will be passed to the component as props. In this case, the blog component must accept
|
|
||||||
// an `id` prop of type `i32`.
|
|
||||||
Blog { id: i32 },
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can import assets in dioxus with the `asset!` macro. This macro takes a path to an asset relative to the crate root.
|
|
||||||
// The macro returns an `Asset` type that will display as the path to the asset in the browser or a local path in desktop bundles.
|
|
||||||
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
|
||||||
// The asset macro also minifies some assets like CSS and JS to make bundled smaller
|
|
||||||
const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// The `launch` function is the main entry point for a dioxus app. It takes a component and renders it with the platform feature
|
|
||||||
// you have enabled
|
|
||||||
dioxus::launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// App is the main component of our app. Components are the building blocks of dioxus apps. Each component is a function
|
|
||||||
/// that takes some props and returns an Element. In this case, App takes no props because it is the root of our app.
|
|
||||||
///
|
|
||||||
/// Components should be annotated with `#[component]` to support props, better error messages, and autocomplete
|
|
||||||
#[component]
|
|
||||||
fn App() -> Element {
|
|
||||||
// The `rsx!` macro lets us define HTML inside of rust. It expands to an Element with all of our HTML inside.
|
|
||||||
rsx! {
|
|
||||||
// In addition to element and text (which we will see later), rsx can contain other components. In this case,
|
|
||||||
// we are using the `document::Link` component to add a link to our favicon and main CSS file into the head of our app.
|
|
||||||
document::Link { rel: "icon", href: FAVICON }
|
|
||||||
document::Link { rel: "stylesheet", href: MAIN_CSS }
|
|
||||||
|
|
||||||
|
|
||||||
// The router component renders the route enum we defined above. It will handle synchronization of the URL and render
|
|
||||||
// the layouts and components for the active route.
|
|
||||||
Router::<Route> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
13
src/route.rs
Normal file
13
src/route.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::views::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Routable, PartialEq)]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub enum Route {
|
||||||
|
#[layout(NavLayout)]
|
||||||
|
#[route("/")]
|
||||||
|
Home {},
|
||||||
|
#[route("/settings")]
|
||||||
|
Settings {},
|
||||||
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
use crate::Route;
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
|
|
||||||
|
|
||||||
/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
|
|
||||||
///
|
|
||||||
/// The component takes a `id` prop of type `i32` from the route enum. Whenever the id changes, the component function will be
|
|
||||||
/// re-run and the rendered HTML will be updated.
|
|
||||||
#[component]
|
|
||||||
pub fn Blog(id: i32) -> Element {
|
|
||||||
rsx! {
|
|
||||||
document::Link { rel: "stylesheet", href: BLOG_CSS }
|
|
||||||
|
|
||||||
div {
|
|
||||||
id: "blog",
|
|
||||||
|
|
||||||
// Content
|
|
||||||
h1 { "This is blog #{id}!" }
|
|
||||||
p { "In blog #{id}, we show how the Dioxus router works and how URL parameters can be passed as props to our route components." }
|
|
||||||
|
|
||||||
// Navigation links
|
|
||||||
// The `Link` component lets us link to other routes inside our app. It takes a `to` prop of type `Route` and
|
|
||||||
// any number of child nodes.
|
|
||||||
Link {
|
|
||||||
// The `to` prop is the route that the link should navigate to. We can use the `Route` enum to link to the
|
|
||||||
// blog page with the id of -1. Since we are using an enum instead of a string, all of the routes will be checked
|
|
||||||
// at compile time to make sure they are valid.
|
|
||||||
to: Route::Blog { id: id - 1 },
|
|
||||||
"Previous"
|
|
||||||
}
|
|
||||||
span { " <---> " }
|
|
||||||
Link {
|
|
||||||
to: Route::Blog { id: id + 1 },
|
|
||||||
"Next"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
use crate::components::Hero;
|
use crate::components::playback::Player;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
/// The Home page component that will be rendered when the current route is `[Route::Home]`
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Home() -> Element {
|
pub fn Home() -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
Hero {}
|
Player{}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
//! The views module contains the components for all Layouts and Routes for our app. Each layout and route in our [`Route`]
|
|
||||||
//! enum will render one of these components.
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
//! The [`Home`] and [`Blog`] components will be rendered when the current route is [`Route::Home`] or [`Route::Blog`] respectively.
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
//! The [`Navbar`] component will be rendered on all pages of our app since every page is under the layout. The layout defines
|
|
||||||
//! a common wrapper around all child routes.
|
|
||||||
|
|
||||||
mod home;
|
mod home;
|
||||||
pub use home::Home;
|
pub use home::*;
|
||||||
|
|
||||||
mod blog;
|
|
||||||
pub use blog::Blog;
|
|
||||||
|
|
||||||
mod navbar;
|
mod navbar;
|
||||||
pub use navbar::Navbar;
|
pub use navbar::*;
|
||||||
|
mod settings;
|
||||||
|
pub use settings::*;
|
||||||
|
|||||||
@@ -1,32 +1,68 @@
|
|||||||
use crate::Route;
|
use crate::{env::APP_VERSION, route::Route};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
const NAV_CSS: Asset = asset!("/assets/styling/navbar.scss");
|
||||||
|
|
||||||
const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css");
|
#[component]
|
||||||
|
pub fn NavLayout() -> Element {
|
||||||
|
rsx! {
|
||||||
|
|
||||||
|
Navbar { }
|
||||||
|
div {
|
||||||
|
id: "content",
|
||||||
|
Outlet::<Route> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAV_ICON: Asset = asset!("/assets/favicon.ico");
|
||||||
|
|
||||||
/// The Navbar component that will be rendered on all pages of our app since every page is under the layout.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// This layout component wraps the UI of [Route::Home] and [Route::Blog] in a common navbar. The contents of the Home and Blog
|
|
||||||
/// routes will be rendered under the outlet inside this component
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Navbar() -> Element {
|
pub fn Navbar() -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
document::Link { rel: "stylesheet", href: NAVBAR_CSS }
|
document::Link { rel: "stylesheet", href: NAV_CSS }
|
||||||
|
nav {
|
||||||
div {
|
Branding {}
|
||||||
id: "navbar",
|
MainNaviagation {}
|
||||||
Link {
|
Widgets {}
|
||||||
to: Route::Home {},
|
Utils {}
|
||||||
"Home"
|
}
|
||||||
}
|
}
|
||||||
Link {
|
}
|
||||||
to: Route::Blog { id: 1 },
|
|
||||||
"Blog"
|
#[component]
|
||||||
}
|
pub fn MainNaviagation() -> Element {
|
||||||
|
rsx! {
|
||||||
|
div { class: "mainNav",
|
||||||
|
Link { class: "navItem", to: Route::Home { }, "Home" }
|
||||||
|
Link { class: "navItem", to: Route::Settings {}, "Settings" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Branding() -> Element {
|
||||||
|
rsx! {
|
||||||
|
div { class: "branding",
|
||||||
|
img { src: NAV_ICON, alt: "Aoba" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Widgets() -> Element {
|
||||||
|
rsx! {
|
||||||
|
div { class: "widgets" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Utils() -> Element {
|
||||||
|
// let mut auth_context = use_context::<AuthContext>();
|
||||||
|
let version = APP_VERSION;
|
||||||
|
rsx! {
|
||||||
|
div { class: "utils",
|
||||||
|
div { "{version}" }
|
||||||
|
div { /*onclick: move |_| auth_context.logout(),*/ "Logout" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `Outlet` component is used to render the next component inside the layout. In this case, it will render either
|
|
||||||
// the [`Home`] or [`Blog`] component depending on the current route.
|
|
||||||
Outlet::<Route> {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/views/settings.rs
Normal file
8
src/views/settings.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Settings() -> Element {
|
||||||
|
rsx! {
|
||||||
|
"Settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user