1
1
use crate :: report_client:: ReportClient ;
2
2
use chrono:: { DateTime , Duration , Utc } ;
3
- use std:: sync:: Arc ;
3
+ use std:: { cmp :: max , sync:: Arc } ;
4
4
5
5
pub struct State {
6
6
last_input_time : DateTime < Utc > ,
7
+ changed_time : DateTime < Utc > ,
7
8
is_idle : bool ,
8
9
is_changed : bool ,
9
10
idle_timeout : Duration ,
@@ -13,22 +14,26 @@ impl State {
13
14
pub fn new ( idle_timeout : Duration ) -> Self {
14
15
Self {
15
16
last_input_time : Utc :: now ( ) ,
17
+ changed_time : Utc :: now ( ) ,
16
18
is_idle : false ,
17
19
is_changed : false ,
18
20
idle_timeout,
19
21
}
20
22
}
21
23
22
- pub fn mark_not_idle ( & mut self ) {
23
- self . is_idle = false ;
24
+ fn set_idle ( & mut self , is_idle : bool , now : DateTime < Utc > ) {
25
+ self . is_idle = is_idle ;
24
26
self . is_changed = true ;
27
+ self . changed_time = now;
28
+ }
29
+
30
+ pub fn mark_not_idle ( & mut self ) {
25
31
self . last_input_time = Utc :: now ( ) ;
32
+ self . set_idle ( false , self . last_input_time ) ;
26
33
}
27
34
28
35
pub fn mark_idle ( & mut self ) {
29
- self . is_idle = true ;
30
- self . is_changed = true ;
31
- self . last_input_time -= self . idle_timeout ;
36
+ self . set_idle ( true , Utc :: now ( ) ) ;
32
37
}
33
38
34
39
// The logic is rewritten from the original Python code:
@@ -47,14 +52,12 @@ impl State {
47
52
&& u64:: from ( seconds_since_input) < self . idle_timeout . num_seconds ( ) . try_into ( ) . unwrap ( )
48
53
{
49
54
debug ! ( "No longer idle" ) ;
50
- self . is_idle = false ;
51
- self . is_changed = true ;
55
+ self . set_idle ( false , now) ;
52
56
} else if !self . is_idle
53
57
&& u64:: from ( seconds_since_input) >= self . idle_timeout . num_seconds ( ) . try_into ( ) . unwrap ( )
54
58
{
55
59
debug ! ( "Idle again" ) ;
56
- self . is_idle = true ;
57
- self . is_changed = true ;
60
+ self . set_idle ( true , now) ;
58
61
}
59
62
60
63
self . send_ping ( now, client) . await
@@ -63,7 +66,7 @@ impl State {
63
66
pub async fn send_reactive ( & mut self , client : & Arc < ReportClient > ) -> anyhow:: Result < ( ) > {
64
67
let now = Utc :: now ( ) ;
65
68
if !self . is_idle {
66
- self . last_input_time = now;
69
+ self . last_input_time = max ( now - self . idle_timeout , self . changed_time ) ;
67
70
}
68
71
69
72
self . send_ping ( now, client) . await
0 commit comments