@@ -81,11 +81,22 @@ def _create_card_components(self, recording: Recording):
81
81
on_click = partial (self .recording_delete_button_click , recording = recording ),
82
82
)
83
83
84
- if recording .monitor_status :
85
- display_title = recording .title
86
- else :
87
- display_title = f"[{ self ._ ['monitor_stopped' ]} ] { recording .title } "
88
- display_title_label = ft .Text (display_title , size = 14 , selectable = True , max_lines = 1 , no_wrap = True )
84
+ status_prefix = ""
85
+ if not recording .monitor_status :
86
+ status_prefix = f"[{ self ._ ['monitor_stopped' ]} ] "
87
+
88
+ display_title = f"{ status_prefix } { recording .title } "
89
+ display_title_label = ft .Text (
90
+ display_title ,
91
+ size = 14 ,
92
+ selectable = True ,
93
+ max_lines = 1 ,
94
+ no_wrap = True ,
95
+ overflow = ft .TextOverflow .ELLIPSIS ,
96
+ expand = True ,
97
+ weight = ft .FontWeight .BOLD if recording .recording or recording .is_live else None ,
98
+ )
99
+
89
100
open_folder_button = ft .IconButton (
90
101
icon = ft .Icons .FOLDER ,
91
102
tooltip = self ._ ["open_folder" ],
@@ -98,10 +109,19 @@ def _create_card_components(self, recording: Recording):
98
109
)
99
110
speed_text_label = ft .Text (speed , size = 12 )
100
111
112
+ status_label = self .create_status_label (recording )
113
+
114
+ title_row = ft .Row (
115
+ [display_title_label , status_label ] if status_label else [display_title_label ],
116
+ alignment = ft .MainAxisAlignment .START ,
117
+ spacing = 5 ,
118
+ tight = True ,
119
+ )
120
+
101
121
card_container = ft .Container (
102
122
content = ft .Column (
103
123
[
104
- display_title_label ,
124
+ title_row ,
105
125
duration_text_label ,
106
126
speed_text_label ,
107
127
ft .Row (
@@ -114,17 +134,18 @@ def _create_card_components(self, recording: Recording):
114
134
delete_button ,
115
135
monitor_button
116
136
],
117
- spacing = 5
137
+ spacing = 3 ,
138
+ alignment = ft .MainAxisAlignment .START
118
139
),
119
140
],
120
- spacing = 5 ,
141
+ spacing = 3 ,
121
142
tight = True
122
143
),
123
- padding = 10 ,
144
+ padding = 8 ,
124
145
on_click = partial (self .recording_card_on_click , recording = recording ),
125
- bgcolor = None ,
146
+ bgcolor = self . get_card_background_color ( recording ) ,
126
147
border_radius = 5 ,
127
-
148
+ border = ft . border . all ( 2 , self . get_card_border_color ( recording )),
128
149
)
129
150
card = ft .Card (key = str (recording .rec_id ), content = card_container )
130
151
@@ -138,21 +159,126 @@ def _create_card_components(self, recording: Recording):
138
159
"recording_info_button" : recording_info_button ,
139
160
"edit_button" : edit_button ,
140
161
"monitor_button" : monitor_button ,
162
+ "status_label" : status_label ,
141
163
}
164
+
165
+ def get_card_background_color (self , recording : Recording ):
166
+ is_dark_mode = self .app .page .theme_mode == ft .ThemeMode .DARK
167
+ if recording .selected :
168
+ return ft .colors .GREY_800 if is_dark_mode else ft .colors .GREY_400
169
+ return None
170
+
171
+ @staticmethod
172
+ def get_card_border_color (recording : Recording ):
173
+ """Get the border color of the card."""
174
+ if recording .recording :
175
+ return ft .colors .GREEN
176
+ elif recording .status_info == RecordingStatus .RECORDING_ERROR :
177
+ return ft .colors .RED
178
+ elif not recording .is_live and recording .monitor_status :
179
+ return ft .colors .AMBER
180
+ elif not recording .monitor_status :
181
+ return ft .colors .GREY
182
+ return ft .colors .TRANSPARENT
183
+
184
+ def create_status_label (self , recording : Recording ):
185
+ if recording .recording :
186
+ return ft .Container (
187
+ content = ft .Text (self ._ ["recording" ], color = ft .colors .WHITE , size = 12 , weight = ft .FontWeight .BOLD ),
188
+ bgcolor = ft .colors .GREEN ,
189
+ border_radius = 5 ,
190
+ padding = 5 ,
191
+ width = 60 ,
192
+ height = 26 ,
193
+ alignment = ft .alignment .center ,
194
+ )
195
+ elif recording .status_info == RecordingStatus .RECORDING_ERROR :
196
+ return ft .Container (
197
+ content = ft .Text (self ._ ["recording_error" ], color = ft .colors .WHITE , size = 12 , weight = ft .FontWeight .BOLD ),
198
+ bgcolor = ft .colors .RED ,
199
+ border_radius = 5 ,
200
+ padding = 5 ,
201
+ width = 60 ,
202
+ height = 26 ,
203
+ alignment = ft .alignment .center ,
204
+ )
205
+ elif not recording .is_live and recording .monitor_status :
206
+ return ft .Container (
207
+ content = ft .Text (self ._ ["offline" ], color = ft .colors .BLACK , size = 12 , weight = ft .FontWeight .BOLD ),
208
+ bgcolor = ft .colors .AMBER ,
209
+ border_radius = 5 ,
210
+ padding = 5 ,
211
+ width = 60 ,
212
+ height = 26 ,
213
+ alignment = ft .alignment .center ,
214
+ )
215
+ elif not recording .monitor_status :
216
+ return ft .Container (
217
+ content = ft .Text (self ._ ["no_monitor" ], color = ft .colors .WHITE , size = 12 , weight = ft .FontWeight .BOLD ),
218
+ bgcolor = ft .colors .GREY ,
219
+ border_radius = 5 ,
220
+ padding = 5 ,
221
+ width = 60 ,
222
+ height = 26 ,
223
+ alignment = ft .alignment .center ,
224
+ )
225
+ return None
142
226
143
227
async def update_card (self , recording ):
144
228
"""Update only the recordings cards in the scrollable content area."""
145
229
if recording .rec_id in self .cards_obj :
146
- recording_card = self .cards_obj [recording .rec_id ]
147
- recording_card ["display_title_label" ].value = recording .display_title
148
- recording_card ["duration_label" ].value = self .app .record_manager .get_duration (recording )
149
- recording_card ["speed_label" ].value = recording .speed
150
- recording_card ["record_button" ].icon = self .get_icon_for_recording_state (recording )
151
- recording_card ["record_button" ].tooltip = self .get_tip_for_recording_state (recording )
152
- recording_card ["monitor_button" ].icon = self .get_icon_for_monitor_state (recording )
153
- recording_card ["monitor_button" ].tooltip = self .get_tip_for_monitor_state (recording )
154
- recording_card ["card" ].content .bgcolor = await self .update_record_hover (recording )
155
- recording_card ["card" ].update ()
230
+ try :
231
+ recording_card = self .cards_obj [recording .rec_id ]
232
+
233
+ status_prefix = ""
234
+ if not recording .monitor_status :
235
+ status_prefix = f"[{ self ._ ['monitor_stopped' ]} ] "
236
+
237
+ display_title = f"{ status_prefix } { recording .title } "
238
+ if recording_card .get ("display_title_label" ):
239
+ recording_card ["display_title_label" ].value = display_title
240
+ title_label_weight = ft .FontWeight .BOLD if recording .recording or recording .is_live else None
241
+ recording_card ["display_title_label" ].weight = title_label_weight
242
+
243
+ new_status_label = self .create_status_label (recording )
244
+
245
+ if recording_card ["card" ] and recording_card ["card" ].content and recording_card ["card" ].content .content :
246
+ title_row = recording_card ["card" ].content .content .controls [0 ]
247
+ title_row .alignment = ft .MainAxisAlignment .START
248
+ title_row .spacing = 5
249
+ title_row .tight = True
250
+
251
+ title_row_controls = title_row .controls
252
+ if len (title_row_controls ) > 1 :
253
+ if new_status_label :
254
+ title_row_controls [1 ] = new_status_label
255
+ else :
256
+ title_row_controls .pop (1 )
257
+ elif new_status_label :
258
+ title_row_controls .append (new_status_label )
259
+
260
+ recording_card ["status_label" ] = new_status_label
261
+
262
+ if recording_card .get ("duration_label" ):
263
+ recording_card ["duration_label" ].value = self .app .record_manager .get_duration (recording )
264
+
265
+ if recording_card .get ("speed_label" ):
266
+ recording_card ["speed_label" ].value = recording .speed
267
+
268
+ if recording_card .get ("record_button" ):
269
+ recording_card ["record_button" ].icon = self .get_icon_for_recording_state (recording )
270
+ recording_card ["record_button" ].tooltip = self .get_tip_for_recording_state (recording )
271
+
272
+ if recording_card .get ("monitor_button" ):
273
+ recording_card ["monitor_button" ].icon = self .get_icon_for_monitor_state (recording )
274
+ recording_card ["monitor_button" ].tooltip = self .get_tip_for_monitor_state (recording )
275
+
276
+ if recording_card ["card" ] and recording_card ["card" ].content :
277
+ recording_card ["card" ].content .bgcolor = self .get_card_background_color (recording )
278
+ recording_card ["card" ].content .border = ft .border .all (2 , self .get_card_border_color (recording ))
279
+ recording_card ["card" ].update ()
280
+ except Exception as e :
281
+ print (f"Error updating card: { e } " )
156
282
157
283
async def update_monitor_state (self , recording : Recording ):
158
284
"""Update the monitor button state based on the current monitoring status."""
0 commit comments