= Lazy::new(|| {
- let theme =
- ThemeService::convert_auto_to_actually_theme(ThemeService::get_theme_from_storage());
-
- ThemePool { theme }
-});
diff --git a/router/Cargo.toml b/shared/Cargo.toml
similarity index 80%
rename from router/Cargo.toml
rename to shared/Cargo.toml
index 51bf0f0..8a1f6b8 100644
--- a/router/Cargo.toml
+++ b/shared/Cargo.toml
@@ -1,9 +1,9 @@
[package]
-name = "router"
+name = "shared"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-yew-router = "0.16.0"
+serde = "1.0.204"
diff --git a/shared/src/lib.rs b/shared/src/lib.rs
new file mode 100644
index 0000000..f409c95
--- /dev/null
+++ b/shared/src/lib.rs
@@ -0,0 +1,4 @@
+pub mod links;
+pub mod post;
+pub mod site_config;
+pub mod tag;
diff --git a/shared/src/links.rs b/shared/src/links.rs
new file mode 100644
index 0000000..96f9e23
--- /dev/null
+++ b/shared/src/links.rs
@@ -0,0 +1,14 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Deserialize, Serialize)]
+pub struct LinksConfig {
+ pub links: Vec,
+}
+
+#[derive(Deserialize, Serialize)]
+pub struct Link {
+ pub name: String,
+ pub description: String,
+ pub url: String,
+ pub avatar: String,
+}
diff --git a/shared/src/post.rs b/shared/src/post.rs
new file mode 100644
index 0000000..98f7776
--- /dev/null
+++ b/shared/src/post.rs
@@ -0,0 +1,43 @@
+use serde::{Deserialize, Serialize};
+
+use crate::tag::Tag;
+
+#[derive(Serialize, Deserialize, Clone)]
+pub struct PostWithTags {
+ pub post: P,
+ pub tags: Vec,
+}
+
+#[derive(Serialize, Deserialize, Clone)]
+pub struct PaginationPostsRes {
+ pub page_limit: u64,
+ pub page: u64,
+ pub total: u64,
+ pub has_next: bool,
+ pub posts: Vec,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+pub struct Post {
+ pub id: i32,
+ pub path: String,
+ pub spoiler: String,
+ pub title: String,
+ pub created_at: String,
+ pub updated_at: String,
+ pub tags: Vec,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct PostDetail {
+ pub id: i32,
+ pub content: String,
+ pub created_at: String,
+ pub updated_at: String,
+ pub title: String,
+ pub tags: Vec,
+}
+
+pub trait IntoPost: Sized {
+ fn into_post>(self, tags: Vec) -> P;
+}
diff --git a/shared/src/site_config.rs b/shared/src/site_config.rs
new file mode 100644
index 0000000..574bf8f
--- /dev/null
+++ b/shared/src/site_config.rs
@@ -0,0 +1,27 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
+pub struct Config {
+ pub root: RootConfig,
+ pub server: ServerConfig,
+ pub nav: Vec,
+}
+
+#[derive(PartialEq, Serialize, Eq, Debug, Deserialize, Clone)]
+pub struct NavConfig {
+ pub text: String,
+ pub url: String,
+}
+
+#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
+pub struct RootConfig {
+ pub language: String,
+ pub posts_folder_name: String,
+ pub dynamic_pages_folder_name: String,
+}
+
+#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
+pub struct ServerConfig {
+ pub dev_port: usize,
+ pub prod_port: usize,
+}
diff --git a/shared/src/tag.rs b/shared/src/tag.rs
new file mode 100644
index 0000000..1bb4901
--- /dev/null
+++ b/shared/src/tag.rs
@@ -0,0 +1,8 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+pub struct Tag {
+ pub id: i32,
+ pub text: String,
+ pub color: Option,
+}
diff --git a/site.config.toml b/site.config.toml
new file mode 100644
index 0000000..4b423b5
--- /dev/null
+++ b/site.config.toml
@@ -0,0 +1,44 @@
+[root]
+posts_folder_name = "posts"
+
+# The default language of the site
+# en | zh
+language = "en"
+
+# dynamic_pages_folder_name is really useful in most cases,
+# you can put markdown files under the root/dynamic_pages_folder_name folder,
+# if zzhack found markdown file in root/dynamic_pages_folder_name,
+# these files will be rendered as html pages, that allows users can visit these pages
+# through path of these markdown files, for instance:
+#
+# dynamic_pages/
+# |- about/
+# |- me.md
+#
+# then you can visit the about page through /pages/about/me
+dynamic_pages_folder_name = "dynamic_pages"
+
+[[nav]]
+text = "Home"
+url = "/"
+
+[[nav]]
+text = "Posts"
+url = "/posts"
+
+[[nav]]
+text = "About me"
+url = "/pages/about/me"
+
+[server]
+dev_port = 8000
+prod_port = 8080
+
+# If you want to use different client to create/update post,
+# you need to set password and secret_key to create access_token
+# Otherwise you don't need to modify this section
+[api]
+password = ""
+
+# The secret_key used for encoding and decoding the JWT tokens
+secret_key = ""
diff --git a/site_config/Cargo.toml b/site_config/Cargo.toml
new file mode 100644
index 0000000..c48e98d
--- /dev/null
+++ b/site_config/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "site_config"
+version = "0.0.1"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+serde = "1.0.204"
+serde_derive = "1.0.204"
+toml = "0.8.14"
+shared = { path = "../shared" }
+cached = "0.52.0"
+wasm-bindgen = "0.2.92"
diff --git a/site_config/src/lib.rs b/site_config/src/lib.rs
new file mode 100644
index 0000000..ca28476
--- /dev/null
+++ b/site_config/src/lib.rs
@@ -0,0 +1,9 @@
+use cached::proc_macro::cached;
+use shared::site_config::Config;
+
+static SITE_CONFIG_STRING: &'static str = include_str!("../../site.config.toml");
+
+#[cached]
+pub fn get_site_config() -> Config {
+ toml::from_str::(&SITE_CONFIG_STRING).expect("Wrong format of site.config.toml")
+}
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..113ada5
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,40 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ darkMode: "selector",
+ content: ["app/**/*.{rs,html}", "entry/**/*.{rs,html}"],
+ theme: {
+ extend: {
+ borderRadius: {
+ "4xl": "30px",
+ "5xl": "38px",
+ "6xl": "42px",
+ },
+ },
+ colors: {
+ orange: {
+ DEFAULT: "#FFBE76",
+ },
+ gray: {
+ 500: "rgba(156,156,156,0.5)",
+ 200: "rgba(217,217,217,0.2)",
+ 900: "rgba(138,143,152,0.9)",
+ 450: "rgba(175,177,180,0.45)",
+ 600: "rgba(28,28,32,0.6)",
+ 100: "rgba(128,132,140,0.1)",
+ },
+ black: {
+ dark: "#F7F8F8",
+ DEFAULT: "#1e1e1e",
+ 400: "rgba(0,0,0,0.4)",
+ 900: "#0A0A0A",
+ },
+ white: {
+ dark: "#2B2B2F",
+ DEFAULT: "#ffffff",
+ 200: "#E9E9E9",
+ 600: "rgba(255,255,255,0.6)",
+ },
+ },
+ },
+ plugins: [require("@tailwindcss/typography")],
+};
diff --git a/templates/md_parser.template b/templates/md_parser.template
deleted file mode 100644
index 6723ae0..0000000
--- a/templates/md_parser.template
+++ /dev/null
@@ -1,12 +0,0 @@
-use std::*;
-
-#[derive(Clone)]
-pub struct PostFile {
- pub content: &'static str,
- pub modified_time: u128,
- pub filename: &'static str
-}
-
-pub static POSTS: [PostFile; {{TRAVERSE_COUNT}}] = [
- {{TEMPLATE}}
-];
diff --git a/templates/md_parser_iteration.template b/templates/md_parser_iteration.template
deleted file mode 100644
index 11309b0..0000000
--- a/templates/md_parser_iteration.template
+++ /dev/null
@@ -1,5 +0,0 @@
-PostFile {
- content: include_str!("../../posts/{{STEM}}.md"),
- modified_time: {{MODIFY_TIME}},
- filename: "{{STEM}}"
-},
diff --git a/ui/.gitignore b/ui/.gitignore
deleted file mode 100644
index 96ef6c0..0000000
--- a/ui/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/target
-Cargo.lock
diff --git a/ui/Cargo.toml b/ui/Cargo.toml
deleted file mode 100644
index 8b8a878..0000000
--- a/ui/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "ui"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-yew = "0.19.3"
-stylist = {version = "0.10", features = ["yew_integration"]}
-utils = {path = "../utils"}
-global = {path = "../global"}
-services = {path = "../services"}
-web-sys = { version = "0.3", features = ["HtmlMetaElement", "Document", "Element", "DocumentFragment", "HtmlTemplateElement", "MediaQueryList"] }
-wasm-logger = "0.2.0"
-log = "0.4.17"
-material-yew = { git = "https://github.com/hamza1311/material-yew", features = ["full"] }
-urlencoding = "2.1.0"
-router = {path = "../router"}
-yew-router = "0.16.0"
diff --git a/ui/src/common/contact.rs b/ui/src/common/contact.rs
deleted file mode 100644
index 153678d..0000000
--- a/ui/src/common/contact.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use super::image::Icon;
-use crate::link::Link;
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct ContactsProps {
- pub source: Vec,
-}
-
-#[derive(Clone, PartialEq)]
-pub enum ContactType {
- Twitter,
- GitHub,
- Email,
- WeChat,
- Discord,
-}
-
-impl From<&ContactType> for &'static str {
- fn from(contact: &ContactType) -> &'static str {
- match contact {
- ContactType::Discord => "discord.svg",
- ContactType::Twitter => "twitter.svg",
- ContactType::WeChat => "wechat.svg",
- ContactType::Email => "gmail.svg",
- ContactType::GitHub => "github.svg",
- }
- }
-}
-
-impl ContactType {
- pub fn into_lnk(&self) -> &'static str {
- match self {
- ContactType::Discord => "#",
- ContactType::Twitter => "https://twitter.com/_mistricky",
- ContactType::WeChat => "#",
- ContactType::Email => "mailto:mist.zzh@gmail.com",
- ContactType::GitHub => "https://github.com/mistricky",
- }
- }
-}
-
-impl ContactType {
- fn has_theme(&self) -> bool {
- match self {
- ContactType::GitHub => true,
- _ => false,
- }
- }
-
- fn into_size(&self) -> i32 {
- match self {
- ContactType::GitHub => 30,
- _ => 32,
- }
- }
-}
-
-#[function_component(Contacts)]
-pub fn contacts(props: &ContactsProps) -> Html {
- let style = use_style!(
- r"
- display: flex;
- align-items: center;
- "
- );
-
- let render_contacts = props
- .source
- .iter()
- .map(|contact| {
- let source: &'static str = contact.into();
- html! {
-
-
-
- }
- })
- .collect::();
-
- html! {
-
- {render_contacts}
-
- }
-}
diff --git a/ui/src/common/container.rs b/ui/src/common/container.rs
deleted file mode 100644
index 978ca18..0000000
--- a/ui/src/common/container.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use crate::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, Debug, PartialEq)]
-pub struct ContainerProps {
- pub children: Children,
-}
-
-#[function_component(Container)]
-pub fn container(props: &ContainerProps) -> Html {
- let style = use_style!(
- r"
- width: 100%;
- display: flex;
- justify-content: center;
-
- .container-box {
- width: 816px;
- box-sizing: border-box;
- }
-
- @media (max-width: 600px) {
- .container-box {
- min-width: 100%;
- width: 100%;
- padding: 0 22px;
- }
- }
- "
- );
-
- html! {
-
-
- {props.children.clone()}
-
-
- }
-}
diff --git a/ui/src/common/footer.rs b/ui/src/common/footer.rs
deleted file mode 100644
index 9b92552..0000000
--- a/ui/src/common/footer.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-use crate::contact::{ContactType, Contacts};
-use crate::container::Container;
-use utils::use_style;
-use yew::prelude::*;
-
-#[function_component(Footer)]
-pub fn footer() -> Html {
- let style = use_style!(
- r"
- width: 100%;
- background: var(--base-color);
- padding-bottom: 18px;
-
- .contacts {
- margin-top: 31px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
-
- .copyright {
- display: flex;
- justify-content: center;
- }
-
- .text {
- font-size: 14px;
- }
-
- @media (max-width: 600px) {
- .contacts {
- flex-direction: column;
- height: auto;
- padding-bottom: 30px;
- }
- }
- "
- );
-
- html! {
-
-
-
-
-
{"Copyright © 2021 Mist"}
-
-
-
- }
-}
diff --git a/ui/src/common/gradient_title.rs b/ui/src/common/gradient_title.rs
deleted file mode 100644
index 179d5b8..0000000
--- a/ui/src/common/gradient_title.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct GradientTitleProps {
- pub children: Children,
-}
-
-#[function_component(GradientTitle)]
-pub fn gradient_title(props: &GradientTitleProps) -> Html {
- let style = style!(
- r"
- display: flex;
- margin-bottom: 21px;
-
- .gradient-title__content {
- font-size: 29px;
- position: relative;
- }
-
- .gradient-title__content::before {
- content: '';
- width: 120%;
- display: block;
- height: 21px;
- border-radius: 100px;
- background: linear-gradient(90deg, #FF4AA8 0%, #F95D66 22%, #FE9C76 100%);
- position: absolute;
- z-index: -1;
- bottom: 0px;
- left: -5%;
- }
- "
- )
- .unwrap();
-
- html! {
-
-
- { props.children.clone() }
-
-
- }
-}
diff --git a/ui/src/common/header/drawer.rs b/ui/src/common/header/drawer.rs
deleted file mode 100644
index a4d71f7..0000000
--- a/ui/src/common/header/drawer.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-use crate::header::drawer_item::DrawerItem;
-use stylist::{css, yew::styled_component};
-use utils::html::render_with_insert_node;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct DrawerProps {
- pub is_open: UseStateHandle,
- pub children: ChildrenWithProps,
-}
-
-#[styled_component(Drawer)]
-pub fn drawer(props: &DrawerProps) -> Html {
- let style = css!(
- r"
- width: 100%;
- transition: all 0.2s;
- position: absolute;
- left: 0;
- background: var(--underlay-color);
- z-index: 5;
- transform: translateY(${translate});
-
- .drawer-items {
- position: relative;
- z-index: 5;
- background: var(--underlay-color);
- padding: 0 20px;
- }
-
- .line {
- width: 100%;
- height: 1px;
- background: var(--shallow-gray);
- }
- ",
- translate = if *props.is_open { "56px" } else { "-100%" },
- );
- let mask_style = css!(
- r"
- top: 0;
- left: 0;
- position: fixed;
- width: 100%;
- height: 100vh;
- background: var(--mask-color);
- z-index: 4;
- display: ${display};
- ",
- display = if *props.is_open { "block" } else { "none" }
- );
- let render_nodes = props
- .children
- .iter()
- .map(|item| html! {{item}})
- .collect::>();
- let handle_mask_click = {
- let is_open = props.is_open.clone();
-
- Callback::from(move |_| is_open.set(!*is_open))
- };
-
- html! {
- <>
-
-
-
- {render_with_insert_node(&render_nodes, &html! {
-
- })}
-
-
- >
- }
-}
diff --git a/ui/src/common/header/drawer_item.rs b/ui/src/common/header/drawer_item.rs
deleted file mode 100644
index b317c03..0000000
--- a/ui/src/common/header/drawer_item.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use crate::link::Link;
-use router::RootRoutes;
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct DrawerProps {
- pub lnk: RootRoutes,
- pub children: Children,
-}
-
-#[function_component(DrawerItem)]
-pub fn drawer_item(props: &DrawerProps) -> Html {
- let style = use_style!(
- r"
- padding: 12px 0;
- "
- );
-
- html! {
-
- {props.children.clone()}
-
- }
-}
diff --git a/ui/src/common/header/header.rs b/ui/src/common/header/header.rs
deleted file mode 100644
index 33f2965..0000000
--- a/ui/src/common/header/header.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-use crate::contact::ContactType;
-use crate::container::Container;
-use crate::header::drawer::Drawer;
-use crate::header::drawer_item::DrawerItem;
-use crate::image::{Icon, ThemeImage};
-use crate::link::Link;
-use crate::modal::{modal::Modal, modal_content::ModalContent};
-use crate::theme_selector::ThemeSelector;
-use router::RootRoutes;
-use utils::resource::with_assets;
-use utils::theme::only_render_on_mobile;
-use utils::use_style;
-use yew::prelude::*;
-
-#[function_component(Header)]
-pub fn header() -> Html {
- let style = use_style!(
- r"
- width: 100%;
-
- .wrapper {
- height: 56px;
- justify-content: space-between;
- }
-
- .wrapper, .tabs, .left, .right, .setting-icon {
- display: flex;
- align-items: center;
- }
-
- .left img {
- height: 23px;
- display: flex;
- }
-
- .tabs {
- margin-left: 88px;
- }
-
- .tabs a {
- font-size: 14px;
- margin: 0 15px;
- }
-
- .setting-icon {
- margin-right: 19px;
- }
-
- .header {
- height:56px;
- width: 100%;
- background: var(--base-color);
- position: relative;
- z-index: 6;
- }
-
- @media (max-width: 600px) {
- .tabs {
- display: none;
- }
- }
- "
- );
- let control_theme_style = use_style!(
- r"
- display: flex;
- flex-direction: column;
- align-items: center;
-
- .control-theme__text {
- width: 100%;
- text-align: left;
- font-size: 14px;
- color: var(--sub-text-color);
- }
-
- .control-theme__img {
- width: 126px;
- }
-
- @media (max-width: 600px) {
- .control-theme__text {
- font-size: 12px;
- }
- }
- "
- );
- let is_open_drawer_handle = use_state_eq(|| false);
- let is_open_theme_modal = use_state_eq(|| false);
- let handle_drawer_click = {
- let is_open_drawer_handle = is_open_drawer_handle.clone();
-
- Callback::from(move |_| is_open_drawer_handle.set(!*is_open_drawer_handle))
- };
- let handle_setting_click = {
- let is_open_theme_modal = is_open_theme_modal.clone();
-
- Callback::from(move |_| is_open_theme_modal.set(!*is_open_theme_modal))
- };
-
- html! {
-
-
- {"Posts"}
- {"Projects"}
- {"About"}
- {"Links"}
-
-
-
-
-
-
-
{"你可以在任何地方通过开关随时修改你的主题"}
-
-
-
-
-
- }
-}
diff --git a/ui/src/common/header/mod.rs b/ui/src/common/header/mod.rs
deleted file mode 100644
index f7e3457..0000000
--- a/ui/src/common/header/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-pub mod drawer;
-pub mod drawer_item;
-pub mod header;
-pub use header::Header;
diff --git a/ui/src/common/image.rs b/ui/src/common/image.rs
deleted file mode 100644
index 616ba57..0000000
--- a/ui/src/common/image.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-use global::theme_context::ThemeContext;
-use material_yew::MatIconButton;
-use stylist::{style, yew::styled_component};
-use utils::resource::{with_assets, with_assets_by_theme};
-use utils::theme::with_reactive_source;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct ImageProps {
- pub source: &'static str,
-}
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct ThemeImageProps {
- #[prop_or(false)]
- pub is_reactive: bool,
- pub source: &'static str,
- #[prop_or(String::from(""))]
- pub style: String,
-}
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct IconProps {
- pub source: &'static str,
- #[prop_or(true)]
- pub has_theme: bool,
- pub size: i32,
- #[prop_or(String::from(""))]
- pub style: String,
- #[prop_or_default]
- pub onclick: Option>,
-}
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct BaseImageProps {
- pub source: &'static str,
- #[prop_or(false)]
- pub has_theme: bool,
- #[prop_or(false)]
- pub is_reactive: bool,
- #[prop_or(String::from(""))]
- pub style: String,
-}
-
-#[function_component(BaseImage)]
-pub fn base_image(props: &BaseImageProps) -> Html {
- let theme_ctx = use_context::().unwrap();
- let source = if props.is_reactive {
- with_reactive_source(props.source.to_string())
- } else {
- props.source.to_string()
- };
- let source = if props.has_theme {
- with_assets_by_theme(&source, &theme_ctx.theme)
- } else {
- with_assets(&source)
- };
-
- html! {
-
- }
-}
-
-#[function_component(Image)]
-pub fn image(props: &ImageProps) -> Html {
- html! {
-
- }
-}
-
-#[function_component(ThemeImage)]
-pub fn theme_image(props: &ThemeImageProps) -> Html {
- html! {
-
- }
-}
-
-#[styled_component(Icon)]
-pub fn icon(props: &IconProps) -> Html {
- let style = style!(
- r"
- width: ${size}px;
- height: ${size}px;
- ",
- size = props.size,
- )
- .unwrap();
- let style = style.get_class_name();
- let wrapper_style = style!(
- r"
- --mdc-icon-size: ${size}px;
- ",
- size = props.size,
- )
- .unwrap();
- let onclick_callback = match props.onclick.clone() {
- Some(callback) => callback,
- None => Callback::noop(),
- };
-
- html! {
-
-
-
-
-
- }
-}
diff --git a/ui/src/common/layout.rs b/ui/src/common/layout.rs
deleted file mode 100644
index a73f4ba..0000000
--- a/ui/src/common/layout.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use super::{footer::Footer, header::Header};
-use crate::common::switch::ThemeSwitchBar;
-use crate::container::Container;
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, PartialEq)]
-pub struct BaseLayoutProps {
- pub children: Children,
-}
-
-#[function_component(BaseLayout)]
-pub fn base_layout(props: &BaseLayoutProps) -> Html {
- let style = use_style!(
- r"
- width: 100%;
- height: 100%;
- position: relative;
-
- .theme-switch-bar {
- position: absolute;
- right: -118px;
- top: 63px;
- }
-
- .page-outlet {
- min-height: calc(100vh - 100px);
- }
-
- @media (max-width: 600px) {
- .theme-switch-bar {
- position: static;
- }
- }
- "
- );
-
- html! {
- <>
-
-
-
-
-
-
-
- { props.children.clone() }
-
-
-
-
- >
- }
-}
diff --git a/ui/src/common/link.rs b/ui/src/common/link.rs
deleted file mode 100644
index eaf65a4..0000000
--- a/ui/src/common/link.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-use router::RootRoutes;
-use utils::use_style;
-use yew::prelude::*;
-use yew_router::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct LinkProps {
- #[prop_or_default]
- pub href: Option,
- #[prop_or(String::from(""))]
- pub out_href: String,
- pub children: Children,
- #[prop_or_default]
- pub onclick: Option>,
-}
-
-#[function_component(Link)]
-pub fn link(props: &LinkProps) -> Html {
- let style = use_style!(
- r"
- text-decoration: none;
- transition: 0.3s opacity;
- cursor: pointer;
-
- &:hover {
- opacity: 0.75;
- }
- "
- );
- let onclick_callback = match props.onclick.clone() {
- Some(callback) => callback,
- None => {
- let history = use_history().unwrap();
- let history = history.clone();
- let target = props.href.clone();
- let out_href = props.out_href.clone();
-
- match target {
- Some(target) => Callback::from(move |_| {
- history.push(target.clone());
- }),
- None => Callback::from(move |_| {
- web_sys::window()
- .unwrap()
- .location()
- .set_href(out_href.as_str())
- .unwrap();
- }),
- }
- }
- };
-
- html! {
-
- {props.children.clone()}
-
- }
-}
diff --git a/ui/src/common/mod.rs b/ui/src/common/mod.rs
deleted file mode 100644
index a496428..0000000
--- a/ui/src/common/mod.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-pub mod contact;
-pub mod container;
-pub mod footer;
-pub mod gradient_title;
-pub mod header;
-pub mod image;
-pub mod layout;
-pub mod link;
-pub mod modal;
-pub mod switch;
diff --git a/ui/src/common/modal/mod.rs b/ui/src/common/modal/mod.rs
deleted file mode 100644
index 1194157..0000000
--- a/ui/src/common/modal/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod modal;
-pub mod modal_action;
-pub mod modal_content;
diff --git a/ui/src/common/modal/modal.rs b/ui/src/common/modal/modal.rs
deleted file mode 100644
index 463bad5..0000000
--- a/ui/src/common/modal/modal.rs
+++ /dev/null
@@ -1,247 +0,0 @@
-use crate::image::Icon;
-use crate::modal::{
- modal_action::{ModalAction, ModalActionProps},
- modal_content::{ModalContent, ModalContentProps},
-};
-use std::collections::HashMap;
-use std::rc::Rc;
-use stylist::{css, yew::styled_component};
-use yew::html::ChildrenRenderer;
-use yew::prelude::*;
-use yew::virtual_dom::{VChild, VComp};
-
-// vchild.props -> {props: enum} -> {props} -> vnode(html)
-
-#[derive(Clone, PartialEq)]
-pub enum ModalComponentProps {
- Action(Rc),
- Content(Rc),
-}
-
-pub enum ModalComponentType {
- Action,
- Content,
- Title,
-}
-
-impl From for ModalComponentProps {
- fn from(props: ModalActionProps) -> Self {
- ModalComponentProps::Action(Rc::new(props))
- }
-}
-
-impl From for ModalComponentProps {
- fn from(props: ModalContentProps) -> Self {
- ModalComponentProps::Content(Rc::new(props))
- }
-}
-
-#[derive(Clone, PartialEq)]
-pub struct ModalVariant {
- pub modal_component_props: ModalComponentProps,
-}
-
-impl From> for ModalVariant
-where
- T: Component,
- T::Properties: Clone + Into,
-{
- fn from(child: VChild) -> Self {
- ModalVariant {
- modal_component_props: (*child.props).clone().into(),
- }
- }
-}
-
-impl From for Html {
- fn from(variant: ModalVariant) -> Self {
- match variant.modal_component_props {
- ModalComponentProps::Action(props) => {
- VComp::new::(props, NodeRef::default(), None).into()
- }
- ModalComponentProps::Content(props) => {
- VComp::new::(props, NodeRef::default(), None).into()
- }
- }
- }
-}
-
-#[derive(Properties, PartialEq, Clone)]
-pub struct ModalProps {
- pub children: ChildrenRenderer,
- pub is_visible: UseStateHandle,
- pub title: &'static str,
- #[prop_or_default]
- pub subtitle: Option<&'static str>,
-}
-
-#[styled_component(Modal)]
-pub fn modal(props: &ModalProps) -> Html {
- let modal_host = web_sys::window()
- .unwrap()
- .document()
- .unwrap()
- .body()
- .unwrap();
- let mut nodes = HashMap::<&'static str, Vec>::new();
-
- nodes.insert("action", vec![]);
- nodes.insert("content", vec![]);
- extract_nodes(&props.children, &mut nodes);
-
- let wrapper_style = css!(
- r#"
- display: ${display} !important;
- width: 100%;
- height: 100vh;
- position: fixed;
- left: 0;
- top: 0;
- z-index: 10;
- display: flex;
- justify-content: center;
- align-items: center;
- transition:1s opacity ease-out;
- opacity: ${opacity};
-
- .modal-box {
- background: var(--card-color);
- border-radius: 10px;
- width: fit-content;
- padding: 15px 0;
- min-width: 240px;
- position: relative;
- z-index: 3;
- position: relative;
- }
-
- .modal-title, .modal-content {
- padding: 0 20px;
- }
-
- .modal-actions {
- display: flex;
- justify-content: flex-end;
- }
-
- .close-btn {
- position: absolute;
- top: 0;
- right: 0;
- z-index: 10;
- display: none;
- }
-
- .modal-subtitle {
- font-size: 14px;
- color: var(--sub-text-color);
- font-weight: 400;
- }
-
- .mask {
- display: ${display} !important;
- width: 100%;
- height: 100%;
- position: absolute;
- left: 0;
- top: 0;
- background: var(--mask-color);
- }
-
- @media (max-width: 600px) {
- .modal-box {
- margin: 0 30px;
- }
-
- .modal-subtitle {
- font-size: 12px;
- }
-
- .close-btn {
- display: block;
- }
- }
- "#,
- opacity = if *props.is_visible { 1 } else { 0 },
- display = if *props.is_visible { "flex" } else { "none" },
- );
- let handle_mask_click = {
- let visible = props.is_visible.clone();
-
- Callback::from(move |_| visible.set(false))
- };
- let render_subtitle = match props.subtitle {
- Some(subtitle) => html! {
-
- {subtitle}
-
- },
- None => html! {},
- };
-
- let render_component = html! {
-
-
-
-
-
-
-
- {props.title}
- {render_subtitle}
-
-
- { get_single_ele_from_vec_by_default(&nodes, "content") }
-
-
- { nodes.get("action").unwrap().into_iter().map(|vnode| vnode.clone()).collect::() }
-
-
-
- };
-
- create_portal(
- html! {
- {render_component}
- },
- modal_host.into(),
- )
-}
-
-fn get_single_ele_from_vec_by_default(
- map: &HashMap<&'static str, Vec>,
- key: &'static str,
-) -> Html {
- let vec = map.get(key).unwrap();
-
- match vec.get(0) {
- Some(vnode) => vnode.clone(),
- None => html! {},
- }
-}
-
-fn extract_nodes<'a>(
- children: &ChildrenRenderer,
- map: &'a mut HashMap<&'static str, Vec>,
-) {
- for child in children.iter() {
- match child.modal_component_props {
- ModalComponentProps::Action(_) => {
- append_child(child, "action", map);
- }
- ModalComponentProps::Content(_) => {
- append_child(child, "content", map);
- }
- }
- }
-}
-
-fn append_child<'a>(
- child: ModalVariant,
- key: &'static str,
- map: &'a mut HashMap<&'static str, Vec>,
-) {
- let v = map.get_mut(key).unwrap();
-
- v.push(child.into());
-}
diff --git a/ui/src/common/modal/modal_action.rs b/ui/src/common/modal/modal_action.rs
deleted file mode 100644
index 55ab6a1..0000000
--- a/ui/src/common/modal/modal_action.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use material_yew::MatButton;
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, PartialEq, Clone)]
-pub struct ModalActionProps {
- pub label: &'static str,
- pub onclick: Callback,
-}
-
-#[function_component(ModalAction)]
-pub fn modal_action(props: &ModalActionProps) -> Html {
- let style = use_style!(
- r"
- margin: 0 10px;
- "
- );
- html! {
-
-
-
- }
-}
diff --git a/ui/src/common/modal/modal_content.rs b/ui/src/common/modal/modal_content.rs
deleted file mode 100644
index 310ba8e..0000000
--- a/ui/src/common/modal/modal_content.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use yew::prelude::*;
-
-#[derive(Properties, PartialEq, Clone)]
-pub struct ModalContentProps {
- pub children: Children,
-}
-
-#[function_component(ModalContent)]
-pub fn modal_content(props: &ModalContentProps) -> Html {
- html! {
- <>
- {props.children.clone()}
- >
- }
-}
diff --git a/ui/src/common/switch.rs b/ui/src/common/switch.rs
deleted file mode 100644
index c295e87..0000000
--- a/ui/src/common/switch.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use global::theme_context::ThemeAction;
-use global::theme_context::ThemeContext;
-use services::theme_service::Theme;
-use stylist::yew::styled_component;
-use yew::prelude::*;
-
-#[styled_component(ThemeSwitchBar)]
-pub fn theme_switch_bar() -> Html {
- let theme_ctx = use_context::().unwrap();
- let mobile_sliding_bar_offset_pos = if &theme_ctx.theme == &Theme::Dark {
- "100%"
- } else {
- "0"
- };
- let pc_sliding_bar_offset_pos = if &theme_ctx.theme == &Theme::Dark {
- "-100%"
- } else {
- "-190%"
- };
- let style = css!(
- r#"
- width: 43px;
- height: 130px;
- background: var(--primary-color);
- box-shadow: 0px 8px 24px 0px rgba(149, 157, 165, 0.5);
- border-radius: 13px;
- position: relative;
-
- .sliding-block {
- position: absolute;
- transform: translateY(${pc_offset});
- left: 0;
- width: 43px;
- height: 69px;
- border-radius: 13px;
- background: #fff;
- transition: all 0.3s ease-out;
- }
-
- .switch-bar {
- position: relative;
- z-index: 1;
- height: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- }
-
- .light-mode {
- width: 25px;
- height: 25px;
- }
-
- .dark-mode {
- width: 14.3px;
- height: 14.3px;
- }
-
- @media (max-width: 600px) {
- width: 100%;
- height: 43px;
- display: flex;
- align-items: center;
- margin-top: 33px;
-
- .switch-bar {
- width: 50%;
- height: 100%;
- }
-
- .sliding-block {
- width: 50%;
- top: 0;
- height: 100%;
- transform: translateX(${mobile_offset});
- }
- }
- "#,
- pc_offset = pc_sliding_bar_offset_pos,
- mobile_offset = mobile_sliding_bar_offset_pos
- );
-
- let handle_switch_bar_click = |theme: Theme| -> Callback {
- Callback::from(move |_| theme_ctx.dispatch(ThemeAction::UpdateTheme(theme.clone())))
- };
-
- html! {
-
-
-
-
-
-
-
-
-
- }
-}
diff --git a/ui/src/lib.rs b/ui/src/lib.rs
deleted file mode 100644
index dcef42c..0000000
--- a/ui/src/lib.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub mod common;
-pub mod link_card;
-pub mod post_card;
-pub mod project_card;
-pub mod theme;
-
-pub use common::*;
-pub use post_card::*;
-pub use project_card::*;
-pub use theme::*;
-use utils::use_style;
diff --git a/ui/src/link_card.rs b/ui/src/link_card.rs
deleted file mode 100644
index 3a11124..0000000
--- a/ui/src/link_card.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-use crate::link::Link;
-use services::links_service::links_service::LinkData;
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct LinkCardProps {
- pub link: LinkData,
-}
-
-#[function_component(LinkCard)]
-pub fn link_card(props: &LinkCardProps) -> Html {
- let style = style!(
- r"
- width: 250px;
- height: 98px;
- box-shadow: 0px 8px 50px 0px var(--card-shadow-color);
- background: var(--base-color);
- border-radius: 20px;
- margin: 0 15px;
- display: flex;
- align-items: center;
- padding: 10px 25px;
- box-sizing: border-box;
- margin-bottom: 25px;
-
-
- .logo {
- width: 55px;
- height: 55px;
- border-radius: 10px;
- }
-
- .link-info {
- margin-left: 12px;
- height: 60px;
- }
-
- .link-desc {
- font-size: 13px;
- color: var(--sub-text-color);
- line-height: 18px;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- height: 36px;
- text-overflow: ellipsis;
- display: -webkit-box;
- width: 150px;
- }
-
- .link-name {
- width: 150px;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: pre;
- }
-
- @media (max-width: 600px) {
- width: 100%;
- margin: auto;
- margin-bottom: 20px;
-
- .link-desc {
- width: 100%;
- }
-
- .link-name {
- width: 100%;
- }
- }
- "
- )
- .unwrap();
-
- html! {
-
-
-
-
-
{&props.link.name}
-
{&props.link.desc}
-
-
-
- }
-}
diff --git a/ui/src/post_card/label.rs b/ui/src/post_card/label.rs
deleted file mode 100644
index 6579440..0000000
--- a/ui/src/post_card/label.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct LabelProps {
- pub text: String,
-}
-
-#[function_component(Label)]
-pub fn label(props: &LabelProps) -> Html {
- let style = use_style!(
- r"
- padding: 7px 10px;
- background: var(--label-color);
- height: 31px;
- border-radius: 8px;
- box-sizing: border-box;
- display: flex;
- align-items: center;
- margin-bottom: 10px;
-
- .label-icon {
- width: 13.9px;
- height: 13.9px;
- margin-right: 9px;
- }
-
- .label-text {
- font-size: 12.48px;
- color: var(--text-color);
- }
- "
- );
-
- html! {
-
-
-
- {&props.text}
-
-
- }
-}
diff --git a/ui/src/post_card/mod.rs b/ui/src/post_card/mod.rs
deleted file mode 100644
index e24c835..0000000
--- a/ui/src/post_card/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub mod label;
-pub mod post_card;
-pub mod post_card_header;
-pub mod post_card_large;
-pub mod post_card_small;
diff --git a/ui/src/post_card/post_card.rs b/ui/src/post_card/post_card.rs
deleted file mode 100644
index b9f3076..0000000
--- a/ui/src/post_card/post_card.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use crate::post_card_large::PostCardLarge;
-use crate::post_card_small::PostCardSmall;
-use services::post_service::post_card_size::PostCardSize;
-use services::post_service::post_service::Post;
-use utils::theme::is_on_mobile;
-use yew::prelude::*;
-
-#[derive(PartialEq, Clone, Properties)]
-pub struct PostCardProps {
- pub post: Post,
- #[prop_or(PostCardSize::Large)]
- pub size: PostCardSize,
-}
-
-#[function_component(PostCard)]
-pub fn post_card(props: &PostCardProps) -> Html {
- if is_on_mobile() {
- return html! {
-
- };
- }
-
- match &props.size {
- PostCardSize::Large => html! {
-
- },
- PostCardSize::Small => html! {
-
- },
- }
-}
diff --git a/ui/src/post_card/post_card_header.rs b/ui/src/post_card/post_card_header.rs
deleted file mode 100644
index a91ed79..0000000
--- a/ui/src/post_card/post_card_header.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use crate::label::Label;
-use utils::use_style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct PostCardHeaderProps {
- pub label: String,
-}
-
-#[function_component(PostCardHeader)]
-pub fn post_card_header(props: &PostCardHeaderProps) -> Html {
- let style = use_style!(
- r"
- display: flex;
- align-items: center;
- width: 100%;
- justify-content: space-between;
-
-
- .avatar {
- width: 32px;
- height: 32px;
- }
-
- .author {
- display: flex;
- align-items: center;
- }
-
- .author-name {
- font-weight: bold;
- font-size: 17px;
- color: var(--text-color);
- margin-left: 8px;
- }
- "
- );
-
- html! {
-
-
-
-
{"Mist"}
-
-
-
- }
-}
diff --git a/ui/src/post_card/post_card_large.rs b/ui/src/post_card/post_card_large.rs
deleted file mode 100644
index cb06ebc..0000000
--- a/ui/src/post_card/post_card_large.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-use crate::link::Link;
-use crate::post_card_header::PostCardHeader;
-use router::RootRoutes;
-use services::post_service::post_service::Post;
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(PartialEq, Clone, Properties)]
-pub struct PostCardLargeProps {
- pub post: Post,
-}
-
-#[function_component(PostCardLarge)]
-pub fn post_card_large(props: &PostCardLargeProps) -> Html {
- let style = style!(
- r#"
- height: 330px;
- display: flex;
- border-radius: 17px;
- background: var(--base-color);
- overflow: hidden;
- box-shadow: 0px 7px 43px 0px var(--card-shadow-color);
- margin: 0 18px;
- margin-bottom: 35px;
-
- .cover {
- flex-shrink: 0;
- width: 446.51px;
- height: 330px;
- background-image: url("${cover}");
- background-repeat: no-repeat;
- background-size: cover;
- background-position: 50% 50%;
- }
-
- .post-preview {
- margin-left: 40px;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- padding: 23px 25px 10px 0;
- }
-
- .post-preview__body {
- width: 100%;
- word-break: break-all;
- font-size: 14.48px;
- color: var(--sub-text-color);
- line-height: 25px;
- -webkit-line-clamp: 6;
- -webkit-box-orient: vertical;
- overflow: hidden;
- height: 156px;
- text-overflow: ellipsis;
- display: -webkit-box;
- }
-
- .post-preview__title {
- font-size: 23px;
- font-weight: 600;
- color: var(--text-color);
- line-height: 33px;
- margin-top: 25px;
- margin-bottom: 10px;
- }
-
- .modified-at {
- display: flex;
- width: 100%;
- justify-content: flex-end;
- color: var(--tip-color);
- font-size: 10px;
- line-height: 15px;
- margin-top: 10px;
- }
- "#,
- cover = props.post.metadata.cover.clone()
- )
- .unwrap();
-
- html! {
-
-
-
-
-
-
-
{&props.post.metadata.title}
-
{&props.post.desc}
-
-
{&props.post.modified_time}
-
-
-
- }
-}
diff --git a/ui/src/post_card/post_card_small.rs b/ui/src/post_card/post_card_small.rs
deleted file mode 100644
index b2aaa86..0000000
--- a/ui/src/post_card/post_card_small.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-use crate::link::Link;
-use crate::post_card_header::PostCardHeader;
-use router::RootRoutes;
-use services::post_service::post_service::Post;
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct PostCardProps {
- pub post: Post,
-}
-
-#[function_component(PostCardSmall)]
-pub fn post_card_small(props: &PostCardProps) -> Html {
- let style = style!(
- r#"
- width: 250px;
- height: 350px;
- background: var(--base-color);
- box-shadow: 0px 7px 43px 0px var(--card-shadow-color);
- border-radius: 17.33px;
- box-sizing: border-box;
- padding: 18px;
- cursor: pointer;
- margin: 0 17px;
- margin-bottom: 35px;
-
- .cover {
- width: 236px;
- height: 134px;
- border-radius: 10px;
- margin: 13px -11px;
- margin-bottom: 0;
- background-image: url("${cover}");
- background-repeat: no-repeat;
- background-size: cover;
- background-position: 50% 50%;
- }
-
- .post-preview__title {
- font-size: 15.25px;
- font-weight: bold;
- color: var(--text-color);
- line-height: 26px;
- margin-top: 17px;
- }
-
- .post-preview__body {
- width: 100%;
- word-break: break-all;
- text-overflow: ellipsis;
- line-height: 22px;
- display: -webkit-box;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- overflow: hidden;
- margin-top: 4px;
- font-size: 14.48px;
- color: var(--sub-text-color);
- }
-
- .modified-at {
- color: var(--tip-color);
- font-size: 10px;
- line-height: 15px;
- margin-top: 10px;
- }
-
- @media (max-width: 600px) {
- width: 100%;
- margin: 0;
- margin-bottom: 33px;
-
- .cover {
- width: 100%;
- margin: 13px 0;
- }
- }
- "#,
- cover = props.post.metadata.cover.clone()
- )
- .unwrap();
-
- html! {
-
-
-
-
-
-
-
- {&props.post.metadata.title}
-
-
- {&props.post.desc}
-
-
-
{&props.post.modified_time}
-
-
-
- }
-}
diff --git a/ui/src/project_card.rs b/ui/src/project_card.rs
deleted file mode 100644
index 7320e37..0000000
--- a/ui/src/project_card.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-use crate::link::Link;
-use router::RootRoutes;
-use services::projects_service::projects_service::Project;
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct ProjectCardProps {
- pub project: Project,
-}
-
-#[function_component(ProjectCard)]
-pub fn project_card(props: &ProjectCardProps) -> Html {
- let style = style!(
- r#"
- width: 384px;
- box-shadow: 0px 8px 50px 0px var(--card-shadow-color);
- border-radius: 8px;
- padding: 15px 20px;
- background-color: var(--base-color);
- box-sizing: border-box;
- margin-bottom: 30px;
-
- .name {
- font-size: 20px;
- color: var(text-color);
- }
-
- .desc {
- font-size: 13px;
- color: var(--sub-text-color);
- }
-
- .summary {
- word-break: break-all;
- -webkit-line-clamp: 9;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- overflow: hidden;
- line-height: 25px;
- font-size: 14px;
- }
-
- .footer {
- text-align: right;
- font-size: 13px;
- margin-top: 10px;
- }
-
- .post-block {
- margin-top: 10px;
- }
-
- @media (max-width: 600px) {
- width: 100%;
- }
- "#
- )
- .unwrap();
-
- html! {
-
-
-
- {&props.project.name}
-
-
- {&props.project.desc}
-
-
- {
- match &props.project.post {
- Some(post) => {
- html! {
-
-
-
- }
- },
- None => html! {},
- }
- }
-
- }
-}
diff --git a/ui/src/theme/mod.rs b/ui/src/theme/mod.rs
deleted file mode 100644
index e55a1a7..0000000
--- a/ui/src/theme/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod theme_item;pub mod theme_selector;
diff --git a/ui/src/theme/theme_item.rs b/ui/src/theme/theme_item.rs
deleted file mode 100644
index 14216fa..0000000
--- a/ui/src/theme/theme_item.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use services::theme_service::Theme;
-use stylist::style;
-use yew::prelude::*;
-
-#[derive(Properties, Clone, PartialEq)]
-pub struct ThemeItemProps {
- pub source: &'static str,
- pub text: &'static str,
- pub theme: Theme,
- pub is_pick: bool,
- pub onclick: Callback,
-}
-
-#[function_component(ThemeItem)]
-pub fn theme_item(props: &ThemeItemProps) -> Html {
- let picked_calculator = |picked_value: &'static str| -> &'static str {
- if props.is_pick {
- picked_value
- } else {
- "0"
- }
- };
-
- let picked_border_radius = picked_calculator("10px");
- let picked_border_width = picked_calculator("2.5px");
- let picked_shadow = picked_calculator("var(--primary-shadow-color) 0px 8px 24px");
- let style = style!(
- r"
- display: flex;
- flex-direction: column;
- align-items: center;
-
- .theme-preview {
- width: 100px;
- transition: all 0.1s;
- border: 2.5px solid #7FD6C2;
- border-radius: 10px;
- box-sizing: border-box;
- border: 2.5px solid var(--primary-color);
- border-width: ${border_width};
- border-radius: ${border_radius};
- box-shadow: ${shadow};
- cursor: pointer;
- }
-
- .text {
- color: var(--text-color);
- font-size: 14px;
- margin-top: 8px;
- font-weight: bold;
- }
-
- @media (max-width: 600px) {
- margin: 5px 0;
-
- .text {
- font-size: 12px;
- }
- }
- ",
- border_radius = picked_border_radius,
- border_width = picked_border_width,
- shadow = picked_shadow
- )
- .unwrap();
-
- html! {
-
-
-
{props.text}
-
- }
-}
diff --git a/ui/src/theme/theme_selector.rs b/ui/src/theme/theme_selector.rs
deleted file mode 100644
index 31d15cf..0000000
--- a/ui/src/theme/theme_selector.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-use crate::theme::theme_item::ThemeItem;
-use global::theme_context::ThemeAction;
-use global::theme_context::ThemeContext;
-use services::theme_service::Theme;
-use services::theme_service::ThemeService;
-use stylist::style;
-use yew::prelude::*;
-
-struct ThemeItemData {
- source: &'static str,
- text: &'static str,
- theme: Theme,
-}
-
-static THEME_ITEMS: &[ThemeItemData; 3] = &[
- ThemeItemData {
- source: "/images/light_mode_skeleton.png",
- text: "Light",
- theme: Theme::Light,
- },
- ThemeItemData {
- source: "/images/dark_mode_skeleton.png",
- text: "Dark",
- theme: Theme::Dark,
- },
- ThemeItemData {
- source: "/images/auto_mode_skeleton.png",
- text: "Follow OS",
- theme: Theme::Auto,
- },
-];
-
-#[function_component(ThemeSelector)]
-pub fn theme_selector() -> Html {
- let current_theme = use_state_eq(|| ThemeService::get_theme_from_storage());
- let theme_ctx = use_context::().unwrap();
- let style = style!(
- r"
- .skeletons {
- width: 360px;
- display: flex;
- justify-content: space-between;
- }
-
- .skeleton {
- width: 100px;
- }
-
- .follow-os-theme-wrapper {
- display: flex;
- align-items: center;
- }
-
- @media (max-width: 600px) {
- .skeletons {
- width: 100%;
- display: flex;
- flex-direction: column;
- }
- }
- "
- )
- .unwrap();
- let handle_theme_item_click = |theme: &Theme| -> Callback {
- let theme = theme.clone();
- let current_theme = current_theme.clone();
-
- Callback::from(move |_| {
- current_theme.set(theme.clone());
- theme_ctx.dispatch(ThemeAction::UpdateTheme(theme.clone()));
- })
- };
- use_effect({
- let current_theme = current_theme.clone();
-
- move || {
- current_theme.set(ThemeService::get_theme_from_storage());
- || ()
- }
- });
-
- html! {
-
-
- {THEME_ITEMS.into_iter().map(|data| {
- html! {
-
- }
- }).collect::()}
-
-
- }
-}
diff --git a/utils/.gitignore b/utils/.gitignore
deleted file mode 100644
index 96ef6c0..0000000
--- a/utils/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/target
-Cargo.lock
diff --git a/utils/Cargo.toml b/utils/Cargo.toml
deleted file mode 100644
index e63dd56..0000000
--- a/utils/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "utils"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-web-sys = { version = "0.3", features = ["HtmlMetaElement", "Document", "Element", "DocumentFragment", "HtmlTemplateElement", "MediaQueryList"] }
-js-sys = "0.3.55"
-global = {path = "../global"}
-services = {path = "../services"}
-yew = "0.19.3"
-chrono = "0.4.19"
-wasm-bindgen = "0.2.80"
diff --git a/utils/src/error.rs b/utils/src/error.rs
deleted file mode 100644
index 665789c..0000000
--- a/utils/src/error.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use crate::console_log;
-use std::fmt::Display;
-
-pub trait ErrorDebug {
- fn debug(&self) -> &T;
-}
-
-impl ErrorDebug for Result
-where
- E: Display,
-{
- fn debug(&self) -> &T {
- match &self {
- Ok(data) => data,
- Err(err) => {
- console_log!("{}", err);
- panic!("{}", err)
- }
- }
- }
-}
diff --git a/utils/src/html.rs b/utils/src/html.rs
deleted file mode 100644
index d4049f3..0000000
--- a/utils/src/html.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use yew::prelude::*;
-
-pub fn render_with_insert_node(nodes: &Vec, node: &Html) -> Html {
- let render_nodes = nodes[1..].iter();
- let rendered_nodes = render_nodes
- .map(|render_node| {
- html! {
- <>
- {render_node.clone()}
- {node.clone()}
- >
- }
- })
- .collect::();
-
- html! {
- <>
- {rendered_nodes}
- {nodes.get(0).unwrap().clone()}
- >
- }
-}
diff --git a/utils/src/lib.rs b/utils/src/lib.rs
deleted file mode 100644
index 439498e..0000000
--- a/utils/src/lib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub mod error;
-pub mod html;
-pub mod logger;
-pub mod resource;
-pub mod style;
-pub mod theme;
-pub mod time;
diff --git a/utils/src/logger.rs b/utils/src/logger.rs
deleted file mode 100644
index d6ba17e..0000000
--- a/utils/src/logger.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#[macro_export]
-macro_rules! console_log {
- ( $( $t:tt )* ) => {
- web_sys::console::log_1(&format!( $( $t )* ).into());
- }
-}
-
-#[macro_export]
-macro_rules! console_error {
- ( $( $t:tt )* ) => {
- web_sys::console::error_1(&format!( $( $t )* ).into());
- }
-}
diff --git a/utils/src/resource.rs b/utils/src/resource.rs
deleted file mode 100644
index 5669e27..0000000
--- a/utils/src/resource.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use services::theme_service::Theme;
-
-const BASE_IMAGE_PATH: &'static str = "images";
-
-pub fn with_assets(img_name: &str) -> String {
- format!("/{}/{}", BASE_IMAGE_PATH, img_name)
-}
-
-pub fn with_assets_by_theme(img_name: &str, theme: &Theme) -> String {
- format!("/{}/${}_{}", BASE_IMAGE_PATH, theme.into_str(), img_name)
-}
diff --git a/utils/src/style.rs b/utils/src/style.rs
deleted file mode 100644
index 0b791d7..0000000
--- a/utils/src/style.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[macro_export]
-macro_rules! use_style {
- ($arg:tt) => {{
- stylist::style!($arg).unwrap().get_class_name().to_string()
- }};
-}
diff --git a/utils/src/theme.rs b/utils/src/theme.rs
deleted file mode 100644
index 08701a2..0000000
--- a/utils/src/theme.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use services::theme_service::Theme;
-use services::theme_service::ThemeService;
-use yew::prelude::*;
-use yew::virtual_dom::VNode;
-
-pub fn by_theme(light: T, dark: T) -> T {
- let theme_service = ThemeService::from_storage();
- let theme = theme_service.get_theme();
-
- if theme == &Theme::Dark {
- dark
- } else {
- light
- }
-}
-
-pub fn is_on_mobile() -> bool {
- web_sys::window()
- .unwrap()
- .match_media("(max-width: 600px)")
- .unwrap()
- .unwrap()
- .matches()
-}
-
-pub fn only_render_on_pc(vnode: VNode) -> VNode {
- if is_on_mobile() {
- html! {}
- } else {
- vnode
- }
-}
-
-pub fn only_render_on_mobile(vnode: VNode) -> VNode {
- if is_on_mobile() {
- vnode
- } else {
- html! {}
- }
-}
-
-pub fn by_reactive(mobile: T, pc: T) -> T {
- if is_on_mobile() {
- mobile
- } else {
- pc
- }
-}
-
-pub fn with_reactive_source(source: String) -> String {
- if is_on_mobile() {
- format!("$mobile_{}", source)
- } else {
- source
- }
-}
diff --git a/utils/src/time.rs b/utils/src/time.rs
deleted file mode 100644
index f52e81f..0000000
--- a/utils/src/time.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use chrono::prelude::*;
-use std::time::{Duration, UNIX_EPOCH};
-use wasm_bindgen::closure::Closure;
-use wasm_bindgen::JsCast;
-
-pub fn format_timestamp(timestamp: u64, format_str: &'static str) -> String {
- let date = UNIX_EPOCH + Duration::from_millis(timestamp);
- let datetime = DateTime::::from(date);
-
- datetime.format(format_str).to_string()
-}
-
-pub fn format_time_string(timestring: &str, format_str: &'static str) -> String {
- let datetime = DateTime::parse_from_rfc3339(timestring).unwrap();
-
- datetime.format(format_str).to_string()
-}
-
-// pub fn set_interval(callback: F, delay: i32) -> i32
-// where
-// F: Fn() + 'static,
-// {
-// let mut clear_fn: Option<_> = None;
-// let callback = || {
-// // callback();
-// };
-// let window = web_sys::window().unwrap();
-// let callback = Closure::wrap(Box::new(callback) as Box);
-// let id = window
-// .set_interval_with_callback_and_timeout_and_arguments_0(
-// callback.as_ref().unchecked_ref(),
-// delay,
-// )
-// .unwrap();
-
-// clear_fn = Some(move || window.clear_interval_with_handle(id));
-// id
-// }
-
-pub fn set_timeout(callback: F, timeout: i32)
-where
- F: Fn() + 'static,
-{
- let window = web_sys::window().unwrap();
- let callback = Closure::wrap(Box::new(callback) as Box);
-
- window
- .set_timeout_with_callback_and_timeout_and_arguments_0(
- callback.as_ref().unchecked_ref(),
- timeout,
- )
- .unwrap();
-}
diff --git a/vercel.json b/vercel.json
deleted file mode 100644
index 7cf4c77..0000000
--- a/vercel.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "rewrites": [
- {
- "source": "/(.*)",
- "destination": "/index.html"
- }
- ]
-}