[WIP] Terms Checker TODO: Ignore allready accepted Terms in Updater.
This commit is contained in:
parent
b81276dd18
commit
b8029ca829
4 changed files with 232 additions and 112 deletions
|
|
@ -8,7 +8,6 @@ use crate::{
|
||||||
util::file_util::{load_file, save_file},
|
util::file_util::{load_file, save_file},
|
||||||
};
|
};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use tokio::task;
|
|
||||||
|
|
||||||
pub struct ConsentManager;
|
pub struct ConsentManager;
|
||||||
impl ConsentManager {
|
impl ConsentManager {
|
||||||
|
|
@ -30,7 +29,9 @@ impl ConsentManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((eula_update, tos_update, privacy_update)) = Self::get_updates().await {
|
if let Some((eula_update, tos_update, privacy_update)) = Self::get_updates().await {
|
||||||
let is_forced = eula_update.is_err() || tos_update.is_err() || privacy_update.is_err();
|
let _is_forced = matches!(eula_update, UpdateDecision::Forced(_))
|
||||||
|
|| matches!(tos_update, UpdateDecision::Forced(_))
|
||||||
|
|| matches!(privacy_update, UpdateDecision::Forced(_));
|
||||||
|
|
||||||
let updater_logic = async move {
|
let updater_logic = async move {
|
||||||
let state_to_update = terms_updater::run_consent_ui(
|
let state_to_update = terms_updater::run_consent_ui(
|
||||||
|
|
@ -45,12 +46,14 @@ impl ConsentManager {
|
||||||
|
|
||||||
save_file("", "agreements", &state_to_update.sanitize().to_string());
|
save_file("", "agreements", &state_to_update.sanitize().to_string());
|
||||||
};
|
};
|
||||||
|
// ======================================================== //
|
||||||
if is_forced {
|
// TODO: Implement UI Drawing order, draw update As PoPup //
|
||||||
updater_logic.await;
|
// ======================================================== //
|
||||||
} else {
|
//if is_forced {
|
||||||
task::spawn(updater_logic);
|
updater_logic.await;
|
||||||
}
|
//} else {
|
||||||
|
//task::spawn(updater_logic);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
let final_state = ConsentState::from_str(&load_file("", "agreements")).sanitize();
|
let final_state = ConsentState::from_str(&load_file("", "agreements")).sanitize();
|
||||||
|
|
@ -64,9 +67,9 @@ impl ConsentManager {
|
||||||
// Ok(None) indicates no update
|
// Ok(None) indicates no update
|
||||||
// Ok(Some) Indicates a future update
|
// Ok(Some) Indicates a future update
|
||||||
// Err indicates a update that has to be accepted before the programm can continue
|
// Err indicates a update that has to be accepted before the programm can continue
|
||||||
Result<Option<Doc>, Doc>,
|
UpdateDecision,
|
||||||
Result<Option<Doc>, Doc>,
|
UpdateDecision,
|
||||||
Result<Option<Doc>, Doc>,
|
UpdateDecision,
|
||||||
)> {
|
)> {
|
||||||
let file = load_file("", "agreements");
|
let file = load_file("", "agreements");
|
||||||
let accepted_state = ConsentState::from_str(&file).sanitize();
|
let accepted_state = ConsentState::from_str(&file).sanitize();
|
||||||
|
|
@ -76,46 +79,47 @@ impl ConsentManager {
|
||||||
Some((newest_eula, newest_tos, newest_privacy)),
|
Some((newest_eula, newest_tos, newest_privacy)),
|
||||||
) = (get_current_docs().await, get_newest_docs().await)
|
) = (get_current_docs().await, get_newest_docs().await)
|
||||||
{
|
{
|
||||||
let eula_update: Result<Option<Doc>, Doc> =
|
let eula_update: UpdateDecision = if current_eula.equals_some(&accepted_state.eula) {
|
||||||
if current_eula.equals_some(&accepted_state.eula) {
|
if current_eula.equals(&newest_eula) {
|
||||||
if current_eula.equals(&newest_eula) {
|
UpdateDecision::NoChange
|
||||||
Ok(None)
|
} else {
|
||||||
} else {
|
UpdateDecision::Future {
|
||||||
Ok(Some(newest_eula))
|
newest: newest_eula,
|
||||||
}
|
}
|
||||||
} else if newest_eula.equals_some(&accepted_state.eula) {
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Err(current_eula)
|
|
||||||
};
|
|
||||||
|
|
||||||
let tos_update: Result<Option<Doc>, Doc> = if newest_tos
|
|
||||||
.equals_some(&accepted_state.tos)
|
|
||||||
{
|
|
||||||
Ok(None)
|
|
||||||
} else if accepted_state.accepted_tos && current_tos.equals_some(&accepted_state.tos) {
|
|
||||||
if current_tos.equals(&newest_tos) {
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Ok(Some(newest_tos))
|
|
||||||
}
|
}
|
||||||
|
} else if newest_eula.equals_some(&accepted_state.eula) {
|
||||||
|
UpdateDecision::NoChange
|
||||||
} else {
|
} else {
|
||||||
Err(current_tos)
|
UpdateDecision::Forced(current_eula)
|
||||||
};
|
};
|
||||||
|
|
||||||
let privacy_update: Result<Option<Doc>, Doc> =
|
let tos_update: UpdateDecision = if newest_tos.equals_some(&accepted_state.tos) {
|
||||||
|
UpdateDecision::NoChange
|
||||||
|
} else if accepted_state.accepted_tos && current_tos.equals_some(&accepted_state.tos) {
|
||||||
|
if current_tos.equals(&newest_tos) {
|
||||||
|
UpdateDecision::NoChange
|
||||||
|
} else {
|
||||||
|
UpdateDecision::Future { newest: newest_tos }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UpdateDecision::Forced(current_tos)
|
||||||
|
};
|
||||||
|
|
||||||
|
let privacy_update: UpdateDecision =
|
||||||
if newest_privacy.equals_some(&accepted_state.privacy) {
|
if newest_privacy.equals_some(&accepted_state.privacy) {
|
||||||
Ok(None)
|
UpdateDecision::NoChange
|
||||||
} else if accepted_state.accepted_pp
|
} else if accepted_state.accepted_pp
|
||||||
&& current_privacy.equals_some(&accepted_state.privacy)
|
&& current_privacy.equals_some(&accepted_state.privacy)
|
||||||
{
|
{
|
||||||
if current_privacy.equals(&newest_privacy) {
|
if current_privacy.equals(&newest_privacy) {
|
||||||
Ok(None)
|
UpdateDecision::NoChange
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(newest_privacy))
|
UpdateDecision::Future {
|
||||||
|
newest: newest_privacy,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(current_privacy)
|
UpdateDecision::Forced(current_privacy)
|
||||||
};
|
};
|
||||||
Some((eula_update, tos_update, privacy_update))
|
Some((eula_update, tos_update, privacy_update))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -131,14 +135,26 @@ pub enum UserChoice {
|
||||||
AcceptAll,
|
AcceptAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum UpdateDecision {
|
||||||
|
NoChange,
|
||||||
|
Future { newest: Doc },
|
||||||
|
Forced(Doc),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ConsentState {
|
pub struct ConsentState {
|
||||||
pub eula: Option<Doc>,
|
pub eula: Option<Doc>,
|
||||||
pub accepted_eula: bool,
|
pub accepted_eula: bool,
|
||||||
|
pub future_eula: Option<Doc>,
|
||||||
|
|
||||||
pub tos: Option<Doc>,
|
pub tos: Option<Doc>,
|
||||||
pub accepted_tos: bool,
|
pub accepted_tos: bool,
|
||||||
|
pub future_tos: Option<Doc>,
|
||||||
|
|
||||||
pub privacy: Option<Doc>,
|
pub privacy: Option<Doc>,
|
||||||
pub accepted_pp: bool,
|
pub accepted_pp: bool,
|
||||||
|
pub future_privacy: Option<Doc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsentState {
|
impl ConsentState {
|
||||||
|
|
@ -165,12 +181,6 @@ impl ConsentState {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(eula) = &self.eula {
|
if let Some(eula) = &self.eula {
|
||||||
println!(
|
|
||||||
"EULA: {}, {}, {}",
|
|
||||||
self.accepted_eula,
|
|
||||||
eula.get_version(),
|
|
||||||
eula.get_hash()
|
|
||||||
);
|
|
||||||
file_out.push_str(&format!("\
|
file_out.push_str(&format!("\
|
||||||
\n\"EULA=true\" indicates that you read, understood and accepted Tensamin's End User Licence agreement. You can find our EULA at https://legal.tensamin.net/eula/\
|
\n\"EULA=true\" indicates that you read, understood and accepted Tensamin's End User Licence agreement. You can find our EULA at https://legal.tensamin.net/eula/\
|
||||||
\nEULA={}\
|
\nEULA={}\
|
||||||
|
|
@ -204,6 +214,44 @@ impl ConsentState {
|
||||||
\nEULA=false\
|
\nEULA=false\
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(eula) = &self.future_eula {
|
||||||
|
file_out.push_str(&format!(
|
||||||
|
"\
|
||||||
|
\nFUTURE-EULA-VERSION={}\
|
||||||
|
\nFUTURE-EULA-HASH={}\
|
||||||
|
\nFUTURE-EULA-TIME={}\
|
||||||
|
",
|
||||||
|
eula.get_version(),
|
||||||
|
eula.get_hash(),
|
||||||
|
eula.get_time()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if let Some(tos) = &self.future_tos {
|
||||||
|
file_out.push_str(&format!(
|
||||||
|
"\
|
||||||
|
\nFUTURE-Terms-of-Service-VERSION={}\
|
||||||
|
\nFUTURE-Terms-of-Service-HASH={}\
|
||||||
|
\nFUTURE-Terms-of-Service-TIME={}\
|
||||||
|
",
|
||||||
|
tos.get_version(),
|
||||||
|
tos.get_hash(),
|
||||||
|
tos.get_time()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if let Some(pp) = &self.future_privacy {
|
||||||
|
file_out.push_str(&format!(
|
||||||
|
"\
|
||||||
|
\nFUTURE-Privacy-Policy-VERSION={}\
|
||||||
|
\nFUTURE-Privacy-Policy-HASH={}\
|
||||||
|
\nFUTURE-Privacy-Policy-TIME={}\
|
||||||
|
",
|
||||||
|
pp.get_version(),
|
||||||
|
pp.get_hash(),
|
||||||
|
pp.get_time()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
file_out
|
file_out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,6 +266,18 @@ impl ConsentState {
|
||||||
let mut tos_version = String::new();
|
let mut tos_version = String::new();
|
||||||
let mut tos_hash = String::new();
|
let mut tos_hash = String::new();
|
||||||
|
|
||||||
|
let mut future_eula_version = String::new();
|
||||||
|
let mut future_eula_hash = String::new();
|
||||||
|
let mut future_eula_time = String::new();
|
||||||
|
|
||||||
|
let mut future_tos_version = String::new();
|
||||||
|
let mut future_tos_hash = String::new();
|
||||||
|
let mut future_tos_time = String::new();
|
||||||
|
|
||||||
|
let mut future_pp_version = String::new();
|
||||||
|
let mut future_pp_hash = String::new();
|
||||||
|
let mut future_pp_time = String::new();
|
||||||
|
|
||||||
let mut unix = String::new();
|
let mut unix = String::new();
|
||||||
|
|
||||||
for line in s.lines() {
|
for line in s.lines() {
|
||||||
|
|
@ -241,9 +301,30 @@ impl ConsentState {
|
||||||
pp_hash = v.to_string();
|
pp_hash = v.to_string();
|
||||||
} else if let Some(v) = line.strip_prefix("UNIX=") {
|
} else if let Some(v) = line.strip_prefix("UNIX=") {
|
||||||
unix = v.to_string();
|
unix = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-EULA-VERSION=") {
|
||||||
|
future_eula_version = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-EULA-HASH=") {
|
||||||
|
future_eula_hash = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-EULA-TIME=") {
|
||||||
|
future_eula_time = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Terms-of-Service-VERSION=") {
|
||||||
|
future_tos_version = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Terms-of-Service-HASH=") {
|
||||||
|
future_tos_hash = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Terms-of-Service-TIME=") {
|
||||||
|
future_tos_time = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Privacy-Policy-VERSION=") {
|
||||||
|
future_pp_version = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Privacy-Policy-HASH=") {
|
||||||
|
future_pp_hash = v.to_string();
|
||||||
|
} else if let Some(v) = line.strip_prefix("FUTURE-Privacy-Policy-TIME=") {
|
||||||
|
future_pp_time = v.to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let unix: u64 = unix.parse::<u64>().unwrap_or(0);
|
let unix: u64 = unix.parse::<u64>().unwrap_or(0);
|
||||||
|
let future_eula_time = future_eula_time.parse::<u64>().unwrap_or(0);
|
||||||
|
let future_tos_time = future_tos_time.parse::<u64>().unwrap_or(0);
|
||||||
|
let future_pp_time = future_pp_time.parse::<u64>().unwrap_or(0);
|
||||||
Self {
|
Self {
|
||||||
accepted_eula: eula,
|
accepted_eula: eula,
|
||||||
eula: Some(Doc::new(eula_version, eula_hash, Type::EULA, unix)),
|
eula: Some(Doc::new(eula_version, eula_hash, Type::EULA, unix)),
|
||||||
|
|
@ -251,6 +332,36 @@ impl ConsentState {
|
||||||
privacy: Some(Doc::new(pp_version, pp_hash, Type::PP, unix)),
|
privacy: Some(Doc::new(pp_version, pp_hash, Type::PP, unix)),
|
||||||
accepted_tos: tos,
|
accepted_tos: tos,
|
||||||
tos: Some(Doc::new(tos_version, tos_hash, Type::TOS, unix)),
|
tos: Some(Doc::new(tos_version, tos_hash, Type::TOS, unix)),
|
||||||
|
future_eula: if !future_eula_version.is_empty() {
|
||||||
|
Some(Doc::new(
|
||||||
|
future_eula_version,
|
||||||
|
future_eula_hash,
|
||||||
|
Type::EULA,
|
||||||
|
future_eula_time,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
future_tos: if !future_tos_version.is_empty() {
|
||||||
|
Some(Doc::new(
|
||||||
|
future_tos_version,
|
||||||
|
future_tos_hash,
|
||||||
|
Type::TOS,
|
||||||
|
future_tos_time,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
future_privacy: if !future_pp_version.is_empty() {
|
||||||
|
Some(Doc::new(
|
||||||
|
future_pp_version,
|
||||||
|
future_pp_hash,
|
||||||
|
Type::PP,
|
||||||
|
future_pp_time,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
}
|
}
|
||||||
.sanitize()
|
.sanitize()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,45 +9,17 @@ pub enum Focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Focus {
|
impl Focus {
|
||||||
pub fn next(&mut self, state: (bool, bool, bool)) {
|
pub fn next(&mut self, order: &[Focus]) {
|
||||||
*self = match self {
|
if let Some(pos) = order.iter().position(|&f| f == *self) {
|
||||||
Focus::Eula => Focus::Tos,
|
let next_pos = (pos + 1) % order.len();
|
||||||
Focus::Tos => Focus::Pp,
|
*self = order[next_pos];
|
||||||
Focus::Pp => Focus::Cancel,
|
}
|
||||||
Focus::Cancel => {
|
|
||||||
if state.0 {
|
|
||||||
Focus::Continue
|
|
||||||
} else {
|
|
||||||
Focus::Eula
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Focus::Continue => {
|
|
||||||
if state.0 && state.1 && state.2 {
|
|
||||||
Focus::ContinueAll
|
|
||||||
} else {
|
|
||||||
Focus::Eula
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Focus::ContinueAll => Focus::Eula,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&mut self, state: (bool, bool, bool)) {
|
pub fn prev(&mut self, order: &[Focus]) {
|
||||||
*self = match self {
|
if let Some(pos) = order.iter().position(|&f| f == *self) {
|
||||||
Focus::Eula => {
|
let prev_pos = if pos == 0 { order.len() - 1 } else { pos - 1 };
|
||||||
if state.0 && state.1 && state.2 {
|
*self = order[prev_pos];
|
||||||
Focus::ContinueAll
|
}
|
||||||
} else if state.0 {
|
|
||||||
Focus::Continue
|
|
||||||
} else {
|
|
||||||
Focus::Cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Focus::Tos => Focus::Eula,
|
|
||||||
Focus::Pp => Focus::Tos,
|
|
||||||
Focus::Cancel => Focus::Pp,
|
|
||||||
Focus::Continue => Focus::Cancel,
|
|
||||||
Focus::ContinueAll => Focus::Continue,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,10 +207,17 @@ pub async fn run_consent_ui(mut consent: ConsentState) -> ConsentState {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut possible_states = vec![Focus::Eula, Focus::Tos, Focus::Pp, Focus::Cancel];
|
||||||
|
if eula {
|
||||||
|
possible_states.push(Focus::Continue);
|
||||||
|
if tos && pp {
|
||||||
|
possible_states.push(Focus::ContinueAll);
|
||||||
|
}
|
||||||
|
}
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Esc => break UserChoice::Deny,
|
KeyCode::Esc => break UserChoice::Deny,
|
||||||
KeyCode::Up | KeyCode::Left => focus.prev((eula, tos, pp)),
|
KeyCode::Up | KeyCode::Left => focus.prev(&possible_states),
|
||||||
KeyCode::Down | KeyCode::Right | KeyCode::Tab => focus.next((eula, tos, pp)),
|
KeyCode::Down | KeyCode::Right | KeyCode::Tab => focus.next(&possible_states),
|
||||||
KeyCode::Char('q') | KeyCode::Char('Q') => break UserChoice::Deny,
|
KeyCode::Char('q') | KeyCode::Char('Q') => break UserChoice::Deny,
|
||||||
KeyCode::Char('o') | KeyCode::Char('O') => {
|
KeyCode::Char('o') | KeyCode::Char('O') => {
|
||||||
let terms_type = match focus {
|
let terms_type = match focus {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::terms::{
|
use crate::terms::{
|
||||||
consent_state::{ConsentState, UserChoice},
|
consent_state::{ConsentState, UpdateDecision, UserChoice},
|
||||||
doc::Doc,
|
doc::Doc,
|
||||||
focus::Focus,
|
focus::Focus,
|
||||||
md_viewer::FileViewer,
|
md_viewer::FileViewer,
|
||||||
|
|
@ -16,26 +16,29 @@ use std::time::Duration;
|
||||||
|
|
||||||
pub async fn run_consent_ui(
|
pub async fn run_consent_ui(
|
||||||
mut consent: ConsentState,
|
mut consent: ConsentState,
|
||||||
consent_eula: Result<Option<Doc>, Doc>,
|
consent_eula: UpdateDecision,
|
||||||
consent_tos: Result<Option<Doc>, Doc>,
|
consent_tos: UpdateDecision,
|
||||||
consent_pp: Result<Option<Doc>, Doc>,
|
consent_pp: UpdateDecision,
|
||||||
) -> ConsentState {
|
) -> ConsentState {
|
||||||
let mut terminal = ratatui::init();
|
let mut terminal = ratatui::init();
|
||||||
let (eula_needed, eula_future, future_eula) = match consent_eula {
|
|
||||||
Ok(Some(future)) => (true, true, Some(future)),
|
let (eula_needed, eula_future, eula_for_future): (bool, bool, Option<Doc>) = match consent_eula
|
||||||
Ok(None) => (false, false, None),
|
{
|
||||||
Err(future) => (true, false, Some(future)),
|
UpdateDecision::NoChange => (false, false, None),
|
||||||
|
UpdateDecision::Future { newest } => (true, true, Some(newest)),
|
||||||
|
UpdateDecision::Forced(doc) => (true, false, Some(doc)),
|
||||||
};
|
};
|
||||||
let (tos_needed, tos_future, future_tos) = match consent_tos {
|
let (tos_needed, tos_future, tos_for_future): (bool, bool, Option<Doc>) = match consent_tos {
|
||||||
Ok(Some(future)) => (true, true, Some(future)),
|
UpdateDecision::NoChange => (false, false, None),
|
||||||
Ok(None) => (false, false, None),
|
UpdateDecision::Future { newest } => (true, true, Some(newest)),
|
||||||
Err(future) => (true, false, Some(future)),
|
UpdateDecision::Forced(doc) => (true, false, Some(doc)),
|
||||||
};
|
};
|
||||||
let (pp_needed, pp_future, future_privacy) = match consent_pp {
|
let (pp_needed, pp_future, pp_for_future): (bool, bool, Option<Doc>) = match consent_pp {
|
||||||
Ok(Some(future)) => (true, true, Some(future)),
|
UpdateDecision::NoChange => (false, false, None),
|
||||||
Ok(None) => (false, false, None),
|
UpdateDecision::Future { newest } => (true, true, Some(newest)),
|
||||||
Err(future) => (true, false, Some(future)),
|
UpdateDecision::Forced(doc) => (true, false, Some(doc)),
|
||||||
};
|
};
|
||||||
|
let update_needed = eula_needed || tos_needed || pp_needed;
|
||||||
let (mut eula, mut tos, mut pp) = (!eula_needed, !tos_needed, !pp_needed);
|
let (mut eula, mut tos, mut pp) = (!eula_needed, !tos_needed, !pp_needed);
|
||||||
let mut focus = Focus::Eula;
|
let mut focus = Focus::Eula;
|
||||||
|
|
||||||
|
|
@ -247,7 +250,15 @@ pub async fn run_consent_ui(
|
||||||
.block(Block::default().title(format!(" Update Tensamin User Consent [Q to Quit] {}, {}, {}", pp_needed, eula_needed, tos_needed)).borders(Borders::ALL));
|
.block(Block::default().title(format!(" Update Tensamin User Consent [Q to Quit] {}, {}, {}", pp_needed, eula_needed, tos_needed)).borders(Borders::ALL));
|
||||||
f.render_widget(consent_block, chunks[0]);
|
f.render_widget(consent_block, chunks[0]);
|
||||||
|
|
||||||
draw_buttons(f, chunks[1], focus, (eula, tos, pp));
|
let downgrade_scenario = tos_needed || pp_needed;
|
||||||
|
draw_buttons(
|
||||||
|
f,
|
||||||
|
chunks[1],
|
||||||
|
focus,
|
||||||
|
(eula, tos && pp),
|
||||||
|
update_needed,
|
||||||
|
downgrade_scenario,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
@ -260,10 +271,17 @@ pub async fn run_consent_ui(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut possible_states = vec![Focus::Eula, Focus::Tos, Focus::Pp, Focus::Cancel];
|
||||||
|
if eula {
|
||||||
|
possible_states.push(Focus::Continue);
|
||||||
|
if tos && pp {
|
||||||
|
possible_states.push(Focus::ContinueAll);
|
||||||
|
}
|
||||||
|
}
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Esc => break UserChoice::Deny,
|
KeyCode::Esc => break UserChoice::Deny,
|
||||||
KeyCode::Up | KeyCode::Left => focus.prev((eula, tos, pp)),
|
KeyCode::Up | KeyCode::Left => focus.prev(&possible_states),
|
||||||
KeyCode::Down | KeyCode::Right | KeyCode::Tab => focus.next((eula, tos, pp)),
|
KeyCode::Down | KeyCode::Right | KeyCode::Tab => focus.next(&possible_states),
|
||||||
KeyCode::Char('q') | KeyCode::Char('Q') => break UserChoice::Deny,
|
KeyCode::Char('q') | KeyCode::Char('Q') => break UserChoice::Deny,
|
||||||
KeyCode::Char('o') | KeyCode::Char('O') => {
|
KeyCode::Char('o') | KeyCode::Char('O') => {
|
||||||
let terms_type = match focus {
|
let terms_type = match focus {
|
||||||
|
|
@ -298,8 +316,8 @@ pub async fn run_consent_ui(
|
||||||
KeyCode::Char(' ') => match focus {
|
KeyCode::Char(' ') => match focus {
|
||||||
Focus::Eula => {
|
Focus::Eula => {
|
||||||
eula = !eula;
|
eula = !eula;
|
||||||
tos = false;
|
tos = !tos_needed;
|
||||||
pp = false;
|
pp = !pp_needed;
|
||||||
}
|
}
|
||||||
Focus::Tos => {
|
Focus::Tos => {
|
||||||
if eula {
|
if eula {
|
||||||
|
|
@ -333,16 +351,16 @@ pub async fn run_consent_ui(
|
||||||
consent.accepted_eula = true;
|
consent.accepted_eula = true;
|
||||||
consent.accepted_tos = true;
|
consent.accepted_tos = true;
|
||||||
consent.accepted_pp = true;
|
consent.accepted_pp = true;
|
||||||
consent.eula = future_eula;
|
consent.future_eula = eula_for_future;
|
||||||
consent.tos = future_tos;
|
consent.future_tos = tos_for_future;
|
||||||
consent.privacy = future_privacy;
|
consent.future_privacy = pp_for_future;
|
||||||
}
|
}
|
||||||
UserChoice::AcceptEULA => {
|
UserChoice::AcceptEULA => {
|
||||||
consent.accepted_eula = true;
|
consent.accepted_eula = true;
|
||||||
consent.eula = future_eula;
|
consent.future_eula = eula_for_future;
|
||||||
}
|
}
|
||||||
UserChoice::Deny => {}
|
UserChoice::Deny => {}
|
||||||
};
|
}
|
||||||
|
|
||||||
consent
|
consent
|
||||||
}
|
}
|
||||||
|
|
@ -386,11 +404,23 @@ fn draw_buttons(
|
||||||
f: &mut ratatui::Frame,
|
f: &mut ratatui::Frame,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
current_focus: Focus,
|
current_focus: Focus,
|
||||||
state: (bool, bool, bool),
|
state: (bool, bool),
|
||||||
|
update_needed: bool,
|
||||||
|
downgrade_scenario: bool,
|
||||||
) {
|
) {
|
||||||
|
let cancel_text = if update_needed {
|
||||||
|
"[Q] Quit"
|
||||||
|
} else {
|
||||||
|
"[Q] Not now"
|
||||||
|
};
|
||||||
|
let continue_text = if downgrade_scenario {
|
||||||
|
"Downgrade"
|
||||||
|
} else {
|
||||||
|
"Continue"
|
||||||
|
};
|
||||||
let buttons = vec![
|
let buttons = vec![
|
||||||
("[Q] Cancel", Focus::Cancel),
|
(cancel_text, Focus::Cancel),
|
||||||
("Continue", Focus::Continue),
|
(continue_text, Focus::Continue),
|
||||||
("Continue with Tensamin Services", Focus::ContinueAll),
|
("Continue with Tensamin Services", Focus::ContinueAll),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -434,19 +464,19 @@ fn draw_buttons(
|
||||||
.bg(Color::Green)
|
.bg(Color::Green)
|
||||||
.add_modifier(Modifier::BOLD)
|
.add_modifier(Modifier::BOLD)
|
||||||
} else if state.0 {
|
} else if state.0 {
|
||||||
Style::default().fg(Color::Green) // enabled but not focused
|
Style::default().fg(Color::Green)
|
||||||
} else {
|
} else {
|
||||||
Style::default().fg(Color::DarkGray)
|
Style::default().fg(Color::DarkGray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Focus::ContinueAll => {
|
Focus::ContinueAll => {
|
||||||
if is_focused && state.0 && state.1 && state.2 {
|
if is_focused && state.1 {
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(Color::Black)
|
.fg(Color::Black)
|
||||||
.bg(Color::Green)
|
.bg(Color::Green)
|
||||||
.add_modifier(Modifier::BOLD)
|
.add_modifier(Modifier::BOLD)
|
||||||
} else if state.0 && state.1 && state.2 {
|
} else if state.1 {
|
||||||
Style::default().fg(Color::Green)
|
Style::default().fg(Color::Green)
|
||||||
} else {
|
} else {
|
||||||
Style::default().fg(Color::DarkGray)
|
Style::default().fg(Color::DarkGray)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue