forked from Lonami/Talaria
Use UDL interface to avoid passing around pointers
This commit is contained in:
parent
912949a079
commit
43421f6e54
|
@ -19,8 +19,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import dev.lonami.talaria.R
|
import dev.lonami.talaria.R
|
||||||
import dev.lonami.talaria.ui.theme.TalariaTheme
|
import dev.lonami.talaria.ui.theme.TalariaTheme
|
||||||
import uniffi.talaria.requestLoginCode
|
import uniffi.talaria.LoginProcedure
|
||||||
import uniffi.talaria.signIn
|
|
||||||
|
|
||||||
enum class LoginStage {
|
enum class LoginStage {
|
||||||
ASK_PHONE,
|
ASK_PHONE,
|
||||||
|
@ -106,7 +105,7 @@ fun LoginScreen(onConfirmOtp: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
var phone by remember { mutableStateOf("") }
|
var phone by remember { mutableStateOf("") }
|
||||||
var otp by remember { mutableStateOf("") }
|
var otp by remember { mutableStateOf("") }
|
||||||
|
|
||||||
var tokenPtr by remember { mutableStateOf(0UL) }
|
val loginProcedure by remember { mutableStateOf(LoginProcedure()) }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
@ -128,7 +127,7 @@ fun LoginScreen(onConfirmOtp: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
phone,
|
phone,
|
||||||
onPhoneChanged = { phone = it },
|
onPhoneChanged = { phone = it },
|
||||||
onSendCode = {
|
onSendCode = {
|
||||||
tokenPtr = requestLoginCode(phone)
|
loginProcedure.requestLoginCode(phone)
|
||||||
stage = LoginStage.ASK_CODE
|
stage = LoginStage.ASK_CODE
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -136,7 +135,7 @@ fun LoginScreen(onConfirmOtp: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
otp,
|
otp,
|
||||||
onOtpChanged = { otp = it },
|
onOtpChanged = { otp = it },
|
||||||
onConfirmOtp = {
|
onConfirmOtp = {
|
||||||
signIn(tokenPtr, otp)
|
loginProcedure.signIn(otp)
|
||||||
onConfirmOtp()
|
onConfirmOtp()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -64,6 +64,10 @@ impl fmt::Display for NativeError {
|
||||||
|
|
||||||
impl std::error::Error for NativeError {}
|
impl std::error::Error for NativeError {}
|
||||||
|
|
||||||
|
struct LoginProcedure {
|
||||||
|
token: Mutex<Option<LoginToken>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum MessageAck {
|
pub enum MessageAck {
|
||||||
Received,
|
Received,
|
||||||
|
@ -199,61 +203,75 @@ pub fn need_login() -> Result<bool> {
|
||||||
block_on(client.is_authorized()).map_err(|_| NativeError::Network)
|
block_on(client.is_authorized()).map_err(|_| NativeError::Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_login_code(phone: String) -> Result<u64> {
|
impl LoginProcedure {
|
||||||
let client = CLIENT.get().ok_or(NativeError::Initialization)?;
|
fn new() -> Self {
|
||||||
block_on(client.request_login_code(&phone, API_ID, API_HASH))
|
Self {
|
||||||
.map(|token| Box::into_raw(Box::new(token)) as u64)
|
token: Mutex::new(None),
|
||||||
.map_err(|_| NativeError::Network)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sign_in(token_ptr: u64, code: String) -> Result<()> {
|
|
||||||
let token = unsafe { *Box::from_raw(token_ptr as *mut LoginToken) };
|
|
||||||
let client = CLIENT.get().ok_or(NativeError::Initialization)?;
|
|
||||||
|
|
||||||
block_on(client.sign_in(&token, &code)).map_err(|_| NativeError::Network)?;
|
|
||||||
|
|
||||||
let guard = DATABASE.lock().unwrap();
|
|
||||||
let conn = match guard.as_ref() {
|
|
||||||
Some(c) => c,
|
|
||||||
None => {
|
|
||||||
error!("Database was not initialized");
|
|
||||||
return Err(NativeError::Initialization);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let mut session = db::create_session(conn).map_err(|_| NativeError::Database)?;
|
|
||||||
let s = client.session();
|
|
||||||
if let Some(user) = s.get_user() {
|
|
||||||
session.user_id = Some(user.id);
|
|
||||||
session.dc_id = Some(user.dc);
|
|
||||||
session.bot = Some(user.bot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(state) = s.get_state() {
|
fn request_login_code(&self, phone: String) -> Result<()> {
|
||||||
session.pts = Some(state.pts);
|
let client = CLIENT.get().ok_or(NativeError::Initialization)?;
|
||||||
session.qts = Some(state.qts);
|
let token = block_on(client.request_login_code(&phone, API_ID, API_HASH))
|
||||||
session.seq = Some(state.seq);
|
.map_err(|_| NativeError::Network)?;
|
||||||
session.date = Some(state.date);
|
*self.token.lock().unwrap() = Some(token);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dc_id) = session.dc_id {
|
fn sign_in(&self, code: String) -> Result<()> {
|
||||||
for dc in s.get_dcs() {
|
let token = self
|
||||||
if dc.id == dc_id {
|
.token
|
||||||
if let Some(ipv4) = dc.ipv4 {
|
.lock()
|
||||||
session.dc_addr = Some(Ipv4Addr::from(ipv4.to_le_bytes()).to_string())
|
.unwrap()
|
||||||
} else if let Some(ipv6) = dc.ipv6 {
|
.take()
|
||||||
session.dc_addr = Some(Ipv6Addr::from(ipv6).to_string())
|
.ok_or(NativeError::Initialization)?;
|
||||||
|
let client = CLIENT.get().ok_or(NativeError::Initialization)?;
|
||||||
|
|
||||||
|
block_on(client.sign_in(&token, &code)).map_err(|_| NativeError::Network)?;
|
||||||
|
|
||||||
|
let guard = DATABASE.lock().unwrap();
|
||||||
|
let conn = match guard.as_ref() {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
error!("Database was not initialized");
|
||||||
|
return Err(NativeError::Initialization);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut session = db::create_session(conn).map_err(|_| NativeError::Database)?;
|
||||||
|
let s = client.session();
|
||||||
|
if let Some(user) = s.get_user() {
|
||||||
|
session.user_id = Some(user.id);
|
||||||
|
session.dc_id = Some(user.dc);
|
||||||
|
session.bot = Some(user.bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(state) = s.get_state() {
|
||||||
|
session.pts = Some(state.pts);
|
||||||
|
session.qts = Some(state.qts);
|
||||||
|
session.seq = Some(state.seq);
|
||||||
|
session.date = Some(state.date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(dc_id) = session.dc_id {
|
||||||
|
for dc in s.get_dcs() {
|
||||||
|
if dc.id == dc_id {
|
||||||
|
if let Some(ipv4) = dc.ipv4 {
|
||||||
|
session.dc_addr = Some(Ipv4Addr::from(ipv4.to_le_bytes()).to_string())
|
||||||
|
} else if let Some(ipv6) = dc.ipv6 {
|
||||||
|
session.dc_addr = Some(Ipv6Addr::from(ipv6).to_string())
|
||||||
|
}
|
||||||
|
session.dc_port = Some(dc.port as u16);
|
||||||
|
session.dc_auth = dc.auth.map(|b| b.try_into().unwrap());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
session.dc_port = Some(dc.port as u16);
|
|
||||||
session.dc_auth = dc.auth.map(|b| b.try_into().unwrap());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db::update_session(conn, &session).map_err(|_| NativeError::Database)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
db::update_session(conn, &session).map_err(|_| NativeError::Database)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dialogs() -> Result<Vec<Dialog>> {
|
pub fn get_dialogs() -> Result<Vec<Dialog>> {
|
||||||
|
|
|
@ -25,6 +25,14 @@ dictionary Dialog {
|
||||||
boolean pinned;
|
boolean pinned;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface LoginProcedure {
|
||||||
|
constructor();
|
||||||
|
[Throws=NativeError]
|
||||||
|
void request_login_code(string phone);
|
||||||
|
[Throws=NativeError]
|
||||||
|
void sign_in(string code);
|
||||||
|
};
|
||||||
|
|
||||||
namespace talaria {
|
namespace talaria {
|
||||||
[Throws=NativeError]
|
[Throws=NativeError]
|
||||||
void init_database(string path);
|
void init_database(string path);
|
||||||
|
@ -33,10 +41,6 @@ namespace talaria {
|
||||||
[Throws=NativeError]
|
[Throws=NativeError]
|
||||||
boolean need_login();
|
boolean need_login();
|
||||||
[Throws=NativeError]
|
[Throws=NativeError]
|
||||||
u64 request_login_code(string phone);
|
|
||||||
[Throws=NativeError]
|
|
||||||
void sign_in(u64 tokenPtr, string code);
|
|
||||||
[Throws=NativeError]
|
|
||||||
sequence<Dialog> get_dialogs();
|
sequence<Dialog> get_dialogs();
|
||||||
[Throws=NativeError]
|
[Throws=NativeError]
|
||||||
void send_message(string packed, string text);
|
void send_message(string packed, string text);
|
||||||
|
|
Loading…
Reference in New Issue