@@ -30,6 +30,7 @@ use crate::login_param::LoginParam;
30
30
use crate :: message:: { self , Message , MessageState , MsgId , Viewtype } ;
31
31
use crate :: param:: { Param , Params } ;
32
32
use crate :: peerstate:: Peerstate ;
33
+ use crate :: push:: PushSubscriber ;
33
34
use crate :: quota:: QuotaInfo ;
34
35
use crate :: scheduler:: { convert_folder_meaning, SchedulerState } ;
35
36
use crate :: sql:: Sql ;
@@ -86,6 +87,8 @@ pub struct ContextBuilder {
86
87
events : Events ,
87
88
stock_strings : StockStrings ,
88
89
password : Option < String > ,
90
+
91
+ push_subscriber : Option < PushSubscriber > ,
89
92
}
90
93
91
94
impl ContextBuilder {
@@ -101,6 +104,7 @@ impl ContextBuilder {
101
104
events : Events :: new ( ) ,
102
105
stock_strings : StockStrings :: new ( ) ,
103
106
password : None ,
107
+ push_subscriber : None ,
104
108
}
105
109
}
106
110
@@ -155,10 +159,23 @@ impl ContextBuilder {
155
159
self
156
160
}
157
161
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
+
158
168
/// Builds the [`Context`] without opening it.
159
169
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 ?;
162
179
Ok ( context)
163
180
}
164
181
@@ -263,6 +280,13 @@ pub struct InnerContext {
263
280
/// Standard RwLock instead of [`tokio::sync::RwLock`] is used
264
281
/// because the lock is used from synchronous [`Context::emit_event`].
265
282
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 ,
266
290
}
267
291
268
292
/// The state of ongoing process.
@@ -308,7 +332,8 @@ impl Context {
308
332
events : Events ,
309
333
stock_strings : StockStrings ,
310
334
) -> 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 ?;
312
337
313
338
// Open the database if is not encrypted.
314
339
if context. check_passphrase ( "" . to_string ( ) ) . await ? {
@@ -323,6 +348,7 @@ impl Context {
323
348
id : u32 ,
324
349
events : Events ,
325
350
stockstrings : StockStrings ,
351
+ push_subscriber : PushSubscriber ,
326
352
) -> Result < Context > {
327
353
let mut blob_fname = OsString :: new ( ) ;
328
354
blob_fname. push ( dbfile. file_name ( ) . unwrap_or_default ( ) ) ;
@@ -331,7 +357,14 @@ impl Context {
331
357
if !blobdir. exists ( ) {
332
358
tokio:: fs:: create_dir_all ( & blobdir) . await ?;
333
359
}
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
+ ) ?;
335
368
Ok ( context)
336
369
}
337
370
@@ -374,6 +407,7 @@ impl Context {
374
407
id : u32 ,
375
408
events : Events ,
376
409
stockstrings : StockStrings ,
410
+ push_subscriber : PushSubscriber ,
377
411
) -> Result < Context > {
378
412
ensure ! (
379
413
blobdir. is_dir( ) ,
@@ -408,6 +442,8 @@ impl Context {
408
442
last_full_folder_scan : Mutex :: new ( None ) ,
409
443
last_error : std:: sync:: RwLock :: new ( "" . to_string ( ) ) ,
410
444
debug_logging : std:: sync:: RwLock :: new ( None ) ,
445
+ push_subscriber,
446
+ push_subscribed : AtomicBool :: new ( false ) ,
411
447
} ;
412
448
413
449
let ctx = Context {
@@ -1509,7 +1545,14 @@ mod tests {
1509
1545
let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
1510
1546
let dbfile = tmp. path ( ) . join ( "db.sqlite" ) ;
1511
1547
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
+ ) ;
1513
1556
assert ! ( res. is_err( ) ) ;
1514
1557
}
1515
1558
@@ -1518,7 +1561,14 @@ mod tests {
1518
1561
let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
1519
1562
let dbfile = tmp. path ( ) . join ( "db.sqlite" ) ;
1520
1563
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
+ ) ;
1522
1572
assert ! ( res. is_err( ) ) ;
1523
1573
}
1524
1574
@@ -1741,16 +1791,18 @@ mod tests {
1741
1791
let dir = tempdir ( ) ?;
1742
1792
let dbfile = dir. path ( ) . join ( "db.sqlite" ) ;
1743
1793
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 ( )
1746
1797
. await
1747
1798
. context ( "failed to create context" ) ?;
1748
1799
assert_eq ! ( context. open( "foo" . to_string( ) ) . await ?, true ) ;
1749
1800
assert_eq ! ( context. is_open( ) . await , true ) ;
1750
1801
drop ( context) ;
1751
1802
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 ( )
1754
1806
. await
1755
1807
. context ( "failed to create context" ) ?;
1756
1808
assert_eq ! ( context. is_open( ) . await , false ) ;
@@ -1766,8 +1818,9 @@ mod tests {
1766
1818
let dir = tempdir ( ) ?;
1767
1819
let dbfile = dir. path ( ) . join ( "db.sqlite" ) ;
1768
1820
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 ( )
1771
1824
. await
1772
1825
. context ( "failed to create context" ) ?;
1773
1826
assert_eq ! ( context. open( "foo" . to_string( ) ) . await ?, true ) ;
0 commit comments