add aspnet server

This commit is contained in:
2026-01-14 20:20:15 -05:00
parent 2d2f4c8b89
commit 8fa5612403
40 changed files with 605 additions and 7 deletions

1
client/.env Normal file
View File

@@ -0,0 +1 @@
APP_VERSION=Debug

7
client/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target
.DS_Store
# These are backup files generated by rustfmt
**/*.rs.bk

6209
client/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

32
client/Cargo.toml Normal file
View File

@@ -0,0 +1,32 @@
[package]
name = "azki"
version = "0.1.0"
authors = ["Amatsugu <khamraj@kaisei.app>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
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]
default = ["web"]
# The feature that are only required for the web = ["dioxus/web"] build target should be optional and only enabled in the web = ["dioxus/web"] feature
web = ["dioxus/web"]
# The feature that are only required for the desktop = ["dioxus/desktop"] build target should be optional and only enabled in the desktop = ["dioxus/desktop"] feature
desktop = ["dioxus/desktop"]
# The feature that are only required for the mobile = ["dioxus/mobile"] build target should be optional and only enabled in the mobile = ["dioxus/mobile"] feature
mobile = ["dioxus/mobile"]

21
client/Dioxus.toml Normal file
View File

@@ -0,0 +1,21 @@
[application]
[web.app]
# HTML title tag content
title = "azki"
# include `assets` in web platform
[web.resource]
# Additional CSS style files
style = []
# Additional JavaScript files
script = []
[web.resource.dev]
# Javascript code file
# serve: [dev-server] only
script = []

36
client/README.md Normal file
View File

@@ -0,0 +1,36 @@
# Development
Your new jumpstart project includes basic organization with an organized `assets` folder and a `components` folder.
If you chose to develop with the router feature, you will also have a `views` folder.
```
project/
├─ assets/ # Any assets that are used by the app should be placed here
├─ src/
│ ├─ main.rs # The entrypoint for the app. It also defines the routes for the app.
│ ├─ components/
│ │ ├─ mod.rs # Defines the components module
│ │ ├─ hero.rs # The Hero component for use in the home page
│ ├─ views/ # The views each route will render in the app.
│ │ ├─ mod.rs # Defines the module for the views route and re-exports the components for each route
│ │ ├─ blog.rs # The component that will render at the /blog/:id route
│ │ ├─ home.rs # The component that will render at the / route
├─ Cargo.toml # The Cargo.toml file defines the dependencies and feature flags for your project
```
### Serving Your App
Run the following command in the root of your project to start developing with the default platform:
```bash
dx serve
```
To run for a different platform, use the `--platform platform` flag. E.g.
```bash
dx serve --platform desktop
```

BIN
client/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View 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;

View 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;
}
}

View 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;
}
}

View 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;
}
}
}

View File

@@ -0,0 +1,22 @@
@import "mixins.scss";
@import "colors.scss";
#content {
display: grid;
}
#player {
background-color: $darkBackground;
display: grid;
grid-template-areas: "Head ControlPanel" "ViewPort ControlPanel" "Timeline Timeline";
grid-template-rows: auto 1fr 500px;
grid-template-columns: 1fr auto;
}
#viewport {
grid-area: ViewPort;
border: 1px solid $lightBackground;
}
#timeline {
grid-area: Timeline;
border: 1px solid $lightBackground;
}

38
client/build.rs Normal file
View 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
client/src/app.rs Normal file
View 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> {}
}
}

View File

@@ -0,0 +1,6 @@
use dioxus::prelude::*;
#[component]
pub fn Calendar() -> Element {
rsx! {}
}

View File

@@ -0,0 +1,3 @@
mod calendar;
pub mod playback;
pub use calendar::*;

View File

@@ -0,0 +1,6 @@
mod player;
mod timeline;
mod viewport;
pub use player::*;
pub use timeline::*;
pub use viewport::*;

View 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 { }
}
}
}

View File

@@ -0,0 +1,10 @@
use dioxus::prelude::*;
#[component]
pub fn Timeline() -> Element {
rsx! {
div{
id: "timeline"
}
}
}

View File

@@ -0,0 +1,10 @@
use dioxus::prelude::*;
#[component]
pub fn Viewport() -> Element {
rsx! {
div{
id: "viewport"
}
}
}

4
client/src/env.rs Normal file
View File

@@ -0,0 +1,4 @@
// This file is automatically generated by build.rs
#[allow(dead_code)]
pub const APP_VERSION: &'static str = "Debug";

11
client/src/main.rs Normal file
View File

@@ -0,0 +1,11 @@
use crate::app::App;
mod app;
mod components;
mod env;
mod route;
mod views;
fn main() {
dioxus::launch(App);
}

13
client/src/route.rs Normal file
View 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 {},
}

8
client/src/views/home.rs Normal file
View File

@@ -0,0 +1,8 @@
use crate::components::playback::Player;
use dioxus::prelude::*;
#[component]
pub fn Home() -> Element {
rsx! {
Player{}
}
}

7
client/src/views/mod.rs Normal file
View File

@@ -0,0 +1,7 @@
mod home;
pub use home::*;
mod navbar;
pub use navbar::*;
mod settings;
pub use settings::*;

View File

@@ -0,0 +1,68 @@
use crate::{env::APP_VERSION, route::Route};
use dioxus::prelude::*;
const NAV_CSS: Asset = asset!("/assets/styling/navbar.scss");
#[component]
pub fn NavLayout() -> Element {
rsx! {
Navbar { }
div {
id: "content",
Outlet::<Route> {}
}
}
}
const NAV_ICON: Asset = asset!("/assets/favicon.ico");
#[component]
pub fn Navbar() -> Element {
rsx! {
document::Link { rel: "stylesheet", href: NAV_CSS }
nav {
Branding {}
MainNaviagation {}
Widgets {}
Utils {}
}
}
}
#[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" }
}
}
}

View File

@@ -0,0 +1,8 @@
use dioxus::prelude::*;
#[component]
pub fn Settings() -> Element {
rsx! {
"Settings"
}
}