[WIP] Terms update support
This commit is contained in:
parent
43af786d16
commit
b81276dd18
6 changed files with 251 additions and 91 deletions
|
|
@ -3,41 +3,71 @@ use crate::{
|
|||
doc::Doc,
|
||||
terms_checker,
|
||||
terms_getter::{Type, get_current_docs, get_newest_docs},
|
||||
terms_updater,
|
||||
},
|
||||
util::file_util::load_file,
|
||||
util::file_util::{load_file, save_file},
|
||||
};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tokio::task;
|
||||
|
||||
pub struct ConsentManager;
|
||||
impl ConsentManager {
|
||||
pub async fn check() -> (bool, bool) {
|
||||
let file = load_file("", "agreements");
|
||||
let file_state = ConsentState::from_str(&file).sanitize();
|
||||
let accepted_state = if !&file_state.accepted_eula {
|
||||
terms_checker::run_consent_ui(file_state).await
|
||||
} else {
|
||||
file_state
|
||||
};
|
||||
let mut file_state = ConsentState::from_str(&file).sanitize();
|
||||
|
||||
if let Some((current_eula, current_tos, current_privacy)) = get_current_docs().await {
|
||||
if current_eula.equals_some(&accepted_state.eula) {
|
||||
if current_tos.equals_some(&accepted_state.tos)
|
||||
&& current_privacy.equals_some(&accepted_state.pp)
|
||||
{
|
||||
(true, true)
|
||||
} else {
|
||||
(true, false)
|
||||
}
|
||||
} else {
|
||||
(false, false)
|
||||
}
|
||||
} else {
|
||||
println!("There was an error while loading our EULA, please retry later!");
|
||||
(false, false)
|
||||
if !file_state.accepted_eula {
|
||||
file_state = terms_checker::run_consent_ui(file_state).await;
|
||||
|
||||
println!("{}", &file_state.clone().sanitize().to_string());
|
||||
println!("-----------------------");
|
||||
|
||||
save_file("", "agreements", &file_state.to_string());
|
||||
}
|
||||
|
||||
if !file_state.accepted_eula {
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
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 updater_logic = async move {
|
||||
let state_to_update = terms_updater::run_consent_ui(
|
||||
file_state,
|
||||
eula_update,
|
||||
tos_update,
|
||||
privacy_update,
|
||||
)
|
||||
.await;
|
||||
|
||||
println!("{}", &state_to_update.clone().sanitize().to_string());
|
||||
|
||||
save_file("", "agreements", &state_to_update.sanitize().to_string());
|
||||
};
|
||||
|
||||
if is_forced {
|
||||
updater_logic.await;
|
||||
} else {
|
||||
task::spawn(updater_logic);
|
||||
}
|
||||
}
|
||||
|
||||
let final_state = ConsentState::from_str(&load_file("", "agreements")).sanitize();
|
||||
(
|
||||
final_state.accepted_eula,
|
||||
final_state.accepted_tos && final_state.accepted_pp,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn check_updates() -> Option<(Option<Doc>, Option<Doc>, Option<Doc>)> {
|
||||
async fn get_updates() -> Option<(
|
||||
// Ok(None) indicates no update
|
||||
// Ok(Some) Indicates a future update
|
||||
// Err indicates a update that has to be accepted before the programm can continue
|
||||
Result<Option<Doc>, Doc>,
|
||||
Result<Option<Doc>, Doc>,
|
||||
Result<Option<Doc>, Doc>,
|
||||
)> {
|
||||
let file = load_file("", "agreements");
|
||||
let accepted_state = ConsentState::from_str(&file).sanitize();
|
||||
|
||||
|
|
@ -46,7 +76,48 @@ impl ConsentManager {
|
|||
Some((newest_eula, newest_tos, newest_privacy)),
|
||||
) = (get_current_docs().await, get_newest_docs().await)
|
||||
{
|
||||
None
|
||||
let eula_update: Result<Option<Doc>, Doc> =
|
||||
if current_eula.equals_some(&accepted_state.eula) {
|
||||
if current_eula.equals(&newest_eula) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(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 {
|
||||
Err(current_tos)
|
||||
};
|
||||
|
||||
let privacy_update: Result<Option<Doc>, Doc> =
|
||||
if newest_privacy.equals_some(&accepted_state.privacy) {
|
||||
Ok(None)
|
||||
} else if accepted_state.accepted_pp
|
||||
&& current_privacy.equals_some(&accepted_state.privacy)
|
||||
{
|
||||
if current_privacy.equals(&newest_privacy) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(newest_privacy))
|
||||
}
|
||||
} else {
|
||||
Err(current_privacy)
|
||||
};
|
||||
Some((eula_update, tos_update, privacy_update))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -66,7 +137,7 @@ pub struct ConsentState {
|
|||
pub accepted_eula: bool,
|
||||
pub tos: Option<Doc>,
|
||||
pub accepted_tos: bool,
|
||||
pub pp: Option<Doc>,
|
||||
pub privacy: Option<Doc>,
|
||||
pub accepted_pp: bool,
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +150,7 @@ impl ConsentState {
|
|||
self
|
||||
}
|
||||
|
||||
async fn to_string(self) -> String {
|
||||
pub fn to_string(&self) -> String {
|
||||
let current_secs = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
|
|
@ -93,9 +164,13 @@ impl ConsentState {
|
|||
current_secs
|
||||
);
|
||||
|
||||
if self.accepted_eula
|
||||
&& 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!("\
|
||||
\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={}\
|
||||
|
|
@ -104,17 +179,17 @@ impl ConsentState {
|
|||
", self.accepted_eula, eula.get_version(), eula.get_hash()));
|
||||
|
||||
if self.accepted_tos
|
||||
&& let Some(tos) = self.tos
|
||||
&& let Some(tos) = &self.tos
|
||||
{
|
||||
file_out.push_str(&format!("\
|
||||
\n\"ToS=true\" indicates that you read, understood and accepted Tensamin's Terms of Service. You can find our Terms of Serivce at https://legal.tensamin.net/tos/\
|
||||
\nToS={}\
|
||||
\nToS-VERSION={}\
|
||||
\nToS-HASH={}\
|
||||
\n\"Terms-of-Service=true\" indicates that you read, understood and accepted Tensamin's Terms of Service. You can find our Terms of Serivce at https://legal.tensamin.net/tos/\
|
||||
\nTerms-of-Service={}\
|
||||
\nTerms-of-Service-VERSION={}\
|
||||
\nTerms-of-Service-HASH={}\
|
||||
", self.accepted_tos, tos.get_version(), tos.get_hash()));
|
||||
}
|
||||
if self.accepted_pp
|
||||
&& let Some(pp) = self.pp
|
||||
&& let Some(pp) = &self.privacy
|
||||
{
|
||||
file_out.push_str(&format!("\
|
||||
\n\"Privacy-Policy=true\" indicates that you read, understood and accepted Tensamin's Privacy Policy. You can find our Privacy Policy at https://legal.tensamin.net/privacy/\
|
||||
|
|
@ -152,17 +227,17 @@ impl ConsentState {
|
|||
eula_version = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("EULA-HASH=") {
|
||||
eula_hash = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("ToS=") {
|
||||
} else if let Some(v) = line.strip_prefix("Terms-of-Service=") {
|
||||
tos = v == "true";
|
||||
} else if let Some(v) = line.strip_prefix("ToS-VERSION=") {
|
||||
} else if let Some(v) = line.strip_prefix("Terms-of-Service-VERSION=") {
|
||||
tos_version = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("ToS-HASH=") {
|
||||
} else if let Some(v) = line.strip_prefix("Terms-of-Service-HASH=") {
|
||||
tos_hash = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("PrivacyPolicy=") {
|
||||
} else if let Some(v) = line.strip_prefix("Privacy-Policy=") {
|
||||
pp = v == "true";
|
||||
} else if let Some(v) = line.strip_prefix("PrivacyPolicy-VERSION=") {
|
||||
} else if let Some(v) = line.strip_prefix("Privacy-Policy-VERSION=") {
|
||||
pp_version = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("PrivacyPolicy-HASH=") {
|
||||
} else if let Some(v) = line.strip_prefix("Privacy-Policy-HASH=") {
|
||||
pp_hash = v.to_string();
|
||||
} else if let Some(v) = line.strip_prefix("UNIX=") {
|
||||
unix = v.to_string();
|
||||
|
|
@ -173,7 +248,7 @@ impl ConsentState {
|
|||
accepted_eula: eula,
|
||||
eula: Some(Doc::new(eula_version, eula_hash, Type::EULA, unix)),
|
||||
accepted_pp: pp,
|
||||
pp: Some(Doc::new(pp_version, pp_hash, Type::PP, unix)),
|
||||
privacy: Some(Doc::new(pp_version, pp_hash, Type::PP, unix)),
|
||||
accepted_tos: tos,
|
||||
tos: Some(Doc::new(tos_version, tos_hash, Type::TOS, unix)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use json::{JsonValue, object::Object};
|
|||
|
||||
use crate::{terms::terms_getter::Type, util::file_util::load_file};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[allow(unused)]
|
||||
pub struct Doc {
|
||||
version: String,
|
||||
hash: String,
|
||||
doc_type: Type,
|
||||
pub doc_type: Type,
|
||||
timestamp: u64,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Focus {
|
||||
Eula,
|
||||
Tos,
|
||||
|
|
@ -7,6 +7,7 @@ pub enum Focus {
|
|||
Continue,
|
||||
ContinueAll,
|
||||
}
|
||||
|
||||
impl Focus {
|
||||
pub fn next(&mut self, state: (bool, bool, bool)) {
|
||||
*self = match self {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::terms::{
|
|||
consent_state::{ConsentState, UserChoice},
|
||||
focus::Focus,
|
||||
md_viewer::FileViewer,
|
||||
terms_getter::{Type, get_link, get_terms},
|
||||
terms_getter::{Type, get_current_docs, get_link, get_terms},
|
||||
};
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use ratatui::{
|
||||
|
|
@ -52,19 +52,19 @@ pub async fn run_consent_ui(mut consent: ConsentState) -> ConsentState {
|
|||
height: content_height,
|
||||
});
|
||||
let eula_text = if size.width < 70 {
|
||||
"EULA ¹ (https://legal.tensamin.net/eula/)"
|
||||
"EULA ¹ (https://legal.tensamin.net/eula/newest/)"
|
||||
} else {
|
||||
"End User Licence Agreement ¹ (https://legal.tensamin.net/eula/)"
|
||||
"End User Licence Agreement ¹ (https://legal.tensamin.net/eula/newest/)"
|
||||
};
|
||||
let tos_text = if size.width < 72 {
|
||||
"ToS ² (https://legal.tensamin.net/terms-of-service/)"
|
||||
"ToS ² (https://legal.tensamin.net/terms-of-service/newest/)"
|
||||
} else {
|
||||
"Terms of Service ² (https://legal.tensamin.net/terms-of-service/)"
|
||||
"Terms of Service ² (https://legal.tensamin.net/terms-of-service/newest/)"
|
||||
};
|
||||
let pp_text = if size.width < 68 {
|
||||
"PP ² (https://legal.tensamin.net/privacy-policy/)"
|
||||
"PP ² (https://legal.tensamin.net/privacy-policy/newest/)"
|
||||
} else {
|
||||
"Privacy Policy ² (https://legal.tensamin.net/privacy-policy/)"
|
||||
"Privacy Policy ² (https://legal.tensamin.net/privacy-policy/newest/)"
|
||||
};
|
||||
|
||||
let (mut optional_lines, agree_lines): (Vec<i16>, Vec<&str>) =
|
||||
|
|
@ -275,6 +275,12 @@ pub async fn run_consent_ui(mut consent: ConsentState) -> ConsentState {
|
|||
};
|
||||
ratatui::restore();
|
||||
|
||||
if let Some((eula, tos, privacy)) = get_current_docs().await {
|
||||
consent.eula = Some(eula);
|
||||
consent.tos = Some(tos);
|
||||
consent.privacy = Some(privacy);
|
||||
}
|
||||
|
||||
match result {
|
||||
UserChoice::AcceptAll => {
|
||||
consent.accepted_eula = true;
|
||||
|
|
@ -292,6 +298,7 @@ pub async fn run_consent_ui(mut consent: ConsentState) -> ConsentState {
|
|||
consent.accepted_pp = false;
|
||||
}
|
||||
};
|
||||
|
||||
consent
|
||||
}
|
||||
|
||||
|
|
|
|||
3
src/terms/terms_getter.rs
Normal file → Executable file
3
src/terms/terms_getter.rs
Normal file → Executable file
|
|
@ -2,7 +2,7 @@ use json::JsonValue::Object;
|
|||
|
||||
use crate::terms::doc::Doc;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Type {
|
||||
EULA,
|
||||
TOS,
|
||||
|
|
@ -87,7 +87,6 @@ pub async fn get_newest_docs() -> Option<(Doc, Doc, Doc)> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_terms(terms_type: Type) -> Option<String> {
|
||||
let body = reqwest::get(format!(
|
||||
"https://legal.tensamin.net/api/text/{}/",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::terms::{
|
||||
consent_state::UserChoice,
|
||||
consent_state::{ConsentState, UserChoice},
|
||||
doc::Doc,
|
||||
focus::Focus,
|
||||
md_viewer::FileViewer,
|
||||
terms_getter::{Type, get_link, get_terms},
|
||||
|
|
@ -13,10 +14,29 @@ use ratatui::{
|
|||
};
|
||||
use std::time::Duration;
|
||||
|
||||
pub async fn run_consent_ui() -> UserChoice {
|
||||
pub async fn run_consent_ui(
|
||||
mut consent: ConsentState,
|
||||
consent_eula: Result<Option<Doc>, Doc>,
|
||||
consent_tos: Result<Option<Doc>, Doc>,
|
||||
consent_pp: Result<Option<Doc>, Doc>,
|
||||
) -> ConsentState {
|
||||
let mut terminal = ratatui::init();
|
||||
|
||||
let (mut eula, mut tos, mut pp) = (false, false, false);
|
||||
let (eula_needed, eula_future, future_eula) = match consent_eula {
|
||||
Ok(Some(future)) => (true, true, Some(future)),
|
||||
Ok(None) => (false, false, None),
|
||||
Err(future) => (true, false, Some(future)),
|
||||
};
|
||||
let (tos_needed, tos_future, future_tos) = match consent_tos {
|
||||
Ok(Some(future)) => (true, true, Some(future)),
|
||||
Ok(None) => (false, false, None),
|
||||
Err(future) => (true, false, Some(future)),
|
||||
};
|
||||
let (pp_needed, pp_future, future_privacy) = match consent_pp {
|
||||
Ok(Some(future)) => (true, true, Some(future)),
|
||||
Ok(None) => (false, false, None),
|
||||
Err(future) => (true, false, Some(future)),
|
||||
};
|
||||
let (mut eula, mut tos, mut pp) = (!eula_needed, !tos_needed, !pp_needed);
|
||||
let mut focus = Focus::Eula;
|
||||
|
||||
let result = loop {
|
||||
|
|
@ -51,28 +71,68 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
width: content_width,
|
||||
height: content_height,
|
||||
});
|
||||
let eula_text = if size.width < 70 {
|
||||
"EULA ¹ (https://legal.tensamin.net/eula/)"
|
||||
} else {
|
||||
"End User Licence Agreement ¹ (https://legal.tensamin.net/eula/)"
|
||||
};
|
||||
let tos_text = if size.width < 72 {
|
||||
"ToS ² (https://legal.tensamin.net/terms-of-service/)"
|
||||
} else {
|
||||
"Terms of Service ² (https://legal.tensamin.net/terms-of-service/)"
|
||||
};
|
||||
let pp_text = if size.width < 68 {
|
||||
"PP ² (https://legal.tensamin.net/privacy-policy/)"
|
||||
} else {
|
||||
"Privacy Policy ² (https://legal.tensamin.net/privacy-policy/)"
|
||||
};
|
||||
|
||||
|
||||
let mut text_lines = Vec::new();
|
||||
|
||||
|
||||
if eula_needed {
|
||||
if eula_future {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("EULA ¹³ (https://legal.tensamin.net/eula/newest/)", eula, focus == Focus::Eula, true));
|
||||
} else {
|
||||
text_lines.push(checkbox("End User Licence Agreement ¹³ (https://legal.tensamin.net/eula/newest/)", eula, focus == Focus::Eula, true));
|
||||
}
|
||||
} else {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("EULA ¹ (https://legal.tensamin.net/eula/newest/)", eula, focus == Focus::Eula, true));
|
||||
} else {
|
||||
text_lines.push(checkbox("End User Licence Agreement ¹ (https://legal.tensamin.net/eula/newest/)", eula, focus == Focus::Eula, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if tos_needed {
|
||||
if tos_future {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("ToS ²³ (https://legal.tensamin.net/terms-of-service/newest/)", tos, focus == Focus::Tos, eula));
|
||||
} else {
|
||||
text_lines.push(checkbox("Terms of Service ²³ (https://legal.tensamin.net/terms-of-service/newest/)", tos, focus == Focus::Tos, eula));
|
||||
}
|
||||
} else {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("ToS ² (https://legal.tensamin.net/terms-of-service/newest/)", tos, focus == Focus::Tos, eula));
|
||||
} else {
|
||||
text_lines.push(checkbox("Terms of Service ² (https://legal.tensamin.net/terms-of-service/newest/)", tos, focus == Focus::Tos, eula));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pp_needed {
|
||||
if pp_future {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("PP ²³ (https://legal.tensamin.net/privacy-policy/newest/)", pp, focus == Focus::Pp, eula));
|
||||
} else {
|
||||
text_lines.push(checkbox("Privacy Policy ²³ (https://legal.tensamin.net/privacy-policy/newest/)", pp, focus == Focus::Pp, eula));
|
||||
}
|
||||
} else {
|
||||
if size.width < 70 {
|
||||
text_lines.push(checkbox("PP ² (https://legal.tensamin.net/privacy-policy/newest/)", pp, focus == Focus::Pp, pp));
|
||||
} else {
|
||||
text_lines.push(checkbox("Privacy Policy ² (https://legal.tensamin.net/privacy-policy/newest/)", pp, focus == Focus::Pp, eula));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text_lines.push(Line::from(""));
|
||||
text_lines.push(Line::from("¹ Necessary, ² Optional, ³ Future"));
|
||||
text_lines.push(Line::from(""));
|
||||
|
||||
let (mut optional_lines, agree_lines): (Vec<i16>, Vec<&str>) =
|
||||
if size.width > 143 {
|
||||
(
|
||||
vec![7, 3, 7, 4],
|
||||
vec![
|
||||
"",
|
||||
"By selecting Continue, you confirm that you have read, understood and agree to the End User License Agreement and applicable Terms of Service.",
|
||||
"",
|
||||
"Tensamin services require acceptance of the Terms of Service and Privacy Policy.",
|
||||
|
|
@ -97,7 +157,6 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
(
|
||||
vec![8, 3, 8, 4],
|
||||
vec![
|
||||
"",
|
||||
"By selecting Continue, you confirm that you have read, understood and",
|
||||
"agree to the End User License Agreement and applicable Terms of Service.",
|
||||
"",
|
||||
|
|
@ -111,7 +170,6 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
(
|
||||
vec![9, 3, 10, 4],
|
||||
vec![
|
||||
"",
|
||||
"By selecting Continue, you confirm that you have",
|
||||
"read, understood and agree to the End User License",
|
||||
"Agreement and applicable Terms of Service.",
|
||||
|
|
@ -124,13 +182,8 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
]
|
||||
)
|
||||
};
|
||||
let mut text_lines = vec![
|
||||
checkbox(eula_text, eula, focus == Focus::Eula, true),
|
||||
checkbox(tos_text, tos, focus == Focus::Tos, eula),
|
||||
checkbox(pp_text, pp, focus == Focus::Pp, eula),
|
||||
Line::from(""),
|
||||
Line::from("¹ Necessary, ² Optional"),
|
||||
];
|
||||
|
||||
|
||||
|
||||
for line in agree_lines {
|
||||
text_lines.insert(text_lines.len(), Line::from(line));
|
||||
|
|
@ -191,10 +244,10 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
}
|
||||
|
||||
let consent_block = Paragraph::new(Text::from(text_lines))
|
||||
.block(Block::default().title(" Tensamin User Consent [Q to Quit] ").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]);
|
||||
|
||||
draw_buttons(f, chunks[1], (eula, tos, pp));
|
||||
draw_buttons(f, chunks[1], focus, (eula, tos, pp));
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -275,7 +328,23 @@ pub async fn run_consent_ui() -> UserChoice {
|
|||
};
|
||||
ratatui::restore();
|
||||
|
||||
result
|
||||
match result {
|
||||
UserChoice::AcceptAll => {
|
||||
consent.accepted_eula = true;
|
||||
consent.accepted_tos = true;
|
||||
consent.accepted_pp = true;
|
||||
consent.eula = future_eula;
|
||||
consent.tos = future_tos;
|
||||
consent.privacy = future_privacy;
|
||||
}
|
||||
UserChoice::AcceptEULA => {
|
||||
consent.accepted_eula = true;
|
||||
consent.eula = future_eula;
|
||||
}
|
||||
UserChoice::Deny => {}
|
||||
};
|
||||
|
||||
consent
|
||||
}
|
||||
|
||||
#[allow(mismatched_lifetime_syntaxes)]
|
||||
|
|
@ -313,7 +382,12 @@ fn draw_button(f: &mut ratatui::Frame, area: Rect, label: &str, style: Style) {
|
|||
.block(Block::default().borders(Borders::ALL));
|
||||
f.render_widget(p, area);
|
||||
}
|
||||
fn draw_buttons(f: &mut ratatui::Frame, area: Rect, state: (bool, bool, bool)) {
|
||||
fn draw_buttons(
|
||||
f: &mut ratatui::Frame,
|
||||
area: Rect,
|
||||
current_focus: Focus,
|
||||
state: (bool, bool, bool),
|
||||
) {
|
||||
let buttons = vec![
|
||||
("[Q] Cancel", Focus::Cancel),
|
||||
("Continue", Focus::Continue),
|
||||
|
|
@ -339,9 +413,11 @@ fn draw_buttons(f: &mut ratatui::Frame, area: Rect, state: (bool, bool, bool)) {
|
|||
};
|
||||
x += width;
|
||||
|
||||
let is_focused = current_focus == *focus;
|
||||
|
||||
let style = match focus {
|
||||
Focus::Cancel => {
|
||||
if focus == &Focus::Cancel {
|
||||
if is_focused {
|
||||
Style::default()
|
||||
.fg(Color::Black)
|
||||
.bg(Color::Red)
|
||||
|
|
@ -350,20 +426,22 @@ fn draw_buttons(f: &mut ratatui::Frame, area: Rect, state: (bool, bool, bool)) {
|
|||
Style::default().fg(Color::Red)
|
||||
}
|
||||
}
|
||||
|
||||
Focus::Continue => {
|
||||
if focus == &Focus::Continue && state.0 {
|
||||
if is_focused && state.0 {
|
||||
Style::default()
|
||||
.fg(Color::Black)
|
||||
.bg(Color::Green)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else if state.0 && state.1 && state.2 {
|
||||
Style::default().fg(Color::Green)
|
||||
} else if state.0 {
|
||||
Style::default().fg(Color::Green) // enabled but not focused
|
||||
} else {
|
||||
Style::default().fg(Color::DarkGray)
|
||||
}
|
||||
}
|
||||
|
||||
Focus::ContinueAll => {
|
||||
if focus == &Focus::ContinueAll && state.0 && state.1 && state.2 {
|
||||
if is_focused && state.0 && state.1 && state.2 {
|
||||
Style::default()
|
||||
.fg(Color::Black)
|
||||
.bg(Color::Green)
|
||||
|
|
@ -374,13 +452,13 @@ fn draw_buttons(f: &mut ratatui::Frame, area: Rect, state: (bool, bool, bool)) {
|
|||
Style::default().fg(Color::DarkGray)
|
||||
}
|
||||
}
|
||||
|
||||
_ => Style::default().fg(Color::DarkGray),
|
||||
};
|
||||
|
||||
draw_button(f, chunk, label, style);
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_widths(area_width: u16, min_widths: &[u16]) -> Vec<u16> {
|
||||
let mut widths = vec![0; min_widths.len()];
|
||||
let mut remaining: Vec<usize> = (0..min_widths.len()).collect();
|
||||
|
|
|
|||
Loading…
Reference in a new issue