...
This commit is contained in:
parent
05763e7dd3
commit
1ea0b97f6d
49 changed files with 869 additions and 289 deletions
|
|
@ -1,4 +1,9 @@
|
|||
use crossterm::event::{KeyCode, KeyEvent};
|
||||
use iota_logger::{log, log_command, log_cv};
|
||||
use iota_state::{ACTIVE_TASKS, RELOAD, SHUTDOWN};
|
||||
use iota_storage::users::{user_manager, user_profile::UserProfile};
|
||||
use iota_util::file_util;
|
||||
use omikron_connector::omikron_connection::OMIKRON_CONNECTION;
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::Rect,
|
||||
|
|
@ -9,19 +14,6 @@ use ratatui::{
|
|||
use ttp_core::{CommunicationType, CommunicationValue};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
ACTIVE_TASKS, RELOAD, SHUTDOWN,
|
||||
gui::{
|
||||
elements::elements::{Element, InteractableElement, JoinableElement},
|
||||
interaction_result::InteractionResult,
|
||||
ui::FPS,
|
||||
util::borders::draw_block_joins,
|
||||
},
|
||||
log, log_command, log_cv,
|
||||
omikron::omikron_connection::OMIKRON_CONNECTION,
|
||||
users::{user_manager, user_profile::UserProfile},
|
||||
util::file_util,
|
||||
};
|
||||
use std::{
|
||||
any::Any,
|
||||
sync::{Arc, Mutex},
|
||||
|
|
@ -29,6 +21,13 @@ use std::{
|
|||
};
|
||||
use tokio::time::Instant;
|
||||
|
||||
use crate::{
|
||||
elements::elements::{Element, InteractableElement, JoinableElement},
|
||||
interaction_result::InteractionResult,
|
||||
ui::FPS,
|
||||
util::borders::draw_block_joins,
|
||||
};
|
||||
|
||||
pub struct ConsoleCard {
|
||||
focused: bool,
|
||||
pub title: String,
|
||||
|
|
@ -425,7 +424,8 @@ pub async fn run_command(command: &str) {
|
|||
ping(time).await;
|
||||
}
|
||||
["user", "add", username] => {
|
||||
if let (Some(user), Some(_)) = user_manager::create_user(username).await {
|
||||
if let (Some(user), Some(_)) = omikron_connector::user_ops::create_user(username).await
|
||||
{
|
||||
log!("Created user {}", user.user_id);
|
||||
} else {
|
||||
log!("Failed to create user");
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::any::Any;
|
|||
use crossterm::event::KeyEvent;
|
||||
use ratatui::{Frame, layout::Rect, widgets::Borders};
|
||||
|
||||
use crate::gui::{interaction_result::InteractionResult, screens::screens::Screen};
|
||||
use crate::{interaction_result::InteractionResult, screens::screens::Screen};
|
||||
|
||||
#[allow(unused)]
|
||||
pub trait Element: Send + Sync + Any {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::{any::Any, sync::Arc};
|
||||
|
||||
use crossterm::event::KeyEvent;
|
||||
use iota_state::APP_STATE;
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::Rect,
|
||||
|
|
@ -12,13 +13,10 @@ use ratatui::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
APP_STATE,
|
||||
gui::{
|
||||
elements::elements::{Element, InteractableElement, JoinableElement},
|
||||
interaction_result::InteractionResult,
|
||||
ui::UI,
|
||||
util::borders::draw_block_joins,
|
||||
},
|
||||
elements::elements::{Element, InteractableElement, JoinableElement},
|
||||
interaction_result::InteractionResult,
|
||||
ui::UI,
|
||||
util::borders::draw_block_joins,
|
||||
};
|
||||
|
||||
pub enum GRAPHS {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use crate::APP_STATE;
|
||||
use crate::gui::elements::elements::{Element, InteractableElement, JoinableElement};
|
||||
use crate::gui::interaction_result::InteractionResult;
|
||||
use crate::gui::util::borders::draw_block_joins;
|
||||
use crate::util::logger::PrintType;
|
||||
use crate::app_state::APP_STATE;
|
||||
use crate::elements::elements::{Element, InteractableElement, JoinableElement};
|
||||
use crate::interaction_result::InteractionResult;
|
||||
use crate::util::borders::draw_block_joins;
|
||||
use crossterm::event::{KeyCode, KeyEvent};
|
||||
use iota_logger::PrintType;
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::Rect,
|
||||
|
|
@ -90,7 +90,24 @@ impl LogCard {
|
|||
|
||||
fn get_logs(&self) -> Vec<UiLogEntry> {
|
||||
let state = APP_STATE.lock().unwrap();
|
||||
state.get_logs().iter().cloned().collect()
|
||||
state
|
||||
.get_logs()
|
||||
.iter()
|
||||
.map(|e| UiLogEntry {
|
||||
timestamp_ms: e.timestamp_ms,
|
||||
sender: match e.sender.as_str() {
|
||||
"Call" => PrintType::Call,
|
||||
"Client" => PrintType::Client,
|
||||
"Iota" => PrintType::Iota,
|
||||
"Omikron" => PrintType::Omikron,
|
||||
"Omega" => PrintType::Omega,
|
||||
"Command" => PrintType::Command,
|
||||
_ => PrintType::General,
|
||||
},
|
||||
message: e.message.clone(),
|
||||
is_error: e.is_error,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn find_split_point(s: &str, max_width: usize) -> usize {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ui::{UI, UNIQUE};
|
||||
use crate::{RELOAD, SHUTDOWN};
|
||||
use crate::ui::UI;
|
||||
use crossterm::event::{Event, KeyEvent, KeyEventKind, KeyModifiers, poll, read};
|
||||
use iota_state::{RELOAD, SHUTDOWN, UNIQUE};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Duration;
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
use crate::util::file_util::save_file;
|
||||
use json::{self, JsonError, JsonValue};
|
||||
|
||||
pub fn create_languages() -> Result<(), JsonError> {
|
||||
let mut frontend_messages = JsonValue::new_object();
|
||||
let mut omikron_messages = JsonValue::new_object();
|
||||
let mut button_texts = JsonValue::new_object();
|
||||
let mut general_texts = JsonValue::new_object();
|
||||
let mut debug_messages = JsonValue::new_object();
|
||||
|
||||
frontend_messages.insert("error", "An error occurred")?;
|
||||
// FRONTEND
|
||||
frontend_messages.insert("get_chats", "User {} is loading conversations")?;
|
||||
frontend_messages.insert("message_get", "User {} is loading messages")?;
|
||||
frontend_messages.insert("get_communities", "User {} is loading communities")?;
|
||||
frontend_messages.insert("client_connected", "Client {} connected")?;
|
||||
frontend_messages.insert("add_conversation", "User {} added {}")?;
|
||||
frontend_messages.insert("message_send", "User {} sent a message")?;
|
||||
|
||||
// OMIKRON
|
||||
omikron_messages.insert(
|
||||
"identification_response",
|
||||
"IOTA identified on Omikron, {} users!",
|
||||
)?;
|
||||
omikron_messages.insert(
|
||||
"send_message_failed",
|
||||
"Failed to send message to Omikron: {}",
|
||||
)?;
|
||||
omikron_messages.insert("connection_failed", "Failed to connect to Omikron: {}")?;
|
||||
|
||||
// BUTTONS
|
||||
button_texts.insert("exit", "Exit")?;
|
||||
|
||||
// GENERAL
|
||||
general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############")?;
|
||||
general_texts.insert("user_id", "USER ID: {}")?;
|
||||
general_texts.insert("user_ids", "USER IDS: {}")?;
|
||||
general_texts.insert("user_load_failed", "Failed to load user data")?;
|
||||
general_texts.insert("setup_completed", "Launched")?;
|
||||
general_texts.insert(
|
||||
"community_active",
|
||||
"Communities active on ws://{}:{}/community/...",
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error",
|
||||
"Failed to start community socket on port {}!",
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error_admin",
|
||||
"Failed to start community socket on port {}! Run with admin privileges",
|
||||
)?;
|
||||
// DEBUG
|
||||
debug_messages.insert("", "")?;
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"frontend.json",
|
||||
&frontend_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"omikron.json",
|
||||
&omikron_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"buttons.json",
|
||||
&button_texts.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"debug.json",
|
||||
&debug_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"general.json",
|
||||
&general_texts.to_string(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
use crate::util::file_util::{self};
|
||||
use json::parse;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LanguagePack {
|
||||
language: HashMap<String, String>,
|
||||
}
|
||||
|
||||
pub static LANGUAGE_PACK: Lazy<Mutex<LanguagePack>> =
|
||||
Lazy::new(|| Mutex::new(LanguagePack::new("en_INT")));
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_language() -> LanguagePack {
|
||||
LANGUAGE_PACK.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_languages() -> Vec<String> {
|
||||
file_util::get_children("languages")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_language(language: &str) {
|
||||
LANGUAGE_PACK.lock().unwrap().language.clear();
|
||||
LANGUAGE_PACK.lock().unwrap().load_language(language);
|
||||
}
|
||||
|
||||
pub fn from_key(key: &str) -> String {
|
||||
LANGUAGE_PACK
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_translation(key)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn format(key: &str, args: &[&str]) -> String {
|
||||
let message = from_key(key);
|
||||
let mut formatted = String::new();
|
||||
let parts = message.split("{}");
|
||||
for (i, part) in parts.enumerate() {
|
||||
formatted.push_str(part);
|
||||
if i < args.len() {
|
||||
formatted.push_str(args[i]);
|
||||
}
|
||||
}
|
||||
formatted
|
||||
}
|
||||
|
||||
impl LanguagePack {
|
||||
pub fn new(language: &str) -> Self {
|
||||
let mut pack = LanguagePack {
|
||||
language: HashMap::new(),
|
||||
};
|
||||
pack.load_language(language);
|
||||
pack
|
||||
}
|
||||
|
||||
pub fn load_language(&mut self, language: &str) {
|
||||
let path = format!("languages/{}/", language);
|
||||
|
||||
let frontend_messages = file_util::load_file(&path, "frontend.json");
|
||||
let frontend_messages = parse(&frontend_messages).unwrap();
|
||||
for (key, value) in frontend_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let omikron_messages = file_util::load_file(&path, "omikron.json");
|
||||
let omikron_messages = parse(&omikron_messages).unwrap();
|
||||
for (key, value) in omikron_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let button_texts = file_util::load_file(&path, "buttons.json");
|
||||
let button_texts = parse(&button_texts).unwrap();
|
||||
for (key, value) in button_texts.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let debug_messages = file_util::load_file(&path, "debug.json");
|
||||
let debug_messages = parse(&debug_messages).unwrap();
|
||||
for (key, value) in debug_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let general_messages = file_util::load_file(&path, "general.json");
|
||||
let general_messages = parse(&general_messages).unwrap();
|
||||
for (key, value) in general_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
}
|
||||
pub fn get_translation(&self, key: &str) -> String {
|
||||
match self.language.get(key) {
|
||||
Some(v) if !v.is_empty() => v.clone(),
|
||||
_ => key.to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
pub mod language_creator;
|
||||
pub mod language_manager;
|
||||
|
|
@ -2,8 +2,13 @@ use crate::{
|
|||
interaction_result::InteractionResult,
|
||||
screens::{md_viewer::FileViewer, screens::Screen},
|
||||
ui::UI,
|
||||
util::{
|
||||
buttons::{checkbox, draw_buttons},
|
||||
terms_focus::Focus,
|
||||
},
|
||||
};
|
||||
use crossterm::event::{KeyCode, KeyEvent};
|
||||
use iota_terms::{TermsType, get_link, get_terms};
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
|
|
@ -14,6 +19,13 @@ use ratatui::{
|
|||
use std::{any::Any, pin::Pin, sync::Arc};
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UserChoice {
|
||||
Deny,
|
||||
AcceptEULA,
|
||||
AcceptAll,
|
||||
}
|
||||
|
||||
pub struct TermsCheckerScreen {
|
||||
ui: Arc<UI>,
|
||||
sender: Option<oneshot::Sender<UserChoice>>,
|
||||
|
|
@ -268,9 +280,9 @@ impl Screen for TermsCheckerScreen {
|
|||
}
|
||||
KeyCode::Char('o') | KeyCode::Char('O') => {
|
||||
let terms_type = match self.focus {
|
||||
Focus::Eula => Some(Type::EULA),
|
||||
Focus::Tos => Some(Type::TOS),
|
||||
Focus::Pp => Some(Type::PP),
|
||||
Focus::Eula => Some(TermsType::EULA),
|
||||
Focus::Tos => Some(TermsType::TOS),
|
||||
Focus::Pp => Some(TermsType::PP),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(terms_type) = terms_type {
|
||||
|
|
@ -288,15 +300,15 @@ impl Screen for TermsCheckerScreen {
|
|||
}
|
||||
KeyCode::Char('l') | KeyCode::Char('L') => match self.focus {
|
||||
Focus::Eula => {
|
||||
let _ = open::that(get_link(Type::EULA));
|
||||
let _ = open::that(get_link(TermsType::EULA));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
Focus::Tos => {
|
||||
let _ = open::that(get_link(Type::TOS));
|
||||
let _ = open::that(get_link(TermsType::TOS));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
Focus::Pp => {
|
||||
let _ = open::that(get_link(Type::PP));
|
||||
let _ = open::that(get_link(TermsType::PP));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
_ => InteractionResult::Unhandled,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
use crate::screens::terms_checker::UserChoice;
|
||||
use crate::{
|
||||
interaction_result::InteractionResult,
|
||||
screens::{md_viewer::FileViewer, screens::Screen},
|
||||
util::{
|
||||
buttons::{checkbox, draw_buttons},
|
||||
terms_focus::Focus,
|
||||
},
|
||||
};
|
||||
use chrono::{Local, TimeZone, Utc};
|
||||
use crossterm::event::{KeyCode, KeyEvent};
|
||||
use iota_terms::{Doc, TermsType, get_newest_link, get_terms};
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||
|
|
@ -14,6 +20,13 @@ use ratatui::{
|
|||
use std::any::Any;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UpdateDecision {
|
||||
NoChange,
|
||||
Future { newest: Doc },
|
||||
Forced(Doc),
|
||||
}
|
||||
|
||||
pub struct TermsUpdaterScreen {
|
||||
sender: Option<oneshot::Sender<UserChoice>>,
|
||||
|
||||
|
|
@ -635,9 +648,9 @@ impl Screen for TermsUpdaterScreen {
|
|||
},
|
||||
KeyCode::Char('o') | KeyCode::Char('O') => {
|
||||
let terms_type = match self.focus {
|
||||
Focus::Eula => Some(Type::EULA),
|
||||
Focus::Tos => Some(Type::TOS),
|
||||
Focus::Pp => Some(Type::PP),
|
||||
Focus::Eula => Some(TermsType::EULA),
|
||||
Focus::Tos => Some(TermsType::TOS),
|
||||
Focus::Pp => Some(TermsType::PP),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
|
@ -655,15 +668,15 @@ impl Screen for TermsUpdaterScreen {
|
|||
}
|
||||
KeyCode::Char('l') | KeyCode::Char('L') => match self.focus {
|
||||
Focus::Eula => {
|
||||
let _ = open::that(get_newest_link(Type::EULA));
|
||||
let _ = open::that(get_newest_link(TermsType::EULA));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
Focus::Tos => {
|
||||
let _ = open::that(get_newest_link(Type::TOS));
|
||||
let _ = open::that(get_newest_link(TermsType::TOS));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
Focus::Pp => {
|
||||
let _ = open::that(get_newest_link(Type::PP));
|
||||
let _ = open::that(get_newest_link(TermsType::PP));
|
||||
InteractionResult::Handled
|
||||
}
|
||||
_ => InteractionResult::Unhandled,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::{
|
|||
screens::screens::Screen,
|
||||
};
|
||||
use crossterm::event::KeyEvent;
|
||||
use iota_state::{ACTIVE_TASKS, SHUTDOWN, UNIQUE};
|
||||
use once_cell::sync::Lazy;
|
||||
use ratatui::{Terminal, backend::CrosstermBackend, init};
|
||||
use std::{
|
||||
|
|
@ -17,7 +18,6 @@ use std::{
|
|||
use tokio::{sync::RwLock, time::Instant};
|
||||
|
||||
/// UI state and rendering
|
||||
pub static UNIQUE: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
pub static FPS: Lazy<RwLock<(f64, f64)>> = Lazy::new(|| RwLock::new((0.0, 0.0)));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue