1use crate::file_manager::FileEntry;
2use std::path::PathBuf;
3use std::time::Instant;
4
5pub enum PreviewData {
6 Directory(Vec<FileEntry>),
7 File(Vec<String>),
8 Empty,
9}
10
11pub struct PreviewState {
12 data: PreviewData,
13 selected_idx: usize,
14 current_path: Option<PathBuf>,
15 request_id: u64,
16 pending: bool,
17 last_input_time: Instant,
18}
19
20impl PreviewState {
21 pub fn data(&self) -> &PreviewData {
23 &self.data
24 }
25
26 pub fn selected_idx(&self) -> usize {
27 self.selected_idx
28 }
29
30 pub fn request_id(&self) -> u64 {
31 self.request_id
32 }
33
34 pub fn set_selected_idx(&mut self, idx: usize) {
36 let len = match &self.data {
37 PreviewData::Directory(entries) => entries.len(),
38 PreviewData::File(lines) => lines.len(),
39 PreviewData::Empty => 0,
40 };
41 self.selected_idx = idx.min(len.saturating_sub(1));
42 }
43
44 pub fn mark_pending(&mut self) {
45 self.pending = true;
46 self.last_input_time = Instant::now();
47 }
48
49 pub fn should_trigger(&self) -> bool {
51 self.pending && self.last_input_time.elapsed().as_millis() > 75
52 }
53
54 pub fn prepare_new_request(&mut self, path: PathBuf) -> u64 {
55 self.request_id += 1;
56 self.current_path = Some(path);
57 self.pending = false;
58 self.request_id
59 }
60
61 pub fn update_content(&mut self, lines: Vec<String>, request_id: u64) {
62 if request_id == self.request_id {
63 self.data = PreviewData::File(lines);
64 }
65 }
66
67 pub fn update_from_entries(&mut self, entries: Vec<FileEntry>, request_id: u64) {
68 if request_id == self.request_id {
69 self.data = PreviewData::Directory(entries);
70 self.selected_idx = 0;
71 }
72 }
73
74 pub fn set_error(&mut self, err: String) {
75 self.data = PreviewData::File(vec![err]);
76 }
77}
78
79impl PreviewData {
80 pub fn is_empty(&self) -> bool {
81 match self {
82 PreviewData::Directory(v) => v.is_empty(),
83 PreviewData::File(v) => v.is_empty(),
84 PreviewData::Empty => true,
85 }
86 }
87
88 pub fn iter(&self) -> impl Iterator<Item = &FileEntry> {
89 match self {
90 PreviewData::Directory(entries) => entries.iter(),
91 _ => [].iter(),
92 }
93 }
94
95 pub fn len(&self) -> usize {
96 match self {
97 PreviewData::Directory(entries) => entries.len(),
98 _ => 0,
99 }
100 }
101}
102
103impl Default for PreviewState {
104 fn default() -> Self {
105 Self {
106 data: PreviewData::Empty,
107 selected_idx: 0,
108 current_path: None,
109 request_id: 0,
110 pending: false,
111 last_input_time: Instant::now(),
112 }
113 }
114}