Preserve typing events in iOS FFI
This commit is contained in:
@@ -173,6 +173,7 @@ public enum SessionEvent: Equatable, Sendable {
|
||||
case reactionChanged(Int64, Int64, [Reaction])
|
||||
case incomingNotificationCandidate(ChatSummary, Message, String)
|
||||
case networkChanged(NetworkState)
|
||||
case typingChanged(TypingState)
|
||||
case draftChanged(Draft)
|
||||
case profileLoaded(Profile)
|
||||
case mediaDownloadProgress(fileId: Int32, downloadedSize: Int64, totalSize: Int64)
|
||||
@@ -185,3 +186,8 @@ public enum NetworkState: Equatable, Sendable {
|
||||
case updating
|
||||
case ready
|
||||
}
|
||||
|
||||
public enum TypingState: Equatable, Sendable {
|
||||
case idle
|
||||
case typing(chatId: Int64, userId: Int64, text: String)
|
||||
}
|
||||
|
||||
@@ -155,6 +155,15 @@ public actor UniFfiSessionBridge: SessionBridge {
|
||||
}
|
||||
}
|
||||
|
||||
private static func mapTypingState(_ state: IosTypingState) -> TypingState {
|
||||
switch state {
|
||||
case .idle:
|
||||
.idle
|
||||
case let .typing(chatId, userId, text):
|
||||
.typing(chatId: chatId, userId: userId, text: text)
|
||||
}
|
||||
}
|
||||
|
||||
private static func mapFolder(_ folder: IosFolder) -> Folder {
|
||||
Folder(id: folder.id, name: folder.name)
|
||||
}
|
||||
@@ -236,6 +245,8 @@ public actor UniFfiSessionBridge: SessionBridge {
|
||||
)
|
||||
case let .networkChanged(state):
|
||||
.networkChanged(mapNetworkState(state))
|
||||
case let .typingChanged(state):
|
||||
.typingChanged(mapTypingState(state))
|
||||
case let .draftChanged(draft):
|
||||
.draftChanged(mapDraft(draft))
|
||||
case let .profileLoaded(profile):
|
||||
|
||||
@@ -6,6 +6,7 @@ public final class SessionStore: ObservableObject {
|
||||
@Published public private(set) var account: Account
|
||||
@Published public private(set) var authState: AuthState = .waitTdlibParameters
|
||||
@Published public private(set) var networkState: NetworkState = .ready
|
||||
@Published public private(set) var typingState: TypingState = .idle
|
||||
@Published public private(set) var errorMessage: String?
|
||||
|
||||
public let bridge: SessionBridge
|
||||
@@ -40,6 +41,8 @@ public final class SessionStore: ObservableObject {
|
||||
authState = state
|
||||
case let .networkChanged(state):
|
||||
networkState = state
|
||||
case let .typingChanged(state):
|
||||
typingState = state
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ struct TeleTuiIOSSmokeTests {
|
||||
precondition(store.authState == .waitPhoneNumber)
|
||||
await store.refreshNetworkState()
|
||||
precondition(store.networkState == .ready)
|
||||
store.apply(events: [.typingChanged(.typing(chatId: 1, userId: 10, text: "typing"))])
|
||||
precondition(store.typingState == .typing(chatId: 1, userId: 10, text: "typing"))
|
||||
|
||||
viewModel.phone = "+10000000000"
|
||||
await viewModel.submitCurrentStep()
|
||||
|
||||
@@ -813,6 +813,18 @@ mod tests {
|
||||
CoreNetworkState::from(&NetworkState::WaitingForNetwork),
|
||||
CoreNetworkState::WaitingForNetwork
|
||||
);
|
||||
assert_eq!(
|
||||
CoreTypingState::Typing {
|
||||
chat_id: ChatId::new(42),
|
||||
user_id: UserId::new(7),
|
||||
text: "typing".to_string(),
|
||||
},
|
||||
CoreTypingState::Typing {
|
||||
chat_id: ChatId::new(42),
|
||||
user_id: UserId::new(7),
|
||||
text: "typing".to_string(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::collections::HashMap;
|
||||
use tele_core::session::{
|
||||
CoreAuthState, CoreChatSummary, CoreDownloadedFile, CoreDraft, CoreEvent, CoreFolder,
|
||||
CoreMedia, CoreMessage, CoreNetworkState, CoreProfile, CoreReaction, CoreSearchResult,
|
||||
CoreSession,
|
||||
CoreSession, CoreTypingState,
|
||||
};
|
||||
#[cfg(feature = "core-session")]
|
||||
use tele_core::tdlib::{ChatInfo, MessageBuilder, NetworkState, ProfileInfo};
|
||||
@@ -86,6 +86,30 @@ impl From<CoreNetworkState> for IosNetworkState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, uniffi::Enum)]
|
||||
pub enum IosTypingState {
|
||||
Idle,
|
||||
Typing {
|
||||
chat_id: i64,
|
||||
user_id: i64,
|
||||
text: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(feature = "core-session")]
|
||||
impl From<CoreTypingState> for IosTypingState {
|
||||
fn from(value: CoreTypingState) -> Self {
|
||||
match value {
|
||||
CoreTypingState::Idle => Self::Idle,
|
||||
CoreTypingState::Typing { chat_id, user_id, text } => Self::Typing {
|
||||
chat_id: chat_id.as_i64(),
|
||||
user_id: user_id.as_i64(),
|
||||
text,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, uniffi::Enum)]
|
||||
pub enum IosDownloadState {
|
||||
NotDownloaded,
|
||||
@@ -412,6 +436,9 @@ pub enum IosEvent {
|
||||
downloaded_size: i64,
|
||||
total_size: i64,
|
||||
},
|
||||
TypingChanged {
|
||||
state: IosTypingState,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(feature = "core-session")]
|
||||
@@ -455,7 +482,7 @@ impl From<CoreEvent> for IosEvent {
|
||||
CoreEvent::MediaDownloadProgress { file_id, downloaded_size, total_size } => {
|
||||
Self::MediaDownloadProgress { file_id, downloaded_size, total_size }
|
||||
}
|
||||
CoreEvent::TypingChanged(_) => Self::NetworkChanged { state: IosNetworkState::Ready },
|
||||
CoreEvent::TypingChanged(state) => Self::TypingChanged { state: state.into() },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1363,4 +1390,21 @@ mod tests {
|
||||
|
||||
assert!(format!("{error}").contains("real TDLib sessions"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "core-session")]
|
||||
#[test]
|
||||
fn typing_events_are_preserved_for_ios() {
|
||||
let event = IosEvent::from(CoreEvent::TypingChanged(CoreTypingState::Typing {
|
||||
chat_id: ChatId::new(1),
|
||||
user_id: tele_core::types::UserId::new(2),
|
||||
text: "typing".to_string(),
|
||||
}));
|
||||
|
||||
assert!(matches!(
|
||||
event,
|
||||
IosEvent::TypingChanged {
|
||||
state: IosTypingState::Typing { chat_id: 1, user_id: 2, text }
|
||||
} if text == "typing"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user