@@ -30,6 +30,7 @@ use crate::login_param::LoginParam;
3030use crate :: message:: { self , Message , MessageState , MsgId , Viewtype } ;
3131use crate :: param:: { Param , Params } ;
3232use crate :: peerstate:: Peerstate ;
33+ use crate :: push:: PushSubscriber ;
3334use crate :: quota:: QuotaInfo ;
3435use crate :: scheduler:: { convert_folder_meaning, SchedulerState } ;
3536use crate :: sql:: Sql ;
@@ -86,6 +87,8 @@ pub struct ContextBuilder {
8687 events : Events ,
8788 stock_strings : StockStrings ,
8889 password : Option < String > ,
90+
91+ push_subscriber : Option < PushSubscriber > ,
8992}
9093
9194impl ContextBuilder {
@@ -101,6 +104,7 @@ impl ContextBuilder {
101104 events : Events :: new ( ) ,
102105 stock_strings : StockStrings :: new ( ) ,
103106 password : None ,
107+ push_subscriber : None ,
104108 }
105109 }
106110
@@ -155,10 +159,23 @@ impl ContextBuilder {
155159 self
156160 }
157161
162+ /// Sets push subscriber.
163+ pub ( crate ) fn with_push_subscriber ( mut self , push_subscriber : PushSubscriber ) -> Self {
164+ self . push_subscriber = Some ( push_subscriber) ;
165+ self
166+ }
167+
158168 /// Builds the [`Context`] without opening it.
159169 pub async fn build ( self ) -> Result < Context > {
160- let context =
161- Context :: new_closed ( & self . dbfile , self . id , self . events , self . stock_strings ) . await ?;
170+ let push_subscriber = self . push_subscriber . unwrap_or_default ( ) ;
171+ let context = Context :: new_closed (
172+ & self . dbfile ,
173+ self . id ,
174+ self . events ,
175+ self . stock_strings ,
176+ push_subscriber,
177+ )
178+ . await ?;
162179 Ok ( context)
163180 }
164181
@@ -263,6 +280,13 @@ pub struct InnerContext {
263280 /// Standard RwLock instead of [`tokio::sync::RwLock`] is used
264281 /// because the lock is used from synchronous [`Context::emit_event`].
265282 pub ( crate ) debug_logging : std:: sync:: RwLock < Option < DebugLogging > > ,
283+
284+ /// Push subscriber to store device token
285+ /// and register for heartbeat notifications.
286+ pub ( crate ) push_subscriber : PushSubscriber ,
287+
288+ /// True if account has subscribed to push notifications via IMAP.
289+ pub ( crate ) push_subscribed : AtomicBool ,
266290}
267291
268292/// The state of ongoing process.
@@ -308,7 +332,8 @@ impl Context {
308332 events : Events ,
309333 stock_strings : StockStrings ,
310334 ) -> Result < Context > {
311- let context = Self :: new_closed ( dbfile, id, events, stock_strings) . await ?;
335+ let context =
336+ Self :: new_closed ( dbfile, id, events, stock_strings, Default :: default ( ) ) . await ?;
312337
313338 // Open the database if is not encrypted.
314339 if context. check_passphrase ( "" . to_string ( ) ) . await ? {
@@ -323,6 +348,7 @@ impl Context {
323348 id : u32 ,
324349 events : Events ,
325350 stockstrings : StockStrings ,
351+ push_subscriber : PushSubscriber ,
326352 ) -> Result < Context > {
327353 let mut blob_fname = OsString :: new ( ) ;
328354 blob_fname. push ( dbfile. file_name ( ) . unwrap_or_default ( ) ) ;
@@ -331,7 +357,14 @@ impl Context {
331357 if !blobdir. exists ( ) {
332358 tokio:: fs:: create_dir_all ( & blobdir) . await ?;
333359 }
334- let context = Context :: with_blobdir ( dbfile. into ( ) , blobdir, id, events, stockstrings) ?;
360+ let context = Context :: with_blobdir (
361+ dbfile. into ( ) ,
362+ blobdir,
363+ id,
364+ events,
365+ stockstrings,
366+ push_subscriber,
367+ ) ?;
335368 Ok ( context)
336369 }
337370
@@ -374,6 +407,7 @@ impl Context {
374407 id : u32 ,
375408 events : Events ,
376409 stockstrings : StockStrings ,
410+ push_subscriber : PushSubscriber ,
377411 ) -> Result < Context > {
378412 ensure ! (
379413 blobdir. is_dir( ) ,
@@ -408,6 +442,8 @@ impl Context {
408442 last_full_folder_scan : Mutex :: new ( None ) ,
409443 last_error : std:: sync:: RwLock :: new ( "" . to_string ( ) ) ,
410444 debug_logging : std:: sync:: RwLock :: new ( None ) ,
445+ push_subscriber,
446+ push_subscribed : AtomicBool :: new ( false ) ,
411447 } ;
412448
413449 let ctx = Context {
@@ -1509,7 +1545,14 @@ mod tests {
15091545 let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
15101546 let dbfile = tmp. path ( ) . join ( "db.sqlite" ) ;
15111547 let blobdir = PathBuf :: new ( ) ;
1512- let res = Context :: with_blobdir ( dbfile, blobdir, 1 , Events :: new ( ) , StockStrings :: new ( ) ) ;
1548+ let res = Context :: with_blobdir (
1549+ dbfile,
1550+ blobdir,
1551+ 1 ,
1552+ Events :: new ( ) ,
1553+ StockStrings :: new ( ) ,
1554+ Default :: default ( ) ,
1555+ ) ;
15131556 assert ! ( res. is_err( ) ) ;
15141557 }
15151558
@@ -1518,7 +1561,14 @@ mod tests {
15181561 let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
15191562 let dbfile = tmp. path ( ) . join ( "db.sqlite" ) ;
15201563 let blobdir = tmp. path ( ) . join ( "blobs" ) ;
1521- let res = Context :: with_blobdir ( dbfile, blobdir, 1 , Events :: new ( ) , StockStrings :: new ( ) ) ;
1564+ let res = Context :: with_blobdir (
1565+ dbfile,
1566+ blobdir,
1567+ 1 ,
1568+ Events :: new ( ) ,
1569+ StockStrings :: new ( ) ,
1570+ Default :: default ( ) ,
1571+ ) ;
15221572 assert ! ( res. is_err( ) ) ;
15231573 }
15241574
@@ -1741,16 +1791,18 @@ mod tests {
17411791 let dir = tempdir ( ) ?;
17421792 let dbfile = dir. path ( ) . join ( "db.sqlite" ) ;
17431793
1744- let id = 1 ;
1745- let context = Context :: new_closed ( & dbfile, id, Events :: new ( ) , StockStrings :: new ( ) )
1794+ let context = ContextBuilder :: new ( dbfile. clone ( ) )
1795+ . with_id ( 1 )
1796+ . build ( )
17461797 . await
17471798 . context ( "failed to create context" ) ?;
17481799 assert_eq ! ( context. open( "foo" . to_string( ) ) . await ?, true ) ;
17491800 assert_eq ! ( context. is_open( ) . await , true ) ;
17501801 drop ( context) ;
17511802
1752- let id = 2 ;
1753- let context = Context :: new ( & dbfile, id, Events :: new ( ) , StockStrings :: new ( ) )
1803+ let context = ContextBuilder :: new ( dbfile)
1804+ . with_id ( 2 )
1805+ . build ( )
17541806 . await
17551807 . context ( "failed to create context" ) ?;
17561808 assert_eq ! ( context. is_open( ) . await , false ) ;
@@ -1766,8 +1818,9 @@ mod tests {
17661818 let dir = tempdir ( ) ?;
17671819 let dbfile = dir. path ( ) . join ( "db.sqlite" ) ;
17681820
1769- let id = 1 ;
1770- let context = Context :: new_closed ( & dbfile, id, Events :: new ( ) , StockStrings :: new ( ) )
1821+ let context = ContextBuilder :: new ( dbfile)
1822+ . with_id ( 1 )
1823+ . build ( )
17711824 . await
17721825 . context ( "failed to create context" ) ?;
17731826 assert_eq ! ( context. open( "foo" . to_string( ) ) . await ?, true ) ;
0 commit comments