@@ -34,6 +34,7 @@ use http::StatusCode;
3434pub use identity_status_changes:: IdentityStatusChanges ;
3535#[ cfg( feature = "e2e-encryption" ) ]
3636use matrix_sdk_base:: crypto:: { IdentityStatusChange , RoomIdentityProvider , UserIdentity } ;
37+ pub use matrix_sdk_base:: store:: ThreadStatus ;
3738#[ cfg( feature = "e2e-encryption" ) ]
3839use matrix_sdk_base:: { crypto:: RoomEventDecryptionResult , deserialized_responses:: EncryptionInfo } ;
3940use matrix_sdk_base:: {
@@ -3657,10 +3658,21 @@ impl Room {
36573658 self . client
36583659 . send ( subscribe_thread:: unstable:: Request :: new (
36593660 self . room_id ( ) . to_owned ( ) ,
3660- thread_root,
3661+ thread_root. clone ( ) ,
36613662 automatic,
36623663 ) )
36633664 . await ?;
3665+
3666+ // Immediately save the result into the database.
3667+ self . client
3668+ . state_store ( )
3669+ . upsert_thread_subscription (
3670+ self . room_id ( ) ,
3671+ & thread_root,
3672+ ThreadStatus :: Subscribed { automatic } ,
3673+ )
3674+ . await ?;
3675+
36643676 Ok ( ( ) )
36653677 }
36663678
@@ -3679,9 +3691,16 @@ impl Room {
36793691 self . client
36803692 . send ( unsubscribe_thread:: unstable:: Request :: new (
36813693 self . room_id ( ) . to_owned ( ) ,
3682- thread_root,
3694+ thread_root. clone ( ) ,
36833695 ) )
36843696 . await ?;
3697+
3698+ // Immediately save the result into the database.
3699+ self . client
3700+ . state_store ( )
3701+ . upsert_thread_subscription ( self . room_id ( ) , & thread_root, ThreadStatus :: Unsubscribed )
3702+ . await ?;
3703+
36853704 Ok ( ( ) )
36863705 }
36873706
@@ -3695,42 +3714,57 @@ impl Room {
36953714 ///
36963715 /// # Returns
36973716 ///
3698- /// - An `Ok` result with `Some(ThreadSubscription )` if the subscription
3699- /// exists .
3717+ /// - An `Ok` result with `Some(ThreadStatus )` if we have some subscription
3718+ /// information .
37003719 /// - An `Ok` result with `None` if the subscription does not exist, or the
37013720 /// event couldn't be found, or the event isn't a thread.
37023721 /// - An error if the request fails for any other reason, such as a network
37033722 /// error.
37043723 pub async fn fetch_thread_subscription (
37053724 & self ,
37063725 thread_root : OwnedEventId ,
3707- ) -> Result < Option < ThreadSubscription > > {
3726+ ) -> Result < Option < ThreadStatus > > {
37083727 let result = self
37093728 . client
37103729 . send ( get_thread_subscription:: unstable:: Request :: new (
37113730 self . room_id ( ) . to_owned ( ) ,
3712- thread_root,
3731+ thread_root. clone ( ) ,
37133732 ) )
37143733 . await ;
37153734
37163735 match result {
3717- Ok ( response) => Ok ( Some ( ThreadSubscription { automatic : response. automatic } ) ) ,
3736+ Ok ( response) => Ok ( Some ( ThreadStatus :: Subscribed { automatic : response. automatic } ) ) ,
37183737 Err ( http_error) => match http_error. as_client_api_error ( ) {
3719- Some ( error) if error. status_code == StatusCode :: NOT_FOUND => Ok ( None ) ,
3738+ Some ( error) if error. status_code == StatusCode :: NOT_FOUND => {
3739+ // At this point the server returned no subscriptions, which can mean that the
3740+ // endpoint doesn't exist (not enabled/implemented yet on the server), or that
3741+ // the thread doesn't exist, or that the user has unsubscribed from it
3742+ // previously.
3743+ //
3744+ // If we had any information about prior unsubscription, we can use it here to
3745+ // return something slightly more precise than what the server returned.
3746+ let stored_status = self
3747+ . client
3748+ . state_store ( )
3749+ . load_thread_subscription ( self . room_id ( ) , & thread_root)
3750+ . await ?;
3751+
3752+ if let Some ( ThreadStatus :: Unsubscribed ) = stored_status {
3753+ // The thread was unsubscribed from before, so maintain this information.
3754+ Ok ( Some ( ThreadStatus :: Unsubscribed ) )
3755+ } else {
3756+ // We either have stale information (the thread was marked as subscribed
3757+ // to, but the server said it wasn't), or we didn't have any information.
3758+ // Return unknown.
3759+ Ok ( None )
3760+ }
3761+ }
37203762 _ => Err ( http_error. into ( ) ) ,
37213763 } ,
37223764 }
37233765 }
37243766}
37253767
3726- /// Status of a thread subscription.
3727- #[ derive( Debug , Clone , Copy ) ]
3728- pub struct ThreadSubscription {
3729- /// Whether the subscription was made automatically by a client, not by
3730- /// manual user choice.
3731- pub automatic : bool ,
3732- }
3733-
37343768#[ cfg( feature = "e2e-encryption" ) ]
37353769impl RoomIdentityProvider for Room {
37363770 fn is_member < ' a > ( & ' a self , user_id : & ' a UserId ) -> BoxFuture < ' a , bool > {
0 commit comments