mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-04 04:27:34 +00:00
224 lines
7.8 KiB
Rust
224 lines
7.8 KiB
Rust
mod account;
|
|
pub mod api;
|
|
mod manager;
|
|
|
|
use crate::account::Account;
|
|
use crate::manager::{Manager, TrustMode};
|
|
pub use api::*;
|
|
use chat::Chat;
|
|
use locales::t;
|
|
use modals::Modals;
|
|
use std::io::{Error, ErrorKind};
|
|
|
|
/// PDDB Dict for sigchat keys
|
|
const SIGCHAT_ACCOUNT: &str = "sigchat.account";
|
|
const SIGCHAT_DIALOGUE: &str = "sigchat.dialogue";
|
|
|
|
const WIFI_TIMEOUT: u32 = 10; // seconds
|
|
|
|
#[cfg(not(target_os = "xous"))]
|
|
pub const HOSTED_MODE: bool = true;
|
|
#[cfg(target_os = "xous")]
|
|
pub const HOSTED_MODE: bool = false;
|
|
|
|
//#[derive(Debug)]
|
|
pub struct SigChat<'a> {
|
|
chat: &'a Chat,
|
|
manager: Option<Manager>,
|
|
netmgr: net::NetManager,
|
|
modals: Modals,
|
|
}
|
|
impl<'a> SigChat<'a> {
|
|
pub fn new(chat: &Chat) -> SigChat {
|
|
let xns = xous_names::XousNames::new().unwrap();
|
|
let modals = Modals::new(&xns).expect("can't connect to Modals server");
|
|
let pddb = pddb::Pddb::new();
|
|
pddb.try_mount();
|
|
SigChat {
|
|
chat: chat,
|
|
manager: match Account::read(SIGCHAT_ACCOUNT) {
|
|
Ok(account) => Some(Manager::new(account, TrustMode::OnFirstUse)),
|
|
Err(_) => None,
|
|
},
|
|
netmgr: net::NetManager::new(),
|
|
modals: modals,
|
|
}
|
|
}
|
|
|
|
/// Connect to the Signal servers
|
|
///
|
|
pub fn connect(&mut self) -> bool {
|
|
log::info!("Attempting connect to Signal server");
|
|
if self.wifi() {
|
|
if self.manager.is_none() {
|
|
self.account_setup();
|
|
}
|
|
if let Some(_manager) = &self.manager {
|
|
log::info!("Signal manager OK" );
|
|
} else {
|
|
self.modals
|
|
.show_notification(t!("sigchat.account.failed", locales::LANG), None)
|
|
.expect("notification failed");
|
|
};
|
|
} else {
|
|
self.modals
|
|
.show_notification(t!("sigchat.wifi.warning", locales::LANG), None)
|
|
.expect("notification failed");
|
|
}
|
|
self.dialogue_set(None);
|
|
false
|
|
}
|
|
|
|
/// Setup a Signal Account via Registration or Linking
|
|
///
|
|
fn account_setup(&mut self) {
|
|
self.modals
|
|
.add_list_item(t!("sigchat.account.link", locales::LANG))
|
|
.expect("failed add list item");
|
|
self.modals
|
|
.add_list_item(t!("sigchat.account.register", locales::LANG))
|
|
.expect("failed add list item");
|
|
self.modals
|
|
.get_radiobutton(t!("sigchat.account.title", locales::LANG))
|
|
.expect("failed radiobutton modal");
|
|
match self.modals.get_radio_index() {
|
|
Ok(index) => match index {
|
|
0 => self.account_link(),
|
|
1 => self.account_register(),
|
|
_ => log::warn!("invalid index"),
|
|
},
|
|
Err(e) => log::warn!("failed to select register/link {:?}", e),
|
|
}
|
|
}
|
|
|
|
/// Link this device to an existing Signal Account
|
|
///
|
|
/// Signal allows to link additional devices to your primary device (e.g. Signal-Android).
|
|
/// Note that currently Signal allows up to three linked devices per primary.
|
|
///
|
|
pub fn account_link(&self) {
|
|
self.modals
|
|
.show_notification(&"sorry - linking is not implemented yet", None)
|
|
.expect("notification failed");
|
|
}
|
|
|
|
/// Register a new Signal Account with this as the primary device.
|
|
///
|
|
/// A Signal Account requires a phone number to receive SMS or incoming calls for registration & validation.
|
|
/// The phone number must include the country calling code, i.e. the number must start with a "+" sign.
|
|
/// Warning: this will disable the authentication of your phone as a primary device.
|
|
///
|
|
pub fn account_register(&mut self) {
|
|
self.modals
|
|
.show_notification(&"sorry - registration is not implemented yet", None)
|
|
.expect("notification failed");
|
|
match self.number_modal() {
|
|
Ok(number) => {
|
|
log::info!("registration phone number = {:?}", number);
|
|
match Account::new(SIGCHAT_ACCOUNT) {
|
|
Ok(mut account) => {
|
|
match account.set_number(&number.to_string()) {
|
|
Ok(_number) => {
|
|
self.manager = Some(Manager::new(account, TrustMode::OnFirstUse));
|
|
}
|
|
Err(e) => log::warn!("failed to set Account number: {e}"),
|
|
}
|
|
}
|
|
Err(e) => log::warn!("failed to create new Account: {e}"),
|
|
}
|
|
}
|
|
Err(e) => log::warn!("failed to get phone number: {e}"),
|
|
}
|
|
}
|
|
|
|
/// Attempts to obtain a phone number from the user.
|
|
///
|
|
/// A Signal Account requires a phone number to receive SMS or incoming calls for registration & validation.
|
|
/// The phone number must include the country calling code, i.e. the number must start with a "+" sign.
|
|
///
|
|
#[allow(dead_code)]
|
|
fn number_modal(&mut self) -> Result<String, Error> {
|
|
let mut builder = self
|
|
.modals
|
|
.alert_builder(t!("sigchat.number.title", locales::LANG));
|
|
let builder = builder.field(Some(t!("sigchat.number", locales::LANG).to_string()), None);
|
|
match builder.build() {
|
|
Ok(payloads) => match payloads.content()[0].content.as_str() {
|
|
Ok(number) => {
|
|
log::info!("registration phone number = {:?}", number);
|
|
Ok(number.to_string())
|
|
}
|
|
Err(e) => Err(Error::new(ErrorKind::InvalidData, e)),
|
|
},
|
|
Err(_) => Err(Error::from(ErrorKind::ConnectionRefused)),
|
|
}
|
|
}
|
|
|
|
pub fn redraw(&self) {
|
|
self.chat.redraw();
|
|
}
|
|
|
|
pub fn dialogue_set(&self, room_alias: Option<&str>) {
|
|
self.chat
|
|
.dialogue_set(SIGCHAT_DIALOGUE, room_alias)
|
|
.expect("failed to set dialogue");
|
|
}
|
|
|
|
pub fn help(&self) {
|
|
self.chat.help();
|
|
}
|
|
|
|
/// Returns true if wifi is connected
|
|
///
|
|
/// If wifi is not connected then a modal offers to "Connect to wifi?"
|
|
/// and tries for 10 seconds before representing.
|
|
///
|
|
pub fn wifi(&self) -> bool {
|
|
if HOSTED_MODE {
|
|
return true;
|
|
}
|
|
|
|
if let Some(conf) = self.netmgr.get_ipv4_config() {
|
|
if conf.dhcp == com_rs::DhcpState::Bound {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
while self.wifi_try_modal() {
|
|
self.netmgr.connection_manager_wifi_on_and_run().unwrap();
|
|
self.modals
|
|
.start_progress("Connecting ...", 0, 10, 0)
|
|
.expect("no progress bar");
|
|
let tt = ticktimer_server::Ticktimer::new().unwrap();
|
|
for wait in 0..WIFI_TIMEOUT {
|
|
tt.sleep_ms(1000).unwrap();
|
|
self.modals
|
|
.update_progress(wait)
|
|
.expect("no progress update");
|
|
if let Some(conf) = self.netmgr.get_ipv4_config() {
|
|
if conf.dhcp == com_rs::DhcpState::Bound {
|
|
self.modals
|
|
.finish_progress()
|
|
.expect("failed progress finish");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
/// Returns true if "Connect to WiFi?" yes option is chosen
|
|
///
|
|
fn wifi_try_modal(&self) -> bool {
|
|
self.modals.add_list_item("yes").expect("failed radio yes");
|
|
self.modals.add_list_item("no").expect("failed radio no");
|
|
self.modals
|
|
.get_radiobutton("Connect to WiFi?")
|
|
.expect("failed radiobutton modal");
|
|
match self.modals.get_radio_index() {
|
|
Ok(button) => button == 0,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|