@@ -3,14 +3,16 @@ use crate::settings::{Channel, Settings, VersionedSettings};
3
3
use crate :: { api, background, throw} ;
4
4
use atomicwrites:: { AtomicFile , OverwriteBehavior } ;
5
5
use scraper:: { Html , Selector } ;
6
- use serde:: Deserialize ;
6
+ use serde:: { Deserialize , Serialize } ;
7
7
use specta:: Type ;
8
8
use sqlx:: SqlitePool ;
9
9
use std:: collections:: HashSet ;
10
+ use std:: convert:: TryInto ;
10
11
use std:: env;
11
12
use std:: io:: Write ;
12
13
use std:: path:: { Path , PathBuf } ;
13
14
use std:: sync:: Arc ;
15
+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
14
16
use tauri:: { command, Config , State } ;
15
17
use tokio:: sync:: Mutex ;
16
18
use url:: Url ;
@@ -41,6 +43,7 @@ pub struct Data {
41
43
pub versioned_settings : VersionedSettings ,
42
44
pub paths : AppPaths ,
43
45
pub window : tauri:: Window ,
46
+ pub user_history : UndoHistory ,
44
47
}
45
48
impl Data {
46
49
pub fn settings ( & mut self ) -> & mut Settings {
@@ -122,6 +125,7 @@ pub async fn tags(data: DataState<'_>) -> Result<Vec<String>, String> {
122
125
pub async fn check_now ( data : DataState < ' _ > ) -> Result < ( ) , String > {
123
126
let mut data = data. 0 . lock ( ) . await ;
124
127
data. check_now ( ) ?;
128
+ data. user_history . push ( Action :: CheckNow ) ;
125
129
Ok ( ( ) )
126
130
}
127
131
@@ -227,6 +231,8 @@ pub async fn set_channels(channels: Vec<Channel>, data: DataState<'_>) -> Result
227
231
let mut data = data. 0 . lock ( ) . await ;
228
232
data. settings ( ) . channels = channels;
229
233
data. save_settings ( ) ?;
234
+ data. user_history
235
+ . push ( Action :: UpdateOrDeleteChannels ( "" . to_string ( ) ) ) ;
230
236
Ok ( ( ) )
231
237
}
232
238
@@ -256,7 +262,7 @@ pub async fn add_channel(options: AddChannelOptions, data: DataState<'_>) -> Res
256
262
} ;
257
263
258
264
settings. channels . push ( Channel {
259
- id : channel. id ,
265
+ id : channel. id . clone ( ) ,
260
266
name : channel. snippet . title ,
261
267
icon : channel. snippet . thumbnails . medium . url ,
262
268
uploads_playlist_id : channel. contentDetails . relatedPlaylists . uploads ,
@@ -265,6 +271,7 @@ pub async fn add_channel(options: AddChannelOptions, data: DataState<'_>) -> Res
265
271
tags : options. tags ,
266
272
} ) ;
267
273
data. save_settings ( ) ?;
274
+ data. user_history . push ( Action :: AddChannel ( channel. id ) ) ;
268
275
Ok ( ( ) )
269
276
}
270
277
@@ -291,3 +298,42 @@ impl ArcData {
291
298
Self ( Arc :: new ( Mutex :: new ( data) ) )
292
299
}
293
300
}
301
+
302
+ #[ derive( Serialize , Clone , Type ) ]
303
+ pub struct UndoHistory {
304
+ pub entries : Vec < ( u32 , Action ) > ,
305
+ }
306
+
307
+ impl UndoHistory {
308
+ pub fn new ( ) -> Self {
309
+ Self { entries : vec ! [ ] }
310
+ }
311
+ pub fn push ( & mut self , action : Action ) {
312
+ let time: u32 = SystemTime :: now ( )
313
+ . duration_since ( UNIX_EPOCH )
314
+ . unwrap ( )
315
+ . as_secs ( )
316
+ . try_into ( )
317
+ . unwrap ( ) ;
318
+ self . entries . push ( ( time, action) ) ;
319
+ if self . entries . len ( ) > 100 {
320
+ self . entries . remove ( 0 ) ;
321
+ }
322
+ }
323
+ }
324
+
325
+ #[ derive( Serialize , Clone , Type ) ]
326
+ pub enum Action {
327
+ CheckNow ,
328
+ Archive ( String ) ,
329
+ Unarchive ( String ) ,
330
+ AddChannel ( String ) ,
331
+ UpdateOrDeleteChannels ( String ) ,
332
+ }
333
+
334
+ #[ command]
335
+ #[ specta:: specta]
336
+ pub async fn get_history ( data : DataState < ' _ > ) -> Result < UndoHistory , String > {
337
+ let data = data. 0 . lock ( ) . await ;
338
+ Ok ( data. user_history . clone ( ) )
339
+ }
0 commit comments