@@ -23,13 +23,14 @@ use tokio::{
23
23
} ;
24
24
use tracing:: { debug, info} ;
25
25
26
- use crate :: state:: { ModOrGroup , ModProfile } ;
27
26
use crate :: {
28
27
integrate:: uninstall,
29
28
is_drg_pak,
30
- providers:: ModioTags ,
31
- providers:: { FetchProgress , ModSpecification , ModStore , ProviderFactory } ,
32
- state:: { ModConfig , ModData_v0_1_0 as ModData , State } ,
29
+ providers:: {
30
+ ApprovalStatus , FetchProgress , ModInfo , ModSpecification , ModStore , ModioTags ,
31
+ ProviderFactory , RequiredStatus ,
32
+ } ,
33
+ state:: { ModConfig , ModData_v0_1_0 as ModData , ModOrGroup , ModProfile , State } ,
33
34
} ;
34
35
use find_string:: FindString ;
35
36
use message:: MessageHandle ;
@@ -117,11 +118,13 @@ impl App {
117
118
118
119
struct Ctx {
119
120
needs_save : bool ,
121
+ scroll_to_match : bool ,
120
122
btn_remove : Option < usize > ,
121
123
add_deps : Option < Vec < ModSpecification > > ,
122
124
}
123
125
let mut ctx = Ctx {
124
126
needs_save : false ,
127
+ scroll_to_match : self . scroll_to_match ,
125
128
btn_remove : None ,
126
129
add_deps : None ,
127
130
} ;
@@ -154,6 +157,143 @@ impl App {
154
157
} )
155
158
. collect :: < Vec < _ > > ( ) ;
156
159
160
+ let ui_mod_tags = |ctx : & mut Ctx , ui : & mut Ui , info : & ModInfo | {
161
+ if let Some ( ModioTags {
162
+ qol,
163
+ gameplay,
164
+ audio,
165
+ visual,
166
+ framework,
167
+ required_status,
168
+ approval_status,
169
+ versions : _,
170
+ } ) = info. modio_tags . as_ref ( )
171
+ {
172
+ let mut mk_searchable_modio_tag =
173
+ |tag_str : & str ,
174
+ ui : & mut Ui ,
175
+ color : Option < egui:: Color32 > ,
176
+ hover_str : Option < & str > | {
177
+ let text_color = if color. is_some ( ) {
178
+ Color32 :: BLACK
179
+ } else {
180
+ Color32 :: GRAY
181
+ } ;
182
+ let mut job = LayoutJob :: default ( ) ;
183
+ let mut is_match = false ;
184
+ if let Some ( search_string) = & self . search_string {
185
+ for ( m, chunk) in
186
+ find_string:: FindString :: new ( tag_str, search_string)
187
+ {
188
+ let background = if m {
189
+ is_match = true ;
190
+ TextFormat {
191
+ background : Color32 :: YELLOW ,
192
+ color : text_color,
193
+ ..Default :: default ( )
194
+ }
195
+ } else {
196
+ TextFormat {
197
+ color : text_color,
198
+ ..Default :: default ( )
199
+ }
200
+ } ;
201
+ job. append ( chunk, 0.0 , background) ;
202
+ }
203
+ } else {
204
+ job. append (
205
+ tag_str,
206
+ 0.0 ,
207
+ TextFormat {
208
+ color : text_color,
209
+ ..Default :: default ( )
210
+ } ,
211
+ ) ;
212
+ }
213
+
214
+ let button = if let Some ( color) = color {
215
+ egui:: Button :: new ( job)
216
+ . small ( )
217
+ . fill ( color)
218
+ . stroke ( egui:: Stroke :: NONE )
219
+ } else {
220
+ egui:: Button :: new ( job) . small ( ) . stroke ( egui:: Stroke :: NONE )
221
+ } ;
222
+
223
+ let res = if let Some ( hover_str) = hover_str {
224
+ ui. add_enabled ( false , button)
225
+ . on_disabled_hover_text ( hover_str)
226
+ } else {
227
+ ui. add_enabled ( false , button)
228
+ } ;
229
+
230
+ if is_match && self . scroll_to_match {
231
+ res. scroll_to_me ( None ) ;
232
+ ctx. scroll_to_match = false ;
233
+ }
234
+ } ;
235
+
236
+ match approval_status {
237
+ ApprovalStatus :: Verified => {
238
+ mk_searchable_modio_tag (
239
+ "Verified" ,
240
+ ui,
241
+ Some ( egui:: Color32 :: LIGHT_GREEN ) ,
242
+ Some ( "Does not contain any gameplay affecting features or changes" ) ,
243
+ ) ;
244
+ }
245
+ ApprovalStatus :: Approved => {
246
+ mk_searchable_modio_tag (
247
+ "Approved" ,
248
+ ui,
249
+ Some ( egui:: Color32 :: LIGHT_BLUE ) ,
250
+ Some ( "Contains gameplay affecting features or changes" ) ,
251
+ ) ;
252
+ }
253
+ ApprovalStatus :: Sandbox => {
254
+ mk_searchable_modio_tag ( "Sandbox" , ui, Some ( egui:: Color32 :: LIGHT_YELLOW ) , Some ( "Contains significant, possibly progression breaking, changes to gameplay" ) ) ;
255
+ }
256
+ }
257
+
258
+ match required_status {
259
+ RequiredStatus :: RequiredByAll => {
260
+ mk_searchable_modio_tag (
261
+ "RequiredByAll" ,
262
+ ui,
263
+ Some ( egui:: Color32 :: LIGHT_RED ) ,
264
+ Some (
265
+ "All lobby members must use this mod for it to work correctly!" ,
266
+ ) ,
267
+ ) ;
268
+ }
269
+ RequiredStatus :: Optional => {
270
+ mk_searchable_modio_tag (
271
+ "Optional" ,
272
+ ui,
273
+ None ,
274
+ Some ( "Clients are not required to install this mod to function" ) ,
275
+ ) ;
276
+ }
277
+ }
278
+
279
+ if * qol {
280
+ mk_searchable_modio_tag ( "QoL" , ui, None , None ) ;
281
+ }
282
+ if * gameplay {
283
+ mk_searchable_modio_tag ( "Gameplay" , ui, None , None ) ;
284
+ }
285
+ if * audio {
286
+ mk_searchable_modio_tag ( "Audio" , ui, None , None ) ;
287
+ }
288
+ if * visual {
289
+ mk_searchable_modio_tag ( "Visual" , ui, None , None ) ;
290
+ }
291
+ if * framework {
292
+ mk_searchable_modio_tag ( "Framework" , ui, None , None ) ;
293
+ }
294
+ }
295
+ } ;
296
+
157
297
let mut ui_mod = |ctx : & mut Ctx ,
158
298
ui : & mut Ui ,
159
299
_group : Option < & str > ,
@@ -331,105 +471,12 @@ impl App {
331
471
let res = ui. hyperlink_to ( job, & mc. spec . url ) ;
332
472
if is_match && self . scroll_to_match {
333
473
res. scroll_to_me ( None ) ;
334
- self . scroll_to_match = false ;
474
+ ctx . scroll_to_match = false ;
335
475
}
336
476
337
- if let Some ( ModioTags {
338
- qol,
339
- gameplay,
340
- audio,
341
- visual,
342
- framework,
343
- required_status,
344
- approval_status,
345
- .. // version ignored
346
- } ) = info. modio_tags . as_ref ( )
347
- {
348
- let mut mk_searchable_modio_tag = |tag_str : & str , ui : & mut Ui , color : Option < egui:: Color32 > , hover_str : Option < & str > | {
349
- let text_color = if color. is_some ( ) { Color32 :: BLACK } else { Color32 :: GRAY } ;
350
- let mut job = LayoutJob :: default ( ) ;
351
- let mut is_match = false ;
352
- if let Some ( search_string) = & self . search_string {
353
- for ( m, chunk) in find_string:: FindString :: new ( tag_str, search_string) {
354
- let background = if m {
355
- is_match = true ;
356
- TextFormat {
357
- background : Color32 :: YELLOW ,
358
- color : text_color,
359
- ..Default :: default ( )
360
- }
361
- } else {
362
- TextFormat {
363
- color : text_color,
364
- ..Default :: default ( )
365
- }
366
- } ;
367
- job. append ( chunk, 0.0 , background) ;
368
- }
369
- } else {
370
- job. append ( tag_str, 0.0 , TextFormat {
371
- color : text_color,
372
- ..Default :: default ( )
373
- } ) ;
374
- }
375
-
376
- let button = if let Some ( color) = color {
377
- egui:: Button :: new ( job) . small ( ) . fill ( color) . stroke ( egui:: Stroke :: NONE )
378
- } else {
379
- egui:: Button :: new ( job) . small ( ) . stroke ( egui:: Stroke :: NONE )
380
- } ;
381
-
382
- let res = if let Some ( hover_str) = hover_str {
383
- ui. add_enabled ( false , button) . on_disabled_hover_text ( hover_str)
384
- } else {
385
- ui. add_enabled ( false , button)
386
- } ;
387
-
388
- if is_match && self . scroll_to_match {
389
- res. scroll_to_me ( None ) ;
390
- self . scroll_to_match = false ;
391
- }
392
- } ;
393
-
394
- ui. with_layout ( Layout :: right_to_left ( Align :: Center ) , |ui| {
395
- match approval_status {
396
- crate :: providers:: ApprovalStatus :: Verified => {
397
- mk_searchable_modio_tag ( "Verified" , ui, Some ( egui:: Color32 :: LIGHT_GREEN ) , Some ( "Does not contain any gameplay affecting features or changes" ) ) ;
398
- }
399
- crate :: providers:: ApprovalStatus :: Approved => {
400
- mk_searchable_modio_tag ( "Approved" , ui, Some ( egui:: Color32 :: LIGHT_BLUE ) , Some ( "Contains gameplay affecting features or changes" ) ) ;
401
- }
402
- crate :: providers:: ApprovalStatus :: Sandbox => {
403
- mk_searchable_modio_tag ( "Sandbox" , ui, Some ( egui:: Color32 :: LIGHT_YELLOW ) , Some ( "Contains significant, possibly progression breaking, changes to gameplay" ) ) ;
404
- }
405
- }
406
-
407
- match required_status {
408
- crate :: providers:: RequiredStatus :: RequiredByAll => {
409
- mk_searchable_modio_tag ( "RequiredByAll" , ui, Some ( egui:: Color32 :: LIGHT_RED ) , Some ( "All lobby members must use this mod for it to work correctly!" ) ) ;
410
- }
411
- crate :: providers:: RequiredStatus :: Optional => {
412
- mk_searchable_modio_tag ( "Optional" , ui, None , Some ( "Clients are not required to install this mod to function" ) ) ;
413
- }
414
- }
415
-
416
- if * qol {
417
- mk_searchable_modio_tag ( "QoL" , ui, None , None ) ;
418
- }
419
- if * gameplay {
420
- mk_searchable_modio_tag ( "Gameplay" , ui, None , None ) ;
421
- }
422
- if * audio {
423
- mk_searchable_modio_tag ( "Audio" , ui, None , None ) ;
424
- }
425
- if * visual {
426
- mk_searchable_modio_tag ( "Visual" , ui, None , None ) ;
427
- }
428
- if * framework {
429
- mk_searchable_modio_tag ( "Framework" , ui, None , None ) ;
430
- }
431
- } ) ;
432
- }
477
+ ui. with_layout ( Layout :: right_to_left ( Align :: Center ) , |ui| {
478
+ ui_mod_tags ( ctx, ui, info) ;
479
+ } ) ;
433
480
} else {
434
481
if ui
435
482
. button ( "📋" )
@@ -533,6 +580,8 @@ impl App {
533
580
message:: ResolveMods :: send ( self , ui. ctx ( ) , add_deps, true ) ;
534
581
}
535
582
583
+ self . scroll_to_match = ctx. scroll_to_match ;
584
+
536
585
if ctx. needs_save {
537
586
self . state . mod_data . save ( ) . unwrap ( ) ;
538
587
}
0 commit comments