diff --git a/.gitignore b/.gitignore index d01bd1a..0b58c0b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ Cargo.lock # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +# Test binaries +*.exe \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index c49c225..d3e5213 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,6 @@ repository = "https://github.com/Administroot/FreeEta" [dependencies] iced = {version = "0.13.1", features = ["image", "svg", "tokio", "advanced"] } -tokio = {version = "1.43.0", features = ["time", "full"]} \ No newline at end of file +tokio = {version = "1.43.0", features = ["time", "full"]} +serde = "1.0" +serde_yml = "0.0.11" \ No newline at end of file diff --git a/README.md b/README.md index b9b7d61..5ae42d9 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@
-# FreeEta +# ![LOGO](static/svg/logo.svg) FreeEta [![Crates.io](https://img.shields.io/crates/v/FreeEta.svg)](https://crates.io/crates/FreeEta) -[![License](https://img.shields.io/crates/l/FreeEta.svg)](https://github.com/Administroot/FreeEta/blob/main/LICENSE) +![GitHub License](https://img.shields.io/github/license/Administroot/FreeEta) [![Downloads](https://img.shields.io/crates/d/FreeEta.svg)](https://github.com/Administroot/FreeEta/releases/latest) -[![Test Status](https://img.shields.io/github/actions/workflow/status/administroot/FreeEta/test.yml?branch=master&event=push&label=test)](https://github.com/administroot/FreeEta/actions) +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/Administroot/FreeEta/rust.yml) [![Made with iced](https://iced.rs/badge.svg)](https://github.com/iced-rs/iced) A fast, elegant & free ETA analysis utility powered by ๐Ÿฆ€ Rust, ๐ŸงŠ iced. @@ -14,7 +14,9 @@ A fast, elegant & free ETA analysis utility powered by ๐Ÿฆ€ Rust, ๐ŸงŠ iced.
-> โ—โ—โ—Main functions are not yet! +> [!danger]+ +> Freeeta is on flight๐Ÿ›ซ +> ## Installation @@ -22,10 +24,13 @@ A fast, elegant & free ETA analysis utility powered by ๐Ÿฆ€ Rust, ๐ŸงŠ iced. Get it on Github -Support windows / linux / MacOS! Or use `cargo` to try it out: +Support windows / linux / MacOS! + +Or use `cargo` to try it out: ```bash cargo install --git https://github.com/administroot/FreeEta.git +``` ## Why "FreeEta"? diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..01e213f --- /dev/null +++ b/config.yml @@ -0,0 +1,3 @@ +name: FreeEta +lang: zh-cn +theme: Light diff --git a/src/freeeta_buttons.rs b/src/freeeta_buttons.rs new file mode 100644 index 0000000..a67ea5d --- /dev/null +++ b/src/freeeta_buttons.rs @@ -0,0 +1,67 @@ +use crate::freeeta_styles; +use crate::main_menu::MainMenuMessage; +use iced::widget::text::LineHeight; +use iced::widget::tooltip::Position; +use iced::widget::{button, Text, Tooltip}; +use iced::{Alignment, Color, Font, Pixels, Theme}; + +#[allow(dead_code)] +/// Button 'ร—' +pub fn button_hide<'a>( + message: MainMenuMessage, + font: Font, +) -> Tooltip<'a, MainMenuMessage, Theme> { + Tooltip::new( + button( + Text::new("ร—") + .font(font) + .align_y(Alignment::Center) + .align_x(Alignment::Center) + .size(15) + .line_height(LineHeight::Relative(1.0)), + ) + .padding(2) + .height(20) + .width(20) + .on_press(message), + Text::new("Cancel").font(font), + Position::Right, + ) + .gap(5) +} + +/// Bookmark +pub fn bookmark<'a>( + message: MainMenuMessage, + font: Font, + inner_text: &str, + color: Color, + is_actived: bool, +) -> Tooltip<'a, MainMenuMessage, Theme> { + let mut button = button( + Text::new(inner_text.to_string()) + .font(font) + .align_y(Alignment::Center) + .align_x(Alignment::Center) + .line_height(LineHeight::Relative(1.0)), + ) + .style(move |theme, status| freeeta_styles::bookmark_style(theme, status, color, is_actived)) + .height(40) + .on_press(message); + + // Lengthen and hignlight the button when activated + button = match is_actived { + true => button.width(80), + false => button.width(60), + }; + + let bookmark = Tooltip::new( + button, + Text::new("Press to active / deactive") + .font(font) + .size(Pixels { 0: 15f32 }), + Position::Right, + ) + .gap(5); + return bookmark; +} diff --git a/src/freeeta_picklists.rs b/src/freeeta_picklists.rs new file mode 100644 index 0000000..796a2e9 --- /dev/null +++ b/src/freeeta_picklists.rs @@ -0,0 +1,28 @@ +use std::borrow::Borrow; + +use iced::widget::pick_list; +use iced::{ + widget::{text::Shaping, PickList}, + Length, +}; + +/// Picklist to select functions. +pub fn functional_picklist<'a, T, L, V, Message, Theme, Renderer>( + options: L, + selected: Option, + on_selected: impl Fn(T) -> Message + 'a, + placeholder: &str, +) -> PickList<'a, T, L, V, Message, Theme, Renderer> +where + T: ToString + PartialEq + Clone + 'a, + L: Borrow<[T]> + 'a, + V: Borrow + 'a, + Message: Clone, + Theme: iced::widget::pick_list::Catalog + iced::widget::overlay::menu::Catalog, + Renderer: iced::advanced::text::Renderer, +{ + pick_list::<'a, T, L, V, Message, Theme, Renderer>(options, selected, on_selected) + .width(Length::Shrink) + .placeholder(placeholder) + .text_shaping(Shaping::Advanced) +} diff --git a/src/freeeta_styles.rs b/src/freeeta_styles.rs index 97cebdd..f4c9ee9 100644 --- a/src/freeeta_styles.rs +++ b/src/freeeta_styles.rs @@ -1,27 +1,11 @@ -use iced::{border::Radius, widget::pick_list, Background, Border, Color, Theme}; - -// pub fn radio_selected(_theme: &Theme, _status: radio::Status) -> radio::Style { -// radio::Style { -// text_color: Some(Color::from_rgb(0., 0., 1.)), -// background: Background::Color(Color::from_rgb(1., 1., 1.)), -// dot_color: Color::from_rgb(0., 0., 1.), -// border_width: 1.0, -// border_color: Color::from_rgb(0., 0., 1.), -// } -// } - -// pub fn radio_unselected(_theme: &Theme, _status: radio::Status) -> radio::Style { -// radio::Style { -// text_color: Some(Color::from_rgb(0.5, 0.5, 0.5)), -// background: Background::Color(Color::from_rgb(1., 1., 1.)), -// dot_color: Color::from_rgb(0., 0., 1.), -// border_width: 1.0, -// border_color: Color::from_rgb(0., 0., 1.), -// } -// } +use iced::{ + border::Radius, + widget::{button, pick_list, text}, + Background, Border, Color, Theme, +}; // TODO: Read Theme from const in the future. -pub fn pick_list_unselected(_theme: &Theme, _status: pick_list::Status) -> pick_list::Style { +pub fn functional_picklist_style(_theme: &Theme, _status: pick_list::Status) -> pick_list::Style { pick_list::Style { text_color: Color::from_rgb(0.09, 0.02, 0.08), placeholder_color: Color::from_rgb(0.09, 0.02, 0.08), @@ -39,3 +23,75 @@ pub fn pick_list_unselected(_theme: &Theme, _status: pick_list::Status) -> pick_ }, } } + +pub fn bottomline_text_unselected(_theme: &Theme) -> text::Style { + text::Style { + color: Some(Color::from_rgb(0.35, 0.35, 0.34)), + } +} + +/// Returns the average of two colors; color intensity is fixed to 100% +fn mix_colors(color_1: Color, color_2: Color) -> Color { + Color { + r: (color_1.r + color_2.r) / 2.0, + g: (color_1.g + color_2.g) / 2.0, + b: (color_1.b + color_2.b) / 2.0, + a: 1.0, + } +} + +/// Half transparency of the given color. +fn half_transparency(color: Color) -> Color { + Color { + r: color.r, + g: color.g, + b: color.b, + a: color.a / 2.0, + } +} + +pub fn bookmark_style( + _theme: &Theme, + status: button::Status, + color: Color, + is_actived: bool, +) -> button::Style { + let text_color = Color::BLACK; + let border = Border { + color, + width: 2., + radius: Radius { + top_left: 0., + top_right: 5., + bottom_right: 5., + bottom_left: 0., + }, + }; + + match (status, is_actived) { + (button::Status::Active, true) => button::Style { + background: Some(Background::Color(color)), + text_color, + border, + ..Default::default() + }, + (button::Status::Hovered, _) => button::Style { + background: Some(Background::Color(mix_colors(Color::WHITE, color))), + text_color, + border, + ..Default::default() + }, + (button::Status::Pressed, _) => button::Style { + background: Some(Background::Color(color)), + text_color, + border, + ..Default::default() + }, + (_, _) => button::Style { + background: Some(Background::Color(half_transparency(color))), + text_color, + border, + ..Default::default() + }, + } +} \ No newline at end of file diff --git a/src/freeeta_yml.rs b/src/freeeta_yml.rs new file mode 100644 index 0000000..65fc34e --- /dev/null +++ b/src/freeeta_yml.rs @@ -0,0 +1,34 @@ +use serde::{Deserialize, Serialize}; +use std::fs::{self, File}; + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct FreeEtaConfig { + /// Software name: typically "FreeEta" + name: String, + /// Language: ["zh-cn", "en-us"] + lang: String, + /// Theme: Default "Light"; Others see [iced::theme::Theme](https://docs.rs/iced/0.13.1/iced/theme/enum.Theme.html) + theme: String, +} + +/// Read FreeEta config from ./ +pub fn read_freeeta_config() -> Result { + let path = "config.yml"; + if !fs::exists(path).unwrap() { + // If config doesn't exist, create a default config. + File::create(path).unwrap(); + let default_config = FreeEtaConfig { + name: "FreeEta".to_string(), + lang: "zh-cn".to_string(), + theme: "Light".to_string(), + }; + let yaml = serde_yml::to_string(&default_config)?; + fs::write(path, yaml).expect("Cannot write config.yml"); + return Ok(default_config); + } else { + // If config exists, read from it. + let contents = fs::read_to_string(path).expect("Cannot read config.yml"); + let deserialized_config: FreeEtaConfig = serde_yml::from_str(&contents)?; + return Ok(deserialized_config); + } +} diff --git a/src/main.rs b/src/main.rs index f7af803..a88bc23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,22 @@ +mod freeeta_buttons; +mod freeeta_picklists; mod freeeta_styles; +mod freeeta_yml; mod main_menu; +mod pages; use iced; fn main() -> iced::Result { + let freeeta_yml = freeeta_yml::read_freeeta_config().expect("[ERROR] CONFIG ERROR"); + // TODO: Deal with the config struct. + println!("{:?}", freeeta_yml); iced::application( "FreeEta", main_menu::FreeEta::update, main_menu::FreeEta::view, ) + .theme(main_menu::FreeEta::theme) + .subscription(main_menu::FreeEta::subscription) .run() } diff --git a/src/main_menu.rs b/src/main_menu.rs index c47155e..183cf65 100644 --- a/src/main_menu.rs +++ b/src/main_menu.rs @@ -1,12 +1,27 @@ +use iced::widget::{svg, text}; use iced::{ - widget::{column, container, horizontal_space, pick_list, row, svg, svg::Handle}, - ContentFit, Element, Task, + alignment, + event::{self, Status}, + mouse::Event::CursorMoved, + touch::Event::FingerMoved, + widget::{ + column, container, horizontal_rule, horizontal_space, row, svg::Handle, vertical_space, + }, + Color, ContentFit, Element, Event, Font, Point, Subscription, Task, }; -use crate::freeeta_styles; +use crate::{freeeta_buttons, freeeta_picklists::functional_picklist, freeeta_styles}; +use crate::pages::Pages; pub struct FreeEta { + // TODO: Actually, I don't need this member. file_picklist: Option, + mouse_point: Point, + view_bookmark_status: bool, + eta_bookmark_status: bool, + developer_bookmark_status: bool, + export_bookmark_status: bool, + page: Pages, } impl Default for FreeEta { @@ -17,7 +32,16 @@ impl Default for FreeEta { #[derive(Debug, Clone)] pub enum MainMenuMessage { - DoNothing, + FilePicklistMsg(String), + GraphicsPicklistMsg(String), + AnalysisPicklistMsg(String), + SettingsPicklistMsg(String), + HelpPicklistMsg(String), + PointUpdated(Point), + ViewBookmarkMsg, + EtaBookmarkMsg, + DeveloperBookmarkMsg, + ExportBookmarkMsg, } impl FreeEta { @@ -25,72 +49,254 @@ impl FreeEta { ( Self { file_picklist: None, + mouse_point: Point::ORIGIN, + view_bookmark_status: false, + eta_bookmark_status: false, + developer_bookmark_status: false, + export_bookmark_status: false, + page: Pages::MainMenuPage, }, Task::none(), ) } - pub fn update(&mut self, _message: MainMenuMessage) -> Task { + pub fn update(&mut self, message: MainMenuMessage) -> Task { + match message { + MainMenuMessage::FilePicklistMsg(s) => { + // TODO: Divide different sections + self.file_picklist = Some(s); + } + MainMenuMessage::PointUpdated(p) => { + self.mouse_point = p; + } + MainMenuMessage::GraphicsPicklistMsg(s) => { + // TODO: Divide different sections + self.file_picklist = Some(s); + } + MainMenuMessage::AnalysisPicklistMsg(s) => { + // TODO: Divide different sections + self.file_picklist = Some(s); + } + MainMenuMessage::SettingsPicklistMsg(s) => { + // TODO: Divide different sections + self.file_picklist = Some(s); + } + MainMenuMessage::HelpPicklistMsg(s) => { + // TODO: Divide different sections + self.file_picklist = Some(s); + } + MainMenuMessage::ViewBookmarkMsg => { + self.view_bookmark_status = !self.view_bookmark_status; + if self.view_bookmark_status { + // Close other bookmarks + self.eta_bookmark_status = false; + self.developer_bookmark_status = false; + self.export_bookmark_status = false; + // Open corresponding page + self.page = Pages::InterfacePage; + } + } + MainMenuMessage::EtaBookmarkMsg => { + self.eta_bookmark_status = !self.eta_bookmark_status; + if self.eta_bookmark_status { + // Close other bookmarks + self.view_bookmark_status = false; + self.developer_bookmark_status = false; + self.export_bookmark_status = false; + // Open corresponding page + self.page = Pages::ChartPage; + } + } + MainMenuMessage::DeveloperBookmarkMsg => { + self.developer_bookmark_status = !self.developer_bookmark_status; + if self.developer_bookmark_status { + // Close other bookmarks + self.view_bookmark_status = false; + self.eta_bookmark_status = false; + self.export_bookmark_status = false; + // Open corresponding page + self.page = Pages::DeveloperPage; + } + } + MainMenuMessage::ExportBookmarkMsg => { + self.export_bookmark_status = !self.export_bookmark_status; + if self.export_bookmark_status { + // Close other bookmarks + self.view_bookmark_status = false; + self.eta_bookmark_status = false; + self.developer_bookmark_status = false; + // Open corresponding page + self.page = Pages::ExportPage; + } + } + } Task::none() } pub fn view(&self) -> Element { + let file_picklist = functional_picklist( + [ + "๐Ÿ†• New.. ", + "๐Ÿ“‚ Open..", + "๐Ÿ”Ž Open Recent", + "๐Ÿ’พ Save", + "๐Ÿ“ค Export", + ] + .map(|s| s.to_string()) + .to_vec(), + self.file_picklist.clone(), + |s| MainMenuMessage::FilePicklistMsg(s), + "๐Ÿ“ File", + ) + .style(freeeta_styles::functional_picklist_style); + let graphics_picklist = functional_picklist( + // FIXME: Better use container[svg/png] + ["โ›ฝ Pop", "๐ŸŒ€ Valve", "โž• Add more..."] + .map(|s| s.to_string()) + .to_vec(), + self.file_picklist.clone(), + |s| MainMenuMessage::GraphicsPicklistMsg(s), + "๐Ÿ’  Graphics", + ) + .style(freeeta_styles::functional_picklist_style); + let analysis_picklist = functional_picklist( + ["๐ŸŒฒ Draw ETA Tree", "๐Ÿ“‰ Calculate Success & Failure Rates"] + .map(|s| s.to_string()) + .to_vec(), + self.file_picklist.clone(), + |s| MainMenuMessage::AnalysisPicklistMsg(s), + "๐Ÿงญ Analysis", + ) + .style(freeeta_styles::functional_picklist_style); + let settings_picklist = functional_picklist( + ["๐Ÿ”ฎ Themes", "๐Ÿ—ฃ๏ธ Languages"] + .map(|s| s.to_string()) + .to_vec(), + self.file_picklist.clone(), + |s| MainMenuMessage::SettingsPicklistMsg(s), + "โš™๏ธ Settings", + ) + .style(freeeta_styles::functional_picklist_style); + let help_picklist = functional_picklist( + ["๐Ÿ“” FreeEta Handbook", "๐ŸŒ About FreeEta", "๐ŸงŠ About ICED"] + .map(|s| s.to_string()) + .to_vec(), + self.file_picklist.clone(), + |s| MainMenuMessage::HelpPicklistMsg(s), + "๐Ÿค Help", + ) + .style(freeeta_styles::functional_picklist_style); + + let view_bookmark = freeeta_buttons::bookmark( + MainMenuMessage::ViewBookmarkMsg, + Font::default(), + "View", + Color::from_rgb(0.92, 0.21, 0.36), + self.view_bookmark_status, + ); + let eta_bookmark = freeeta_buttons::bookmark( + MainMenuMessage::EtaBookmarkMsg, + Font::default(), + "ETA", + Color::from_rgb(0., 0.64, 0.51), + self.eta_bookmark_status, + ); + let developer_bookmark = freeeta_buttons::bookmark( + MainMenuMessage::DeveloperBookmarkMsg, + Font::default(), + "Developer", + Color::from_rgb(0.88, 0.6, 0.71), + self.developer_bookmark_status, + ); + let export_bookmark = freeeta_buttons::bookmark( + MainMenuMessage::ExportBookmarkMsg, + Font::default(), + "Export", + Color::from_rgb(0.95, 0.6, 0.), + self.export_bookmark_status, + ); + + let logo = container( + svg(Handle::from_path("static/svg/logo.svg")) + .width(32.) + .height(32.) + .content_fit(ContentFit::ScaleDown), + ) + .padding(0u16) + .style(container::rounded_box); + + let mouse_position = + text(format!("{:?}", self.mouse_point)).color(Color::from_rgb(0.96, 0.31, 0.64)); + let admonition = text( + "| CopyrightยฉShanghai Justlinking Safety Technology co.,ltd. \ + Administroot ", + ) + .style(freeeta_styles::bottomline_text_unselected) + .align_x(alignment::Horizontal::Center); + + let screen = match self.page { + Pages::MainMenuPage => self.main_menu_page(), + Pages::InterfacePage => self.interface_page(), + Pages::ChartPage => self.chart_page(), + Pages::DeveloperPage => self.developer_page(), + Pages::ExportPage => self.export_page(), + }; + column!( - // Funtion row + // Functional row row![ - // File - pick_list( - ["Other choices 1", "Other choices 2"] - .map(|s| s.to_string()) - .to_vec(), - self.file_picklist.clone(), - |_| MainMenuMessage::DoNothing, - ) - .placeholder("File") - .style(freeeta_styles::pick_list_unselected), - // Graphics - pick_list( - ["Other choices 1", "Other choices 2"] - .map(|s| s.to_string()) - .to_vec(), - self.file_picklist.clone(), - |_| MainMenuMessage::DoNothing, - ) - .placeholder("Graphics") - .style(freeeta_styles::pick_list_unselected), - // Tools - pick_list( - ["Other choices 1", "Other choices 2"] - .map(|s| s.to_string()) - .to_vec(), - self.file_picklist.clone(), - |_| MainMenuMessage::DoNothing, - ) - .placeholder("Tools") - .style(freeeta_styles::pick_list_unselected), - // Helps - pick_list( - ["Other choices 1", "Other choices 2"] - .map(|s| s.to_string()) - .to_vec(), - self.file_picklist.clone(), - |_| MainMenuMessage::DoNothing, - ) - .placeholder("Helps") - .style(freeeta_styles::pick_list_unselected), - // Space[ ] + file_picklist, + graphics_picklist, + analysis_picklist, + settings_picklist, + help_picklist, horizontal_space(), - // FreeEta logo - container( - svg(Handle::from_path("assets/logo.svg")) - .width(32.) - .height(32.) - .content_fit(ContentFit::ScaleDown) - ) - .padding(0u16) - .style(container::rounded_box) - ] + logo, + ], + horizontal_rule(0), + vertical_space(), + // Body + container( + row![ + // Bookmarks + column![ + view_bookmark, + eta_bookmark, + developer_bookmark, + export_bookmark, + ] + .spacing(10.) + .align_x(alignment::Horizontal::Left), + + // Canvas + screen + ].spacing(10) + ) + .align_x(alignment::Horizontal::Left), + vertical_space(), + // Bottom row + horizontal_rule(0), + row![mouse_position, admonition].align_y(alignment::Vertical::Bottom) ) .into() } + + pub fn theme(&self) -> iced::Theme { + // TODO: Read from config struct var. + iced::Theme::Light + } + + pub fn subscription(&self) -> Subscription { + event::listen_with(|event, status, _window| { + match (event, status) { + // Using mouse + (Event::Mouse(CursorMoved { position }), Status::Ignored) + // Or using touchboard + | (Event::Touch(FingerMoved {position, ..}), Status::Ignored) => { + Some(MainMenuMessage::PointUpdated(position)) + } + _ => None + } + }) + } } diff --git a/src/pages.rs b/src/pages.rs new file mode 100644 index 0000000..ac9afa4 --- /dev/null +++ b/src/pages.rs @@ -0,0 +1,45 @@ +use iced::{alignment, widget::{container, text, Container}}; + +use crate::main_menu::{FreeEta, MainMenuMessage}; + +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +pub enum Pages { + #[default] + MainMenuPage, + InterfacePage, + ChartPage, + DeveloperPage, + ExportPage, +} + +impl FreeEta { + pub fn main_menu_page(&self) -> Container{ + container( + text("Hello, FreeEta!").size(80), + ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into() + } + + pub fn interface_page(&self) -> Container{ + container( + text("Hello, interface page!").size(70), + ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into() + } + + pub fn chart_page(&self) -> Container{ + container( + text("Hello, chart page!").size(65), + ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into() + } + + pub fn developer_page(&self) -> Container{ + container( + text("Hello, developer page!").size(60), + ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into() + } + + pub fn export_page(&self) -> Container{ + container( + text("Hello, export page!").size(50), + ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into() + } +} \ No newline at end of file diff --git a/static/png/Bookmark_View.png b/static/png/Bookmark_View.png new file mode 100644 index 0000000..8114e52 Binary files /dev/null and b/static/png/Bookmark_View.png differ diff --git a/assets/calculator.svg b/static/svg/calculator.svg similarity index 100% rename from assets/calculator.svg rename to static/svg/calculator.svg diff --git a/assets/code-slash.svg b/static/svg/code-slash.svg similarity index 100% rename from assets/code-slash.svg rename to static/svg/code-slash.svg diff --git a/assets/file-add.svg b/static/svg/file-add.svg similarity index 100% rename from assets/file-add.svg rename to static/svg/file-add.svg diff --git a/static/svg/get_it_on_github.svg b/static/svg/get_it_on_github.svg new file mode 100644 index 0000000..5398824 --- /dev/null +++ b/static/svg/get_it_on_github.svg @@ -0,0 +1,55 @@ + + + + + + + + + + image/svg+xml + + + + + Andrew Nayenko + + + + + https://f-droid.org + + + + + + + + + + + + + + + + + + + + + + GET IT ON + GitHub + + + + + + + + + + + + diff --git a/assets/logo.svg b/static/svg/logo.svg similarity index 100% rename from assets/logo.svg rename to static/svg/logo.svg diff --git a/assets/menu-boxed.svg b/static/svg/menu-boxed.svg similarity index 100% rename from assets/menu-boxed.svg rename to static/svg/menu-boxed.svg diff --git a/assets/more-r.svg b/static/svg/more-r.svg similarity index 100% rename from assets/more-r.svg rename to static/svg/more-r.svg diff --git a/assets/shape-hexagon.svg b/static/svg/shape-hexagon.svg similarity index 100% rename from assets/shape-hexagon.svg rename to static/svg/shape-hexagon.svg diff --git a/assets/software-download.svg b/static/svg/software-download.svg similarity index 100% rename from assets/software-download.svg rename to static/svg/software-download.svg diff --git a/assets/software-upload.svg b/static/svg/software-upload.svg similarity index 100% rename from assets/software-upload.svg rename to static/svg/software-upload.svg diff --git a/assets/view-comfortable.svg b/static/svg/view-comfortable.svg similarity index 100% rename from assets/view-comfortable.svg rename to static/svg/view-comfortable.svg