add frontend and put backend in seperate folder

This commit is contained in:
lukas committed 2023-12-27 16:45:55 +01:00
1 parent d409d08572
commit 6faa995b19
88 files changed
+2993 -12

No files matched your search

+14 -6
View File
@@ -1,4 +1,9 @@
# Stage 1: Build the Rust binary
FROM ghcr.io/cirruslabs/flutter:latest AS frontend_builder
WORKDIR /app
COPY frontend /app
RUN flutter build web --release
FROM rust AS builder
# Install necessary tools and dependencies
@@ -6,13 +11,15 @@ FROM rust AS builder
WORKDIR /app
# Copy the Rust project files
COPY ./src /app/src
COPY ./scripts /app/scripts
COPY Cargo.lock /app
COPY Cargo.toml /app
COPY backend/src /app/src
COPY backend/scripts /app/scripts
COPY backend/Cargo.lock /app
COPY backend/Cargo.toml /app
COPY --from=frontend_builder /app/build/web /app/web
# Build the Rust binary
RUN cargo build --release
RUN cargo build --release --features static
# Stage 2: Create the final image
FROM archlinux
@@ -20,6 +27,7 @@ FROM archlinux
# Copy the built binary from the previous stage
COPY --from=builder /app/target/release/untitled /usr/local/bin/untitled
RUN pacman -Syyu --noconfirm
RUN pacman -S --noconfirm base-devel git
RUN pacman -Sc
+63
View File
@@ -2156,6 +2156,40 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rust-embed"
version = "8.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "8.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.42",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "8.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40"
dependencies = [
"sha2",
"walkdir",
]
[[package]]
name = "rust_decimal"
version = "1.33.1"
@@ -2233,6 +2267,15 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.22"
@@ -3346,6 +3389,7 @@ dependencies = [
"reqwest",
"rocket",
"rocket_okapi",
"rust-embed",
"sea-orm",
"sea-orm-migration",
"serde",
@@ -3409,6 +3453,16 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
@@ -3528,6 +3582,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
+6 -3
View File
@@ -20,9 +20,12 @@ rocket_okapi = { version = "0.8.0-rc.3", features = ["swagger"] }
sea-orm = { version = "0.12", features = [ "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] }
sea-orm-migration = {version = "0.12", features = ["sqlx-sqlite", "runtime-tokio-rustls"]}
serde = "1.0.193"
rust-embed = "8.1.0"
[[bin]]
name = "untitled"
path = "src/main.rs"
path = "src/main.rs"
[features]
default = []
static = []
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -20,5 +20,6 @@ pub fn build_api() -> Vec<Route> {
version_del,
build_output,
list_builds,
]
}
+51
View File
@@ -0,0 +1,51 @@
use rocket::http::uri::fmt::Path;
use rocket::http::uri::Segments;
use rocket::http::{ContentType, Method, Status};
use rocket::route::{Handler, Outcome};
use rocket::{Data, Request, Response, Route};
use rust_embed::{RustEmbed};
use std::io::Cursor;
#[derive(RustEmbed)]
#[folder = "web"]
struct Asset;
#[derive(Clone)]
pub struct CustomHandler {}
impl Into<Vec<Route>> for CustomHandler {
fn into(self) -> Vec<Route> {
vec![Route::ranked(-2, Method::Get, "/<path..>", self)]
}
}
#[rocket::async_trait]
impl Handler for CustomHandler {
async fn handle<'r>(&self, request: &'r Request<'_>, _: Data<'r>) -> Outcome<'r> {
let mut path = request
.segments::<Segments<'_, Path>>(0..)
.ok()
.and_then(|segments| segments.to_path_buf(true).ok())
.unwrap();
if path.is_dir() || path.to_str() == Some("") {
path = path.join("index.html")
}
match <Asset as RustEmbed>::get(path.to_string_lossy().as_ref()) {
None => Outcome::Failure(Status::NotFound),
Some(file_content) => {
let content_type: ContentType = path
.extension()
.map(|x| x.to_string_lossy())
.and_then(|x| ContentType::from_extension(&x))
.unwrap_or(ContentType::Plain);
let rsp = Response::build()
.header(content_type)
.sized_body(file_content.data.len(), Cursor::new(file_content.data))
.finalize();
Outcome::Success(rsp)
}
}
}
}
File renamed without changes.
@@ -2,3 +2,5 @@ mod add;
pub mod backend;
mod list;
mod remove;
#[cfg(feature = "static")]
pub mod embed;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+10 -3
View File
@@ -16,6 +16,8 @@ use sea_orm::{Database, DatabaseConnection};
use sea_orm_migration::MigratorTrait;
use std::fs;
use tokio::sync::broadcast;
#[cfg(feature = "static")]
use crate::api::embed::CustomHandler;
fn main() {
let t = tokio::runtime::Runtime::new().unwrap();
@@ -50,20 +52,25 @@ fn main() {
config.address = "0.0.0.0".parse().unwrap();
config.port = 8081;
let launch_result = rocket::custom(config)
let rock = rocket::custom(config)
.manage(db)
.manage(tx)
.mount("/", backend::build_api())
.mount(
"/docs/",
make_swagger_ui(&SwaggerUIConfig {
url: "../openapi.json".to_owned(),
..Default::default()
}),
)
);
#[cfg(feature = "static")]
let rock = rock.mount("/", CustomHandler {});
let rock = rock
.launch()
.await;
match launch_result {
match rock {
Ok(_) => println!("Rocket shut down gracefully."),
Err(err) => println!("Rocket had an error: {}", err),
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+43
View File
@@ -0,0 +1,43 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
+45
View File
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "b0366e0a3f089e15fd89c97604ab402fe26b724c"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: android
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: ios
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: linux
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: macos
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: web
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
- platform: windows
create_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
base_revision: b0366e0a3f089e15fd89c97604ab402fe26b724c
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
+16
View File
@@ -0,0 +1,16 @@
# aurcache
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
+28
View File
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="15.429" viewBox="0 0 12 15.429">
<g id="Group_785" data-name="Group 785" transform="translate(-279 -215)">
<path id="Vector" d="M11.864,6.612H7.091a1.628,1.628,0,0,1-1.157-.484,1.662,1.662,0,0,1-.479-1.169V.138a.138.138,0,0,0-.04-.1.136.136,0,0,0-.1-.04H2.182A2.171,2.171,0,0,0,.639.646,2.216,2.216,0,0,0,0,2.2v11.02a2.216,2.216,0,0,0,.639,1.559,2.171,2.171,0,0,0,1.543.646H9.818a2.171,2.171,0,0,0,1.543-.646A2.216,2.216,0,0,0,12,13.224V6.75a.138.138,0,0,0-.04-.1A.136.136,0,0,0,11.864,6.612Z" transform="translate(279 215)" fill="#2697ff"/>
<path id="Vector-2" data-name="Vector" d="M5.019,4.973.116.02a.068.068,0,0,0-.1.01A.069.069,0,0,0,0,.069v4.47a.554.554,0,0,0,.16.39.543.543,0,0,0,.386.161H4.971a.068.068,0,0,0,.038-.012.069.069,0,0,0,.025-.031.069.069,0,0,0-.015-.075Z" transform="translate(285.545 215.42)" fill="#2697ff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 916 B

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13.811" height="13.572" viewBox="0 0 13.811 13.572">
<g id="Search" transform="translate(-1165.25 -48.25)" opacity="0.8">
<path id="Vector" d="M10.286,5.041a5.093,5.093,0,0,1-5.143,5.041A5.093,5.093,0,0,1,0,5.041,5.093,5.093,0,0,1,5.143,0,5.093,5.093,0,0,1,10.286,5.041Z" transform="translate(1166 49)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M2.571,2.52,0,0" transform="translate(1175.429 58.241)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 660 B

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14.655" height="14.88" viewBox="0 0 14.655 14.88">
<g id="Group" transform="translate(-918 -214)">
<path id="Vector" d="M3.837,2.249a.346.346,0,0,1-.178-.05L0,0V3.914L4.87,6.842V.966L4.127,2.093A.347.347,0,0,1,3.837,2.249Z" transform="translate(920.102 222.038)" fill="#007ee5"/>
<path id="Vector-2" data-name="Vector" d="M6.654,1.092,4.9,0,0,2.943,1.758,4.036Z" transform="translate(918 214.061)" fill="#007ee5"/>
<path id="Vector-3" data-name="Vector" d="M5.965,2.987,1,0,0,1.513,4.968,4.5Z" transform="translate(918.864 218.972)" fill="#007ee5"/>
<path id="Vector-4" data-name="Vector" d="M4.89,0,0,2.94,4.89,5.88,9.78,2.94Z" transform="translate(920.429 215.563)" fill="#007ee5"/>
<path id="Vector-5" data-name="Vector" d="M3.114,1.115,0,2.987,1.007,4.5,5.975,1.514,4.968,0Z" transform="translate(925.808 218.971)" fill="#007ee5"/>
<path id="Vector-6" data-name="Vector" d="M0,1.147,4.9,4.094,6.679,2.947,1.778,0Z" transform="translate(925.976 214)" fill="#007ee5"/>
<path id="Vector-7" data-name="Vector" d="M1.045,2.242a.347.347,0,0,1-.289-.155L0,.951V6.834L4.87,3.907V0L1.223,2.192A.346.346,0,0,1,1.045,2.242Z" transform="translate(925.666 222.046)" fill="#007ee5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="19" viewBox="0 0 25 19">
<path id="Vector" d="M25,4.354a2.7,2.7,0,0,0-.854-1.959,3,3,0,0,0-2.062-.812H10.631a1.292,1.292,0,0,1-.693-.2L8.49.466A3.015,3.015,0,0,0,6.869,0H2.917A3,3,0,0,0,.854.812,2.7,2.7,0,0,0,0,2.771V5.146a.386.386,0,0,0,.122.28.428.428,0,0,0,.295.116H24.583a.428.428,0,0,0,.295-.116A.386.386,0,0,0,25,5.146ZM0,16.229a2.7,2.7,0,0,0,.854,1.959A3,3,0,0,0,2.917,19H22.083a3,3,0,0,0,2.062-.812A2.7,2.7,0,0,0,25,16.229V7.521a.386.386,0,0,0-.122-.28.428.428,0,0,0-.295-.116H.417a.428.428,0,0,0-.295.116A.386.386,0,0,0,0,7.521Z" fill="#ffcf26"/>
</svg>

After

Width:  |  Height:  |  Size: 624 B

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="69" height="34" viewBox="0 0 69 34">
<defs>
<pattern id="pattern" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" viewBox="0 0 346 532">
<image width="346" height="532" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVoAAAIUCAYAAABb6+T3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAJSWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDMgNzkuMTY0NTI3LCAyMDIwLzEwLzE1LTE3OjQ4OjMyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjg3OTdmNWJhLTg3MzYtMGU0NS04ZTI4LWE2ZTk0OTUxYzRlMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpjMzc5YzA2Mi04ZTYxLWQ4NGEtOGExYi1kNjNmYzQzNTFhNzMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0iQzJDRDMyRjk5M0REQjNFQUZBMzYxNjZCQUU0NjcwRjMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0iIiB0aWZmOkltYWdlV2lkdGg9IjM0NiIgdGlmZjpJbWFnZUxlbmd0aD0iNTMyIiB0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb249IjIiIHRpZmY6U2FtcGxlc1BlclBpeGVsPSIzIiB0aWZmOlhSZXNvbHV0aW9uPSI5Ni8xIiB0aWZmOllSZXNvbHV0aW9uPSI5Ni8xIiB0aWZmOlJlc29sdXRpb25Vbml0PSIyIiBleGlmOkV4aWZWZXJzaW9uPSIwMjMxIiBleGlmOkNvbG9yU3BhY2U9IjY1NTM1IiBleGlmOlBpeGVsWERpbWVuc2lvbj0iMzQ2IiBleGlmOlBpeGVsWURpbWVuc2lvbj0iNTMyIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMS0wMS0yNlQxMDoyODowMiswNjowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjEtMDEtMjZUMTA6MzM6MTYrMDY6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjEtMDEtMjZUMTA6MzM6MTYrMDY6MDAiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowMjEzYmExYy03MGFlLWE2NDQtYWQ0MS0zNWQ0ZWMzMmNiMTAiIHN0RXZ0OndoZW49IjIwMjEtMDEtMjZUMTA6MzM6MTYrMDY6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMi4xIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGltYWdlL2pwZWcgdG8gaW1hZ2UvcG5nIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJkZXJpdmVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJjb252ZXJ0ZWQgZnJvbSBpbWFnZS9qcGVnIHRvIGltYWdlL3BuZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YzM3OWMwNjItOGU2MS1kODRhLThhMWItZDYzZmM0MzUxYTczIiBzdEV2dDp3aGVuPSIyMDIxLTAxLTI2VDEwOjMzOjE2KzA2OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjIuMSAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjAyMTNiYTFjLTcwYWUtYTY0NC1hZDQxLTM1ZDRlYzMyY2IxMCIgc3RSZWY6ZG9jdW1lbnRJRD0iQzJDRDMyRjk5M0REQjNFQUZBMzYxNjZCQUU0NjcwRjMiIHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD0iQzJDRDMyRjk5M0REQjNFQUZBMzYxNjZCQUU0NjcwRjMiLz4gPHRpZmY6Qml0c1BlclNhbXBsZT4gPHJkZjpTZXE+IDxyZGY6bGk+ODwvcmRmOmxpPiA8cmRmOmxpPjg8L3JkZjpsaT4gPHJkZjpsaT44PC9yZGY6bGk+IDwvcmRmOlNlcT4gPC90aWZmOkJpdHNQZXJTYW1wbGU+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+J0hW5wAA7/BJREFUeJzs/WdwJNmVJoh+V7h7KKhEqsoSydJFFjVZ1LLJpiabTXaz2WwxPTM9YntsxmZ3Z5XZeztvbNb6re2+sbdvt3dspqd1k2xBssmmLBZVkSxFUSSLJciSWVUpKhUSQCCUi3vv+3H9uN9wRASABJAJZN7PDIZAhIeHRyD883O/c853mDEGHh4eHh7bB36xD8DDw8PjUocnWg8PD49thidaDw8Pj22GJ1oPDw+PbYYnWg8PD49thidaDw8Pj22GJ1oPDw+PbYYnWg8PD49thidaDw8Pj22GJ1oPDw+PbYYnWg8PD49thidaDw8Pj22GJ1oPDw+PbYYnWg8PD49thidaDw8Pj22G7KcX+xDWBmMAZ+Xf+gJa6Lqvux2g9+K+DmfDV0CN4fc86ph4vl31vkQDIS8fo+0ynb9O/lpsxD5jZZ/LGJDm2wsGKGOfkznHTscXcMCY8rHq/8pU7ncf1xO2G4cL+V24wJBbvcNR1tPCftHO91Nkyv7TJp0la+17Q2fYVv+/OTvv9w4A0MYev+CA0mCpBtMGLBAw2kDNRsiAbfhnemwtVpHniAsOZ8PbaVPex5klPZe8OSyBEjIDaA1IbgkYACJht4mV/ZsxIBT2ZO2mQF1aUh06VmMfjxV4N4UwBrVTPTQGKRrdFPVOikYnwd5Oghv6GW5MNa7rJJg1BvVEoZ5qNGKFRqrQSDUibSA5GzoRjfPj3jcOhjPoCdsYtnp/OwXVf/35gCsDjtErVwaAafs4wwYJD/nn5ny+2/EZamH3vxWfxSgwnN97p+fyXgrBmSXWVCGNJHoMaF81jVMAPvlPX4r/1AqReqK9yFgrYq5GvHTGZGY4KpS8Eh3m5EoRJpznAYBkZWRLkatgAOc2Ck4dwqXnJQroZ0CSAcsD4MgS+OkeWD9DdLaHN5zr462dFK/pJLhukGFOG9RSBQmAZQbIox86TqPt/nUeVRgO6Hz1wgBwzmAyDQWMJEsBgBlTfCTntfaI1fk9b7cgj1hXfX9oBbOJASv0uYlJG63FkGtFqO7xjVp1bRbrPf/GwDQDINVg/QzoJJAA6spgNtXYyxnelWj8ueCeaHc8aFlOxAk4MoArNwCrqIbDflETXW6rtD35GAO4sUSqtN1/J7Hb1Z1vBckWqcrJNgMLBCRjaAKYDzgOpwyvAPAmZfCiVGFe2WhUAIXsY5ix5J4ZMGj729gImCuTn0T5MbnvQ3IITDiZNystRGJHRrPAeV44qnAlI6Akq4J4+ebef6YnHydfY+9qjccF395E0lrkLSY/zhiDEQxGAKhL+1n0MwgAdaXxirpEA0DbE+0OQ0EM+VKfCJTIdhWZViQBVybQsF+USJSRARfDX9xBZn8Lbk+KRIMtxQjO9NA42cFcqnHl0TZuPtXF81ONm4+28byjbVwRcMzECpJ0WzqWSMAIXkbTqSpPJsaAiMNAFPowI41r1GewHj1us5rddkRJOwncTH6Poz7/rcRan28rnPx48b0/T6wVsW4yokWqwLSxslogyiAm4DCJwpQ2kMsDcE+0uwxuZAtYInO/zMYACuV9fQVEsvzCkBRg8hPwmWWwMz0ESzGufXQBbzvZwTsAvOTYCvae7aE+FUF0Ehv1ztftc1oB0rk6mDZQgwwQDIkGImWjG5bl0kOm7YmU5RGx0kCLine truncated
</pattern>
</defs>
<g id="Group_463" data-name="Group 463" transform="translate(-75 -37)">
<text id="Shop" transform="translate(97 44)" fill="#fff" font-size="18" font-family="Poppins-Medium, Poppins" font-weight="500"><tspan x="0" y="19">Shop</tspan></text>
<rect id="Screenshot_2021-01-26_101018_copy_1" data-name="Screenshot 2021-01-26 101018 copy 1" width="20" height="32" transform="translate(75 37)" fill="url(#pattern)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 84 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="22" viewBox="0 0 26 22">
<path id="Vector" d="M23.231,0H2.769A2.755,2.755,0,0,0,.811.819,2.81,2.81,0,0,0,0,2.8V19.2a2.81,2.81,0,0,0,.811,1.977A2.755,2.755,0,0,0,2.769,22H23.231a2.755,2.755,0,0,0,1.958-.819A2.81,2.81,0,0,0,26,19.2V2.8A2.81,2.81,0,0,0,25.189.819,2.755,2.755,0,0,0,23.231,0ZM9.177,15.475V6.525L16.837,11Z" fill="#26e5ff"/>
</svg>

After

Width:  |  Height:  |  Size: 405 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="14" viewBox="0 0 13 14">
<path id="Vector" d="M12.994,2.169V4.278a2.281,2.281,0,0,1-.559,1.537,1.886,1.886,0,0,1-1.384.652h-.8a.592.592,0,0,1,0-1.161h.772a.878.878,0,0,0,.649-.3,1.063,1.063,0,0,0,.262-.719V2.169a.972.972,0,0,0-.911-1H9.1a.959.959,0,0,0-.911,1V5.332a.563.563,0,0,1-.543.57.5.5,0,0,1-.37-.181.61.61,0,0,1-.143-.416V2.169A2.276,2.276,0,0,1,7.71.636,1.881,1.881,0,0,1,9.1,0h1.924A2.123,2.123,0,0,1,12.994,2.169ZM3.9,0H1.973A2.09,2.09,0,0,0,0,2.169V4.284A2.083,2.083,0,0,0,1.973,6.446H3.9a1.88,1.88,0,0,0,1.394-.631A2.276,2.276,0,0,0,5.87,4.284V2.169A2.084,2.084,0,0,0,3.9,0Zm.911,4.284A1.063,1.063,0,0,1,4.546,5a.879.879,0,0,1-.649.3H1.973a.87.87,0,0,1-.662-.293,1.056,1.056,0,0,1-.267-.728V2.169a1.053,1.053,0,0,1,.273-.715.869.869,0,0,1,.656-.286H3.9a.966.966,0,0,1,.911,1Zm4.3,3.27h1.924A2.083,2.083,0,0,1,13,9.716v2.116A2.09,2.09,0,0,1,11.027,14H9.1a2.085,2.085,0,0,1-1.967-2.169V9.716A2.071,2.071,0,0,1,9.1,7.554Zm2.57,4.988a1.048,1.048,0,0,0,.265-.71V9.716a1.054,1.054,0,0,0-.267-.708.871.871,0,0,0-.644-.293H9.1a.959.959,0,0,0-.911,1v2.116a1.048,1.048,0,0,0,.265.71.865.865,0,0,0,.646.291h1.924A.865.865,0,0,0,11.673,12.541ZM0,11.825V9.716A2.275,2.275,0,0,1,.578,8.185a1.88,1.88,0,0,1,1.394-.631h.79a.516.516,0,0,1,.507.271.633.633,0,0,1,0,.619.516.516,0,0,1-.507.271h-.79a.965.965,0,0,0-.917,1V11.8a.984.984,0,0,0,.917,1H3.909a.87.87,0,0,0,.648-.291,1.054,1.054,0,0,0,.269-.71V8.668a.608.608,0,0,1,.238-.6.492.492,0,0,1,.594.019.614.614,0,0,1,.206.613v3.124a2.078,2.078,0,0,1-1.973,2.169H1.973A2.122,2.122,0,0,1,0,11.825Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="15" viewBox="0 0 13 15">
<path id="Vector" d="M12.841,4.167,8.979.183A.574.574,0,0,0,8.567.009H8.41L8.39,0a.082.082,0,0,0-.024,0,.087.087,0,0,0-.025,0l-.019,0H3.495A3.486,3.486,0,0,0,0,3.391V6.51a.572.572,0,0,0,1.144,0V3.391A2.333,2.333,0,0,1,3.495,1.142h4.3V2.764a2.526,2.526,0,0,0,2.529,2.511h0a.566.566,0,1,0,0-1.133A1.386,1.386,0,0,1,8.938,2.764V1.777l2.918,3.011v6.694a2.392,2.392,0,0,1-2.271,2.386H3.495a2.344,2.344,0,0,1-2.351-2.386V9.589A.572.572,0,0,0,0,9.589v1.892A3.47,3.47,0,0,0,3.495,15H9.585A3.514,3.514,0,0,0,13,11.481V4.56A.565.565,0,0,0,12.841,4.167ZM4.107,10.8H8.222a.566.566,0,1,0,0-1.133H4.107a.566.566,0,1,0,0,1.133ZM6.665,7.065H4.107a.566.566,0,1,1,0-1.133H6.665a.566.566,0,1,1,0,1.133Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 792 B

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16">
<path id="Vector" d="M13.445,7.447A3.185,3.185,0,0,1,14,9.088l-.022.148a3.252,3.252,0,0,1-.774,2.2,4.069,4.069,0,0,1-2.572,1.232,34.465,34.465,0,0,1-7.306,0A4.022,4.022,0,0,1,.8,11.439,3.207,3.207,0,0,1,0,9.249v-.1A3.3,3.3,0,0,1,.6,7.469L.659,7.4A3.035,3.035,0,0,0,1.389,5.99V4.54a.631.631,0,0,1,.653-.381.619.619,0,0,1,.553.507v1.45a.353.353,0,0,1,0,.077A4.166,4.166,0,0,1,1.586,8.151a1.982,1.982,0,0,0-.321,1v.155a2.022,2.022,0,0,0,.482,1.373,2.768,2.768,0,0,0,1.71.788,33.927,33.927,0,0,0,7.073,0,2.773,2.773,0,0,0,1.746-.824,2,2,0,0,0,.46-1.33V9.151a2.056,2.056,0,0,0-.314-1.007,4.175,4.175,0,0,1-1.067-1.957.358.358,0,0,1,0-.077V4.653C11.143,2.527,8.944,1.211,7.03,1.211a4.853,4.853,0,0,0-2.323.584.649.649,0,0,1-.639,0A.595.595,0,0,1,4.093.739,6.108,6.108,0,0,1,6.971,0C9.5,0,12.334,1.732,12.656,4.512v1.45a2.973,2.973,0,0,0,.731,1.408A.538.538,0,0,1,13.445,7.447Zm-6.238,7.3a1.641,1.641,0,0,0,1.072-.624h.007a.647.647,0,0,1,.888-.081.592.592,0,0,1,.084.855,2.926,2.926,0,0,1-4.581,0,.592.592,0,0,1,.084-.855.647.647,0,0,1,.888.081,1.661,1.661,0,0,0,1.558.624Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="15" viewBox="0 0 10 15">
<path id="Vector" d="M2.536,4.015A2.735,2.735,0,0,1,5,1.078,2.735,2.735,0,0,1,7.464,4.015,2.735,2.735,0,0,1,5,6.952,2.735,2.735,0,0,1,2.536,4.015Zm-.9,0C1.633,6.229,3.143,8.03,5,8.03s3.367-1.8,3.367-4.015S6.857,0,5,0,1.633,1.8,1.633,4.015ZM4.361,14.989Q4.675,15,5,15c2.147,0,5-.286,5-2.752,0-2.768-3.764-2.768-5-2.768-2.147,0-5,.286-5,2.753a2.362,2.362,0,0,0,1.66,2.29.438.438,0,0,0,.573-.338A.567.567,0,0,0,1.95,13.5C1.011,13.124.9,12.6.9,12.233c0-1.112,1.379-1.676,4.1-1.676s4.1.569,4.1,1.691S7.718,13.922,5,13.922q-.311,0-.613-.01a.547.547,0,0,0-.026,1.076Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 686 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="15" viewBox="0 0 13 15">
<path id="Vector" d="M4.408,3.656a1.713,1.713,0,0,1-1.813-.013L2.57,3.617A.6.6,0,0,1,2.4,2.826a.516.516,0,0,1,.739-.184.732.732,0,0,0,.369.112.723.723,0,0,0,.54-.212.829.829,0,0,0,.241-.559A1.92,1.92,0,0,1,6.078,0h.843A1.915,1.915,0,0,1,8.767,1.976a.8.8,0,0,0,.1.4.755.755,0,0,0,.453.376.7.7,0,0,0,.569-.08,1.78,1.78,0,0,1,2.462.711.61.61,0,0,1-.2.784.522.522,0,0,1-.732-.2.724.724,0,0,0-1.022-.29,1.741,1.741,0,0,1-1.809-.021,2,2,0,0,1-.924-1.665A.829.829,0,0,0,7.456,1.4a.722.722,0,0,0-.535-.243H6.078A.727.727,0,0,0,5.54,1.4a.835.835,0,0,0-.213.581A1.97,1.97,0,0,1,4.408,3.656Zm.919,9.388a.778.778,0,0,0,.751.8l-.006.013a.53.53,0,0,1,.464.287.608.608,0,0,1,0,.573A.53.53,0,0,1,6.071,15a1.915,1.915,0,0,1-1.846-1.976.8.8,0,0,0-.1-.4.725.725,0,0,0-1.022-.3,1.78,1.78,0,0,1-2.462-.711l-.418-.784A2.056,2.056,0,0,1,.89,8.2a.792.792,0,0,0,.271-.29.842.842,0,0,0,.122-.637A.794.794,0,0,0,.92,6.752,2.056,2.056,0,0,1,.256,4.117.535.535,0,0,1,.6,3.873a.507.507,0,0,1,.4.087.592.592,0,0,1,.154.764A.828.828,0,0,0,1.431,5.81a1.887,1.887,0,0,1,.64.718,2.055,2.055,0,0,1-.665,2.635A.828.828,0,0,0,1.13,10.25l.425.784a.742.742,0,0,0,.453.378.691.691,0,0,0,.569-.088,1.689,1.689,0,0,1,.9-.257A1.915,1.915,0,0,1,5.327,13.043ZM12.1,8.2a.793.793,0,0,1-.348-.486.847.847,0,0,1,.077-.607.793.793,0,0,1,.271-.29.6.6,0,0,0,.185-.784.529.529,0,0,0-.726-.217A2.055,2.055,0,0,0,10.9,8.445a1.868,1.868,0,0,0,.671.784.785.785,0,0,1,.348.483.839.839,0,0,1-.077.6l-.418.784a.779.779,0,0,1-.455.375.691.691,0,0,1-.566-.086,1.741,1.741,0,0,0-1.812.023,2,2,0,0,0-.921,1.67.539.539,0,0,0,1.077,0,.8.8,0,0,1,.369-.7.7.7,0,0,1,.751.008,1.78,1.78,0,0,0,2.462-.711l.419-.784A2.056,2.056,0,0,0,12.1,8.2ZM6.5,5.026A2.318,2.318,0,0,0,4.358,6.557a2.606,2.606,0,0,0,.5,2.7,2.2,2.2,0,0,0,2.524.533A2.486,2.486,0,0,0,8.81,7.5a2.561,2.561,0,0,0-.678-1.749A2.233,2.233,0,0,0,6.5,5.026Zm0,3.794A1.276,1.276,0,0,1,5.265,7.5,1.276,1.276,0,0,1,6.5,6.186,1.276,1.276,0,0,1,7.727,7.5,1.276,1.276,0,0,1,6.5,8.821Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="15" viewBox="0 0 13 15">
<path id="Vector" d="M12.934,10.31l-.517-4.4c-.331-1.978-1.527-2.637-2.537-2.637A3.628,3.628,0,0,0,7.559.174,3.176,3.176,0,0,0,4.032,1.226a.622.622,0,0,0-.118.566.552.552,0,0,0,.388.4.5.5,0,0,0,.506-.17V1.951a2.168,2.168,0,0,1,3.258-.2,2.66,2.66,0,0,1,.745,1.516H3.173c-.968,0-2.14.659-2.537,2.67l-.15.989a.574.574,0,0,0,.436.631.531.531,0,0,0,.6-.433l.144-.969c.222-1.1.781-1.76,1.5-1.76H9.881c.757,0,1.316.659,1.5,1.714l.511,4.358a3.567,3.567,0,0,1-.391,2.578,2.657,2.657,0,0,1-2.23.771H3.786a2.728,2.728,0,0,1-2.17-.857,3.285,3.285,0,0,1-.451-2.492A.57.57,0,0,0,.72,9.816a.535.535,0,0,0-.6.488,3.971,3.971,0,0,0,.692,3.412,3.222,3.222,0,0,0,2.974,1.256H9.268A3.528,3.528,0,0,0,12.273,13.8,4.671,4.671,0,0,0,12.934,10.31ZM8.216,7.522a.684.684,0,0,0,.234.053.577.577,0,0,0,.421-.2.527.527,0,0,0,.144-.218.6.6,0,0,0,.048-.251.468.468,0,0,0,0-.132.421.421,0,0,0-.036-.125.273.273,0,0,0-.054-.112.917.917,0,0,0-.162-.185.729.729,0,0,0-.222-.1.473.473,0,0,0-.234,0,.4.4,0,0,0-.114.04.441.441,0,0,0-.108.059l-.09.086a.288.288,0,0,0-.072.1l-.06.112v.125a.478.478,0,0,0,0,.132.593.593,0,0,0,.042.251A.652.652,0,0,0,8.216,7.522ZM5.228,6.915a.632.632,0,0,1-.6.659.578.578,0,0,1-.409-.2.667.667,0,0,1-.132-.218.716.716,0,0,1-.042-.251.47.47,0,0,1,0-.132.423.423,0,0,1,.036-.125.383.383,0,0,1,.054-.112.286.286,0,0,1,.072-.1.4.4,0,0,1,.09-.079A.327.327,0,0,1,4.4,6.3a.339.339,0,0,1,.114-.04.473.473,0,0,1,.234,0,.339.339,0,0,1,.114.04.327.327,0,0,1,.1.059.4.4,0,0,1,.1.086.287.287,0,0,1,.072.1.674.674,0,0,1,.06.112l.036.125A.9.9,0,0,1,5.228,6.915Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<path id="Vector" d="M13.992,5.48A6.347,6.347,0,0,0,8.009,0a1.056,1.056,0,0,0-.8.34,1.114,1.114,0,0,0-.288.821L7.23,5.981A1.144,1.144,0,0,0,8.347,7.059H8.42l4.6-.321a1.02,1.02,0,0,0,.718-.365A1.116,1.116,0,0,0,14,5.583v-.1ZM8.347,5.9,8.04,1.168a5.217,5.217,0,0,1,4.847,4.421Zm2.013,3.3a.562.562,0,0,1,.687-.4.555.555,0,0,1,.346.267.6.6,0,0,1,.059.446,6.045,6.045,0,0,1-2.816,3.728,5.587,5.587,0,0,1-5.477.087A6.081,6.081,0,0,1,.045,8.612,3.969,3.969,0,0,1,0,7.9,6.038,6.038,0,0,1,4.64,1.925a.565.565,0,0,1,.663.462.589.589,0,0,1-.442.693A4.889,4.889,0,0,0,1.125,7.919a3.251,3.251,0,0,0,.031.545,4.806,4.806,0,0,0,4.312,4.317A4.724,4.724,0,0,0,10.359,9.2Z" fill="#001b34" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 780 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="14" viewBox="0 0 13 14">
<path id="Vector" d="M13,6a.518.518,0,0,1-.5.536H12.5a.475.475,0,0,1-.352-.159A.552.552,0,0,1,12.005,6V4.377c0-2.13-1.092-3.306-3.07-3.306H4.065c-1.984,0-3.07,1.176-3.07,3.306V9.629c0,2.13,1.092,3.3,3.07,3.3H8.935c1.984,0,3.07-1.176,3.07-3.3a.5.5,0,1,1,.995,0C13,12.325,11.445,14,8.941,14H4.065C1.555,14,0,12.325,0,9.629V4.377C0,1.675,1.555,0,4.065,0H8.935C11.434,0,13,1.675,13,4.377ZM3.224,10.281V5.8a.548.548,0,0,1,.158-.371.471.471,0,0,1,.356-.14.483.483,0,0,1,.347.17.56.56,0,0,1,.133.384v4.476a.515.515,0,0,1-.515.517A.521.521,0,0,1,3.224,10.281Zm2.8-6.557v6.563a.5.5,0,1,0,.995,0V3.725a.5.5,0,1,0-.995,0Zm2.755,6.557V8.188a.5.5,0,1,1,.995,0v2.093a.5.5,0,1,1-.995,0Z" fill="#00162a" opacity="0.6"/>
</svg>

After

Width:  |  Height:  |  Size: 797 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="25" viewBox="0 0 18 25">
<path id="Vector" d="M17.473,5.357H12.6V.523ZM18,7.143V22.321a2.671,2.671,0,0,1-.792,1.893A2.714,2.714,0,0,1,15.3,25H2.7a2.714,2.714,0,0,1-1.908-.785A2.671,2.671,0,0,1,0,22.321V2.679A2.671,2.671,0,0,1,.792.785,2.714,2.714,0,0,1,2.7,0h8.1V6.25a.889.889,0,0,0,.264.631.9.9,0,0,0,.636.262Zm-8.1,12.5a.889.889,0,0,0-.264-.631.905.905,0,0,0-1.273,0,.888.888,0,0,0,0,1.263.905.905,0,0,0,1.273,0A.889.889,0,0,0,9.9,19.643Zm2.644-8.676A3.559,3.559,0,0,0,11.75,9.3a3.613,3.613,0,0,0-6.014.8,3.542,3.542,0,0,0-.337,1.51.889.889,0,0,0,.264.631.905.905,0,0,0,1.273,0,.889.889,0,0,0,.264-.631,1.782,1.782,0,0,1,.652-1.375,1.809,1.809,0,0,1,2.475.165,1.781,1.781,0,0,1-.64,2.861,2.621,2.621,0,0,0-1.167.98A2.59,2.59,0,0,0,8.1,15.7v1.268a.889.889,0,0,0,.264.631.905.905,0,0,0,1.273,0,.889.889,0,0,0,.264-.631V15.7a.834.834,0,0,1,.119-.464.844.844,0,0,1,.356-.324,3.584,3.584,0,0,0,1.789-1.589,3.54,3.54,0,0,0,.38-2.352Z" fill="#ee2727"/>
</svg>

After

Width:  |  Height:  |  Size: 1016 B

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
const primaryColor = Color(0xFF2697FF);
//const secondaryColor = Color(0xFF2A2D3E);
//const bgColor = Color(0xFF212132);
const secondaryColor = Color(0xFF292929);
const bgColor = Color(0xFF212121);
const darkgreenColor = Color(0xFF2c614f);
const greenColor = Color(0xFF6bab58);
const defaultPadding = 16.0;
const double defaultBorderRadius = 15;
class ColorConstants {
static Color blue = Color(0xFF0D46BB);
}
class Palette {
static const Color background = Color(0xFFEDEEF2);
static const Color wrapperBg = Color(0xFF212121);
}
+22
View File
@@ -0,0 +1,22 @@
import 'dart:ui';
import 'package:flutter/material.dart';
Color getRoleColor(String? role) {
if (role == "Doctor") {
return Colors.green;
} else if (role == "Software Architect") {
return Colors.red;
} else if (role == "Software Engineer") {
return Colors.blueAccent;
} else if (role == "Solution Architect") {
return Colors.amberAccent;
} else if (role == "Project Manager") {
return Colors.cyanAccent;
} else if (role == "Business Analyst") {
return Colors.deepPurpleAccent;
} else if (role == "UI/UX Designer") {
return Colors.indigoAccent;
}
return Colors.black38;
}
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
enum ButtonType { PRIMARY, PLAIN }
class AppButton extends StatelessWidget {
final ButtonType? type;
final VoidCallback? onPressed;
final String? text;
AppButton({this.type, this.onPressed, this.text});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: this.onPressed,
child: Container(
width: double.infinity,
height: 45,
decoration: BoxDecoration(
color: getButtonColor(context, type!),
borderRadius: BorderRadius.circular(4.0),
boxShadow: [
BoxShadow(
//color: Color.fromRGBO(169, 176, 185, 0.42),
//spreadRadius: 0,
//blurRadius: 3.0,
//offset: Offset(0, 2),
)
],
),
child: Center(
child: Text(this.text!,
style: Theme.of(context)
.textTheme
.subtitle1!
.copyWith(color: getTextColor(context, type!))),
),
),
);
}
}
Color getButtonColor(context, ButtonType type) {
switch (type) {
case ButtonType.PRIMARY:
return Theme.of(context).buttonTheme.colorScheme!.background;
case ButtonType.PLAIN:
return Colors.white;
default:
return Theme.of(context).primaryColor;
}
}
Color getTextColor(context, ButtonType type) {
switch (type) {
case ButtonType.PLAIN:
return Theme.of(context).primaryColor;
case ButtonType.PRIMARY:
return Colors.white;
default:
return Theme.of(context).buttonTheme.colorScheme!.background;
}
}
@@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import '../constants/color_constants.dart';
class InputWidget extends StatelessWidget {
final String? hintText;
final String? errorText;
final Widget? prefixIcon;
final double? height;
final String? topLabel;
final bool? obscureText;
final FormFieldSetter<String>? onSaved;
final ValueChanged<String>? onChanged;
final FormFieldValidator<String>? validator;
final TextInputType? keyboardType;
final Key? kKey;
final TextEditingController? kController;
final String? kInitialValue;
InputWidget({
this.hintText,
this.prefixIcon,
this.height = 48.0,
this.topLabel = "",
this.obscureText = false,
required this.onSaved,
this.keyboardType,
this.errorText,
this.onChanged,
this.validator,
this.kKey,
this.kController,
this.kInitialValue,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(this.topLabel!),
SizedBox(height: 4.0),
Container(
height: 50,
decoration: BoxDecoration(
color: secondaryColor,
//color: Theme.of(context).buttonColor,
borderRadius: BorderRadius.circular(4.0),
),
child: TextFormField(
initialValue: this.kInitialValue,
controller: this.kController,
key: this.kKey,
keyboardType: this.keyboardType,
onSaved: this.onSaved,
onChanged: this.onChanged,
validator: this.validator,
obscureText: this.obscureText!,
decoration: InputDecoration(
prefixIcon: this.prefixIcon,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color.fromRGBO(74, 77, 84, 0.2),
),
),
focusedBorder: OutlineInputBorder(
//gapPadding: 16,
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
),
),
errorStyle: TextStyle(height: 0, color: Colors.transparent),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).errorColor,
),
),
focusedErrorBorder: OutlineInputBorder(
//gapPaddings: 16,
borderSide: BorderSide(
color: Theme.of(context).errorColor,
),
),
hintText: this.hintText,
hintStyle: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.white54),
errorText: this.errorText),
),
)
],
);
}
}
+34
View File
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import '../constants/color_constants.dart';
class Wrapper extends StatelessWidget {
final Widget? title;
final Widget child;
const Wrapper({Key? key, this.title, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
color: Palette.wrapperBg,
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null)
Column(
children: [
title!,
const SizedBox(height: defaultPadding),
],
),
child
],
),
);
}
}
+31
View File
@@ -0,0 +1,31 @@
import 'package:aurcache/screens/home/home_screen.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'core/constants/color_constants.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Smart Dashboard - Admin Panel v0.1 ',
theme: ThemeData.dark().copyWith(
appBarTheme: const AppBarTheme(backgroundColor: bgColor, elevation: 0),
scaffoldBackgroundColor: bgColor,
primaryColor: greenColor,
dialogBackgroundColor: secondaryColor,
textTheme: GoogleFonts.openSansTextTheme(Theme.of(context).textTheme)
.apply(bodyColor: Colors.white),
canvasColor: secondaryColor,
),
home: const HomeScreen(),
);
}
}
+289
View File
@@ -0,0 +1,289 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import '../core/constants/color_constants.dart';
class DailyInfoModel {
IconData? icon;
String? title;
String? totalStorage;
int? volumeData;
int? percentage;
Color? color;
List<Color>? colors;
List<FlSpot>? spots;
DailyInfoModel({
this.icon,
this.title,
this.totalStorage,
this.volumeData,
this.percentage,
this.color,
this.colors,
this.spots,
});
DailyInfoModel.fromJson(Map<String, dynamic> json) {
title = json['title'];
volumeData = json['volumeData'];
icon = json['icon'];
totalStorage = json['totalStorage'];
color = json['color'];
percentage = json['percentage'];
colors = json['colors'];
spots = json['spots'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['volumeData'] = this.volumeData;
data['icon'] = this.icon;
data['totalStorage'] = this.totalStorage;
data['color'] = this.color;
data['percentage'] = this.percentage;
data['colors'] = this.colors;
data['spots'] = this.spots;
return data;
}
}
List<DailyInfoModel> dailyDatas =
dailyData.map((item) => DailyInfoModel.fromJson(item)).toList();
//List<FlSpot> spots = yValues.asMap().entries.map((e) {
// return FlSpot(e.key.toDouble(), e.value);
//}).toList();
var dailyData = [
{
"title": "Employee",
"volumeData": 1328,
"icon": Icons.ac_unit,
"totalStorage": "+ %20",
"color": primaryColor,
"percentage": 35,
"colors": [
Color(0xff23b6e6),
Color(0xff02d39a),
],
"spots": [
FlSpot(
1,
2,
),
FlSpot(
2,
1.0,
),
FlSpot(
3,
1.8,
),
FlSpot(
4,
1.5,
),
FlSpot(
5,
1.0,
),
FlSpot(
6,
2.2,
),
FlSpot(
7,
1.8,
),
FlSpot(
8,
1.5,
)
]
},
{
"title": "On Leave",
"volumeData": 1328,
"icon": Icons.ac_unit,
"totalStorage": "+ %5",
"color": Color(0xFFFFA113),
"percentage": 35,
"colors": [Color(0xfff12711), Color(0xfff5af19)],
"spots": [
FlSpot(
1,
1.3,
),
FlSpot(
2,
1.0,
),
FlSpot(
3,
4,
),
FlSpot(
4,
1.5,
),
FlSpot(
5,
1.0,
),
FlSpot(
6,
3,
),
FlSpot(
7,
1.8,
),
FlSpot(
8,
1.5,
)
]
},
{
"title": "Onboarding",
"volumeData": 1328,
"icon": Icons.ac_unit,
"totalStorage": "+ %8",
"color": Color(0xFFA4CDFF),
"percentage": 10,
"colors": [Color(0xff2980B9), Color(0xff6DD5FA)],
"spots": [
FlSpot(
1,
1.3,
),
FlSpot(
2,
5,
),
FlSpot(
3,
1.8,
),
FlSpot(
4,
6,
),
FlSpot(
5,
1.0,
),
FlSpot(
6,
2.2,
),
FlSpot(
7,
1.8,
),
FlSpot(
8,
1,
)
]
},
{
"title": "Open Position",
"volumeData": 1328,
"icon": Icons.ac_unit,
"totalStorage": "+ %8",
"color": Color(0xFFd50000),
"percentage": 10,
"colors": [Color(0xff93291E), Color(0xffED213A)],
"spots": [
FlSpot(
1,
3,
),
FlSpot(
2,
4,
),
FlSpot(
3,
1.8,
),
FlSpot(
4,
1.5,
),
FlSpot(
5,
1.0,
),
FlSpot(
6,
2.2,
),
FlSpot(
7,
1.8,
),
FlSpot(
8,
1.5,
)
]
},
{
"title": "Efficiency",
"volumeData": 5328,
"icon": Icons.ac_unit,
"totalStorage": "- %5",
"color": Color(0xFF00F260),
"percentage": 78,
"colors": [Color(0xff0575E6), Color(0xff00F260)],
"spots": [
FlSpot(
1,
1.3,
),
FlSpot(
2,
1.0,
),
FlSpot(
3,
1.8,
),
FlSpot(
4,
1.5,
),
FlSpot(
5,
1.0,
),
FlSpot(
6,
2.2,
),
FlSpot(
7,
1.8,
),
FlSpot(
8,
1.5,
)
]
}
];
//final List<double> yValues = [
// 2.3,
// 1.8,
// 1.9,
// 1.5,
// 1.0,
// 2.2,
// 1.8,
// 1.5,
//];
+64
View File
@@ -0,0 +1,64 @@
class SliderModel {
String? image;
String? text;
String? altText;
String? bAltText;
String? productImage;
int? kBackgroundColor;
SliderModel(this.image, this.text, this.altText, this.bAltText,
this.productImage, this.kBackgroundColor);
SliderModel.fromJson(Map<String, dynamic> json) {
image = json['image'];
kBackgroundColor = json['kBackgroundColor'];
text = json['text'];
altText = json['altText'];
bAltText = json['bAltText'];
productImage = json['productImage'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['image'] = this.image;
data['kBackgroundColor'] = this.kBackgroundColor;
data['text'] = this.text;
data['altText'] = this.altText;
data['bAltText'] = this.bAltText;
data['productImage'] = this.productImage;
return data;
}
}
List<SliderModel> slides =
slideData.map((item) => SliderModel.fromJson(item)).toList();
var slideData = [
{
"image": "assets/slides/background-1.jpeg",
"kBackgroundColor": 0xFF2c614f,
"text": "Welcome to the Smart Smart Admin Dashboard!",
"altText": "You can access & track your services in real-time.",
"bAltText": "Are you ready for the next generation AI supported Dashboard?",
"productImage": "assets/images/mockup.png"
},
{
"image": "assets/slides/background-2.jpeg",
"kBackgroundColor": 0xFF8a1a4c,
"text": "¡Bienvenido al tablero Smart Admin Dashboard!",
"altText": "Puede acceder y rastrear sus servicios en tiempo real.",
"bAltText":
"¿Estás listo para el panel de control impulsado por IA de próxima generación?",
"productImage": "assets/images/mockup-2.png"
},
{
"image": "assets/slides/background-3.jpeg",
"kBackgroundColor": 0xFF0ab3ec,
"text": "Willkommen im Smart Admin Dashboard!",
"altText":
"Sie können in Echtzeit auf Ihre Dienste zugreifen und diese verfolgen.",
"bAltText":
"Sind Sie bereit für das AI-unterstützte Dashboard der nächsten Generation?",
"productImage": "assets/images/mockup-3.png"
}
];
@@ -0,0 +1 @@
+44
View File
@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
class Responsive extends StatelessWidget {
final Widget mobile;
final Widget tablet;
final Widget desktop;
const Responsive({
Key? key,
required this.mobile,
required this.tablet,
required this.desktop,
}) : super(key: key);
// This size work fine on my design, maybe you need some customization depends on your design
// This isMobile, isTablet, isDesktop helep us later
static bool isMobile(BuildContext context) =>
MediaQuery.of(context).size.width < 850;
static bool isTablet(BuildContext context) =>
MediaQuery.of(context).size.width < 1100 &&
MediaQuery.of(context).size.width >= 850;
static bool isDesktop(BuildContext context) =>
MediaQuery.of(context).size.width >= 1100;
@override
Widget build(BuildContext context) {
final Size _size = MediaQuery.of(context).size;
// If our width is more than 1100 then we consider it a desktop
if (_size.width >= 1100) {
return desktop;
}
// If width it less then 1100 and more then 850 we consider it as tablet
else if (_size.width >= 850) {
return tablet;
}
// Or less then that we called it mobile
else {
return mobile;
}
}
}
@@ -0,0 +1,95 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
class Chart extends StatefulWidget {
const Chart({
Key? key,
}) : super(key: key);
@override
_ChartState createState() => _ChartState();
}
class _ChartState extends State<Chart> {
int touchedIndex = -1;
@override
Widget build(BuildContext context) {
return SizedBox(
height: 300,
child: AspectRatio(
aspectRatio: 1.3,
child: Row(
children: <Widget>[
const SizedBox(
height: 18,
),
Expanded(
child: AspectRatio(
aspectRatio: 1,
child: PieChart(
PieChartData(
pieTouchData:
PieTouchData(touchCallback: (pieTouchResponse, touchresponse) {
setState(() {
// final desiredTouch = pieTouchResponse.touchInput
// is! PointerExitEvent &&
// pieTouchResponse.touchInput is! PointerUpEvent;
if ( touchresponse?.touchedSection != null) {
touchedIndex = touchresponse!.touchedSection!.touchedSectionIndex;
} else {
touchedIndex = -1;
}
});
}),
borderData: FlBorderData(
show: false,
),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: showingSections()),
),
),
),
const SizedBox(
width: 28,
),
],
),
),
);
}
List<PieChartSectionData> showingSections() {
return List.generate(2, (i) {
final isTouched = i == touchedIndex;
final fontSize = isTouched ? 25.0 : 16.0;
final radius = isTouched ? 60.0 : 50.0;
switch (i) {
case 0:
return PieChartSectionData(
color: const Color(0xff760707),
value: 40,
title: '28.3%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
);
case 1:
return PieChartSectionData(
color: const Color(0xff0a7005),
value: 30,
title: '16.7%',
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
);
default:
throw Error();
}
});
}
}
@@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../../core/constants/color_constants.dart';
import '../../../responsive.dart';
class Header extends StatelessWidget {
const Header({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
children: [
if (!Responsive.isDesktop(context))
IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
),
if (!Responsive.isMobile(context))
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Hello, Arch User 👋",
style: Theme.of(context).textTheme.headline6,
),
SizedBox(
height: 8,
),
Text(
"Welcome to AURCentral",
style: Theme.of(context).textTheme.subtitle2,
),
],
),
if (!Responsive.isMobile(context))
Spacer(flex: Responsive.isDesktop(context) ? 2 : 1),
Expanded(child: SearchField()),
//ProfileCard()
],
);
}
}
class ProfileCard extends StatelessWidget {
const ProfileCard({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(left: defaultPadding),
padding: EdgeInsets.symmetric(
horizontal: defaultPadding,
vertical: defaultPadding / 2,
),
decoration: BoxDecoration(
color: secondaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
border: Border.all(color: Colors.white10),
),
child: Row(
children: [
CircleAvatar(
backgroundImage: AssetImage("assets/images/profile_pic.png"),
),
if (!Responsive.isMobile(context))
Padding(
padding:
const EdgeInsets.symmetric(horizontal: defaultPadding / 2),
child: Text("Deniz Çolak"),
),
Icon(Icons.keyboard_arrow_down),
],
),
);
}
}
class SearchField extends StatelessWidget {
const SearchField({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
decoration: InputDecoration(
hintText: "Search",
fillColor: secondaryColor,
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
suffixIcon: InkWell(
onTap: () {},
child: Container(
padding: EdgeInsets.all(defaultPadding * 0.75),
margin: EdgeInsets.symmetric(horizontal: defaultPadding / 2),
decoration: BoxDecoration(
color: greenColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: SvgPicture.asset(
"assets/icons/Search.svg",
),
),
),
),
);
}
}
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
import '../../../models/daily_info_model.dart';
import '../../../responsive.dart';
import 'mini_information_widget.dart';
class MiniInformation extends StatelessWidget {
const MiniInformation({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final Size _size = MediaQuery.of(context).size;
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 10,
),
ElevatedButton.icon(
style: TextButton.styleFrom(
backgroundColor: Colors.green,
padding: EdgeInsets.symmetric(
horizontal: defaultPadding * 1.5,
vertical:
defaultPadding / (Responsive.isMobile(context) ? 2 : 1),
),
),
onPressed: () {
},
icon: Icon(Icons.add),
label: Text(
"Add New",
),
),
],
),
SizedBox(height: defaultPadding),
Responsive(
mobile: InformationCard(
crossAxisCount: _size.width < 650 ? 2 : 4,
childAspectRatio: _size.width < 650 ? 1.2 : 1,
),
tablet: InformationCard(),
desktop: InformationCard(
childAspectRatio: _size.width < 1400 ? 1.2 : 1.4,
),
),
],
);
}
}
class InformationCard extends StatelessWidget {
const InformationCard({
Key? key,
this.crossAxisCount = 5,
this.childAspectRatio = 1,
}) : super(key: key);
final int crossAxisCount;
final double childAspectRatio;
@override
Widget build(BuildContext context) {
return GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: dailyDatas.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
crossAxisSpacing: defaultPadding,
mainAxisSpacing: defaultPadding,
childAspectRatio: childAspectRatio,
),
itemBuilder: (context, index) =>
MiniInformationWidget(dailyData: dailyDatas[index]),
);
}
}
@@ -0,0 +1,206 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
import '../../../models/daily_info_model.dart';
class MiniInformationWidget extends StatefulWidget {
const MiniInformationWidget({
Key? key,
required this.dailyData,
}) : super(key: key);
final DailyInfoModel dailyData;
@override
_MiniInformationWidgetState createState() => _MiniInformationWidgetState();
}
int _value = 1;
class _MiniInformationWidgetState extends State<MiniInformationWidget> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
color: secondaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.all(defaultPadding * 0.75),
height: 40,
width: 40,
decoration: BoxDecoration(
color: widget.dailyData.color!.withOpacity(0.1),
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Icon(
widget.dailyData.icon,
color: widget.dailyData.color,
size: 18,
),
),
Padding(
padding: EdgeInsets.only(right: 12.0),
child: DropdownButton(
icon: Icon(Icons.more_vert, size: 18),
underline: SizedBox(),
style: Theme.of(context).textTheme.button,
value: _value,
items: [
DropdownMenuItem(
child: Text("Daily"),
value: 1,
),
DropdownMenuItem(
child: Text("Weekly"),
value: 2,
),
DropdownMenuItem(
child: Text("Monthly"),
value: 3,
),
],
onChanged: (int? value) {
setState(() {
_value = value!;
});
},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.dailyData.title!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
SizedBox(
height: 8,
),
Container(
child: LineChartWidget(
colors: widget.dailyData.colors,
spotsData: widget.dailyData.spots,
),
)
],
),
SizedBox(
height: 8,
),
ProgressLine(
color: widget.dailyData.color!,
percentage: widget.dailyData.percentage!,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${widget.dailyData.volumeData}",
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Colors.white70),
),
Text(
widget.dailyData.totalStorage!,
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Colors.white),
),
],
)
],
),
);
}
}
class LineChartWidget extends StatelessWidget {
const LineChartWidget({
Key? key,
required this.colors,
required this.spotsData,
}) : super(key: key);
final List<Color>? colors;
final List<FlSpot>? spotsData;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
width: 80,
height: 30,
child: LineChart(
LineChartData(
lineBarsData: [
LineChartBarData(
spots: spotsData!,
belowBarData: BarAreaData(show: false),
aboveBarData: BarAreaData(show: false),
isCurved: true,
dotData: FlDotData(show: false),
//colors: colors,
barWidth: 3),
],
lineTouchData: LineTouchData(enabled: false),
titlesData: FlTitlesData(show: false),
//axisTitleData: FlAxisTitleData(show: false),
gridData: FlGridData(show: false),
borderData: FlBorderData(show: false)),
),
),
],
);
}
}
class ProgressLine extends StatelessWidget {
const ProgressLine({
Key? key,
this.color = primaryColor,
required this.percentage,
}) : super(key: key);
final Color color;
final int percentage;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
width: double.infinity,
height: 5,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
LayoutBuilder(
builder: (context, constraints) => Container(
width: constraints.maxWidth * (percentage / 100),
height: 5,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
],
);
}
}
@@ -0,0 +1,65 @@
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
class RecentBuilds extends StatelessWidget {
const RecentBuilds({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
color: secondaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Recent Builds",
style: Theme.of(context).textTheme.subtitle1,
),
SizedBox(
width: double.infinity,
child: DataTable(
horizontalMargin: 0,
columnSpacing: defaultPadding,
columns: [
DataColumn(
label: Text("Build ID"),
),
DataColumn(
label: Text("Package Name"),
),
DataColumn(
label: Text("Version"),
),
DataColumn(
label: Text("Status"),
),
],
rows: List.generate(
7,
(index) => recentUserDataRow(),
),
),
),
],
),
);
}
DataRow recentUserDataRow() {
return DataRow(
cells: [
DataCell(Text("1")),
DataCell(Text("Resources")),
DataCell(Text("v1.2.3")),
DataCell(Icon(Icons.watch_later_outlined, color: Color(0xFF9D8D00),)),
],
);
}
}
@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
class RecentUsers extends StatelessWidget {
const RecentUsers({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
color: secondaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Your Packages",
style: Theme.of(context).textTheme.subtitle1,
),
SingleChildScrollView(
//scrollDirection: Axis.horizontal,
child: SizedBox(
width: double.infinity,
child: DataTable(
horizontalMargin: 0,
columnSpacing: defaultPadding,
columns: [
DataColumn(
label: Text("Package ID"),
),
DataColumn(
label: Text("Package Name"),
),
DataColumn(
label: Text("Number of versions"),
),
DataColumn(
label: Text("Status"),
),
DataColumn(
label: Text("Action"),
),
],
rows: List.generate(
7,
(index) => recentUserDataRow(context),
),
),
),
),
],
),
);
}
}
DataRow recentUserDataRow(BuildContext context) {
return DataRow(
cells: [
DataCell(Text("1")),
DataCell(Text("Resources")),
DataCell(Text("2")),
DataCell(Icon(Icons.watch_later_outlined, color: Color(0xFF9D8D00),)),
DataCell(
Row(
children: [
TextButton(
child: Text('View', style: TextStyle(color: greenColor)),
onPressed: () {},
),
SizedBox(
width: 6,
),
TextButton(
child: Text("Delete", style: TextStyle(color: Colors.redAccent)),
onPressed: () {
},
// Delete
),
],
),
),
],
);
}
@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
class UserDetailsMiniCard extends StatelessWidget {
const UserDetailsMiniCard({
Key? key,
required this.title,
required this.color,
required this.amountOfFiles,
required this.numberOfIncrease,
}) : super(key: key);
final Color color;
final String title, amountOfFiles;
final int numberOfIncrease;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: defaultPadding),
padding: EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
border: Border.all(width: 2, color: primaryColor.withOpacity(0.15)),
borderRadius: const BorderRadius.all(
Radius.circular(defaultPadding),
),
),
child: Row(
children: [
SizedBox(
height: 20,
width: 20,
child: Container(
color: color,
)),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
"$numberOfIncrease",
style: Theme.of(context)
.textTheme
.caption!
.copyWith(color: Colors.white70),
),
],
),
),
),
Text(amountOfFiles)
],
),
);
}
}
@@ -0,0 +1,48 @@
import 'package:aurcache/screens/dashboard/components/user_details_mini_card.dart';
import 'package:flutter/material.dart';
import '../../../core/constants/color_constants.dart';
import 'charts.dart';
class UserDetailsWidget extends StatelessWidget {
const UserDetailsWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(defaultPadding),
decoration: BoxDecoration(
color: secondaryColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Package build success",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: defaultPadding),
Chart(),
UserDetailsMiniCard(
color: const Color(0xff0a7005),
title: "Successful Builds",
amountOfFiles: "%16.7",
numberOfIncrease: 1328,
),
UserDetailsMiniCard(
color: const Color(0xff760707),
title: "Failed Builds",
amountOfFiles: "%28.3",
numberOfIncrease: 1328,
),
],
),
);
}
}
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import '../../core/constants/color_constants.dart';
import '../../responsive.dart';
import 'components/header.dart';
import 'components/mini_information_card.dart';
import 'components/recent_builds.dart';
import 'components/recent_users.dart';
import 'components/user_details_widget.dart';
class DashboardScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
//padding: EdgeInsets.all(defaultPadding),
child: Container(
padding: EdgeInsets.all(defaultPadding),
child: Column(
children: [
Header(),
SizedBox(height: defaultPadding),
MiniInformation(),
SizedBox(height: defaultPadding),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 5,
child: Column(
children: [
RecentUsers(),
SizedBox(height: defaultPadding),
RecentBuilds(),
if (Responsive.isMobile(context))
SizedBox(height: defaultPadding),
if (Responsive.isMobile(context)) UserDetailsWidget(),
],
),
),
if (!Responsive.isMobile(context))
SizedBox(width: defaultPadding),
// On Mobile means if the screen is less than 850 we dont want to show it
if (!Responsive.isMobile(context))
Expanded(
flex: 2,
child: UserDetailsWidget(),
),
],
)
],
),
),
),
);
}
}
@@ -0,0 +1,90 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../../core/constants/color_constants.dart';
class SideMenu extends StatelessWidget {
const SideMenu({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Drawer(
child: SingleChildScrollView(
// it enables scrolling
child: Column(
children: [
DrawerHeader(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// SizedBox(
// height: defaultPadding * 3,
// ),
// Image.asset(
// "assets/logo/logo_icon.png",
// scale: 5,
// ),
SizedBox(
height: defaultPadding,
),
Text("AUR Build Server")
],
)),
DrawerListTile(
title: "Dashboard",
svgSrc: "assets/icons/menu_dashbord.svg",
press: () {},
),
DrawerListTile(
title: "Builds",
svgSrc: "assets/icons/menu_tran.svg",
press: () {},
),
DrawerListTile(
title: "AUR",
svgSrc: "assets/icons/menu_task.svg",
press: () {},
),
DrawerListTile(
title: "Settings",
svgSrc: "assets/icons/menu_setting.svg",
press: () {},
),
],
),
),
);
}
}
class DrawerListTile extends StatelessWidget {
const DrawerListTile({
Key? key,
// For selecting those three line once press "Command+D"
required this.title,
required this.svgSrc,
required this.press,
}) : super(key: key);
final String title, svgSrc;
final VoidCallback press;
@override
Widget build(BuildContext context) {
return ListTile(
onTap: press,
horizontalTitleGap: 0.0,
leading: SvgPicture.asset(
svgSrc,
color: Colors.white54,
height: 16,
),
title: Text(
title,
style: TextStyle(color: Colors.white54),
),
);
}
}
@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import '../../responsive.dart';
import '../dashboard/dashboard_screen.dart';
import 'components/side_menu.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: const SideMenu(),
body: SafeArea(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// We want this side menu only for large screen
if (Responsive.isDesktop(context))
const Expanded(
// default flex = 1
// and it takes 1/6 part of the screen
child: SideMenu(),
),
Expanded(
// It takes 5/6 part of the screen
flex: 5,
child: DashboardScreen(),
),
],
),
),
);
}
}
+1
View File
@@ -0,0 +1 @@
flutter/ephemeral
+145
View File
@@ -0,0 +1,145 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "aurcache")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "eu.heili.aurcentral.aurcache")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Copy the native assets provided by the build.dart from all packages.
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
+88
View File
@@ -0,0 +1,88 @@
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)
@@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}
@@ -0,0 +1,15 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_
@@ -0,0 +1,23 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
+6
View File
@@ -0,0 +1,6 @@
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}
+104
View File
@@ -0,0 +1,104 @@
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "aurcache");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "aurcache");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,
nullptr));
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_
+397
View File
@@ -0,0 +1,397 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: fe6fec7d85975a99c73b9515a69a6e291364accfa0e4a5b3ce6de814d74b9a1c
url: "https://pub.dev"
source: hosted
version: "0.66.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
url: "https://pub.dev"
source: hosted
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8
url: "https://pub.dev"
source: hosted
version: "6.1.0"
http:
dependency: transitive
description:
name: http
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
url: "https://pub.dev"
source: hosted
version: "1.1.2"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.10.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted
version: "1.0.1"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
url: "https://pub.dev"
source: hosted
version: "3.1.3"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.dev"
source: hosted
version: "2.1.7"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43"
url: "https://pub.dev"
source: hosted
version: "1.1.9+1"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7"
url: "https://pub.dev"
source: hosted
version: "1.1.9+1"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26
url: "https://pub.dev"
source: hosted
version: "1.1.9+1"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
win32:
dependency: transitive
description:
name: win32
sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev"
source: hosted
version: "5.1.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
sdks:
dart: ">=3.2.3 <4.0.0"
flutter: ">=3.16.0"
+99
View File
@@ -0,0 +1,99 @@
name: aurcache
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: '>=3.2.3 <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
fl_chart: ^0.66.0
# flutter_icons:
# git:
# url: https://github.com/DaveatCor/flutter_icons_fork.git
# branch: master
flutter_svg: ^2.0.9
google_fonts: ^6.1.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
assets:
- assets/icons/
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
+30
View File
@@ -0,0 +1,30 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:aurcache/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+59
View File
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="aurcache">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>aurcache</title>
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: function(engineInitializer) {
engineInitializer.initializeEngine().then(function(appRunner) {
appRunner.runApp();
});
}
});
});
</script>
</body>
</html>
+35
View File
@@ -0,0 +1,35 @@
{
"name": "aurcache",
"short_name": "aurcache",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}