@@ -34,6 +34,7 @@ use http::StatusCode;
34
34
pub use identity_status_changes:: IdentityStatusChanges ;
35
35
#[ cfg( feature = "e2e-encryption" ) ]
36
36
use matrix_sdk_base:: crypto:: { IdentityStatusChange , RoomIdentityProvider , UserIdentity } ;
37
+ pub use matrix_sdk_base:: store:: ThreadStatus ;
37
38
#[ cfg( feature = "e2e-encryption" ) ]
38
39
use matrix_sdk_base:: { crypto:: RoomEventDecryptionResult , deserialized_responses:: EncryptionInfo } ;
39
40
use matrix_sdk_base:: {
@@ -3657,10 +3658,21 @@ impl Room {
3657
3658
self . client
3658
3659
. send ( subscribe_thread:: unstable:: Request :: new (
3659
3660
self . room_id ( ) . to_owned ( ) ,
3660
- thread_root,
3661
+ thread_root. clone ( ) ,
3661
3662
automatic,
3662
3663
) )
3663
3664
. 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
+
3664
3676
Ok ( ( ) )
3665
3677
}
3666
3678
@@ -3679,9 +3691,16 @@ impl Room {
3679
3691
self . client
3680
3692
. send ( unsubscribe_thread:: unstable:: Request :: new (
3681
3693
self . room_id ( ) . to_owned ( ) ,
3682
- thread_root,
3694
+ thread_root. clone ( ) ,
3683
3695
) )
3684
3696
. 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
+
3685
3704
Ok ( ( ) )
3686
3705
}
3687
3706
@@ -3695,42 +3714,57 @@ impl Room {
3695
3714
///
3696
3715
/// # Returns
3697
3716
///
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 .
3700
3719
/// - An `Ok` result with `None` if the subscription does not exist, or the
3701
3720
/// event couldn't be found, or the event isn't a thread.
3702
3721
/// - An error if the request fails for any other reason, such as a network
3703
3722
/// error.
3704
3723
pub async fn fetch_thread_subscription (
3705
3724
& self ,
3706
3725
thread_root : OwnedEventId ,
3707
- ) -> Result < Option < ThreadSubscription > > {
3726
+ ) -> Result < Option < ThreadStatus > > {
3708
3727
let result = self
3709
3728
. client
3710
3729
. send ( get_thread_subscription:: unstable:: Request :: new (
3711
3730
self . room_id ( ) . to_owned ( ) ,
3712
- thread_root,
3731
+ thread_root. clone ( ) ,
3713
3732
) )
3714
3733
. await ;
3715
3734
3716
3735
match result {
3717
- Ok ( response) => Ok ( Some ( ThreadSubscription { automatic : response. automatic } ) ) ,
3736
+ Ok ( response) => Ok ( Some ( ThreadStatus :: Subscribed { automatic : response. automatic } ) ) ,
3718
3737
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
+ }
3720
3762
_ => Err ( http_error. into ( ) ) ,
3721
3763
} ,
3722
3764
}
3723
3765
}
3724
3766
}
3725
3767
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
-
3734
3768
#[ cfg( feature = "e2e-encryption" ) ]
3735
3769
impl RoomIdentityProvider for Room {
3736
3770
fn is_member < ' a > ( & ' a self , user_id : & ' a UserId ) -> BoxFuture < ' a , bool > {
0 commit comments