Archived
2
0
This repository has been archived on 2025-04-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
repo/src/main.rs
T
2025-02-12 14:33:42 +02:00

197 lines
5.9 KiB
Rust

mod authentication;
mod input;
mod search;
//mod statistics;
mod widget;
use std::sync::Arc;
use crate::authentication::Authentication;
use crate::search::Search;
//use crate::statistics::Statistics;
use data::{MySqlPool, MySqlSearchAdapter, MySqlUserAdapter, SqlxPool};
use iced::{
Element, Subscription, Task, Theme,
futures::lock::Mutex,
widget::{center, row},
window,
};
use service::{
Authenticated, AuthenticationAdapter, AuthenticationService, SearchAdapter, SearchService,
};
struct Repository {
scale_factor: f64,
main_id: window::Id,
screen: Screen,
authenticated: Option<Authenticated>,
search: Search<SearchService<SearchAdapter<MySqlPool, SqlxPool, MySqlSearchAdapter>>>,
authentication: Authentication<
AuthenticationService<AuthenticationAdapter<MySqlPool, SqlxPool, MySqlUserAdapter>>,
>,
}
enum Screen {
Search,
// Statistics,
Authentication,
}
#[derive(Debug)]
enum Message {
ScaleUp,
ScaleDown,
WindowOpened(window::Id),
WindowClosed(window::Id),
Search(search::Message),
Authentecation(authentication::Message),
}
impl Repository {
fn new() -> (Self, Task<Message>) {
let (main_id, open_task) = window::open(window::Settings::default());
// let (main_window, main_window_task) = MainWindow::new();
let pool = MySqlPool::new(
SqlxPool::connect_lazy(
&std::env::var("DATABASE_URL")
.expect("environment variable `DATABASE_URL` should be set"),
)
.unwrap(),
);
let auth_service = Arc::new(Mutex::new(AuthenticationService::new(
AuthenticationAdapter::new(pool.clone()),
)));
let search_service = Arc::new(Mutex::new(SearchService::new(SearchAdapter::new(
pool.clone(),
))));
(
Self {
main_id,
scale_factor: 1.4,
screen: Screen::Search,
authenticated: None,
search: Search::new(search_service),
authentication: Authentication::new(auth_service),
},
Task::batch([
open_task.map(Message::WindowOpened),
// main_window_task.map(Message::MainWindow),
]),
)
}
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::ScaleUp => self.scale_factor = (self.scale_factor + 0.2).min(5.0),
Message::ScaleDown => self.scale_factor = (self.scale_factor - 0.2).max(0.2),
Message::WindowOpened(id) => {
log!("Window opened: {id}");
return iced::widget::focus_next();
}
Message::WindowClosed(id) => {
log!("Window closed: {id}");
if id == self.main_id {
return iced::exit();
}
}
Message::Authentecation(message) => {
if let Some(event) = self.authentication.update(message) {
match event {
authentication::Event::Task(task) => {
return task.map(Message::Authentecation);
}
authentication::Event::Authenticated(authenticated) => {
log!("authenticated as {:#?}", authenticated);
self.authenticated = Some(authenticated);
self.screen = Screen::Search;
}
}
}
}
Message::Search(m) => {
if let Some(event) = self.search.update(m) {
match event {
search::Event::Task(task) => {
return task.map(Message::Search);
}
search::Event::OpenPackage(id) => {
log!("opening package {id}")
}
search::Event::OpenBase(id) => {
log!("opening package base {id}")
}
search::Event::OpenURL(url) => {
log!("opening url {url}")
}
}
}
}
}
Task::none()
}
fn view(&self, id: window::Id) -> Element<Message> {
if self.main_id == id {
match self.screen {
Screen::Search => self.search.view().map(Message::Search),
Screen::Authentication => self.authentication.view().map(Message::Authentecation),
}
} else {
center(row!["This window is unknown.", "It may be closed."]).into()
}
}
fn title(&self, _: window::Id) -> String {
// "Repository".into()
self.authentication.title()
}
fn subscription(&self) -> Subscription<Message> {
use iced::keyboard::{self, Key, Modifiers};
let hotkeys = keyboard::on_key_press(|key, modifiers| match (modifiers, key) {
(Modifiers::CTRL, Key::Character(c)) if c == "-" => Some(Message::ScaleDown),
(Modifiers::CTRL, Key::Character(c)) if c == "=" || c == "+" => Some(Message::ScaleUp),
_ => None,
});
Subscription::batch([hotkeys, window::close_events().map(Message::WindowClosed)])
}
const fn scale_factor(&self, _: window::Id) -> f64 {
self.scale_factor
}
const fn theme(_: &Self, _: window::Id) -> Theme {
Theme::TokyoNight
}
}
#[macro_export]
macro_rules! log {
($($arg:tt)*) => {
#[cfg(debug_assertions)]
println!($($arg)*)
};
}
fn main() -> iced::Result {
iced::daemon(Repository::title, Repository::update, Repository::view)
.subscription(Repository::subscription)
.scale_factor(Repository::scale_factor)
.theme(Repository::theme)
.run_with(Repository::new)
}