@@ -99,12 +99,23 @@ export const manualSetFlairManagementForm = Devvit.createForm(
9999 ( data ) => ( { fields : data . fields as FormField [ ] } ) ,
100100 manualSetFlairManagementFormHandler ,
101101) ;
102+ export const manualSetFlairManagementForUserForm = Devvit . createForm (
103+ ( data ) => ( { fields : data . fields as FormField [ ] } ) ,
104+ manualSetFlairManagementForUserFormHandler ,
105+ ) ;
102106
103107export const manualPostRestrictionRemovalForm = Devvit . createForm (
104108 ( data ) => ( { fields : data . fields as FormField [ ] } ) ,
105109 manualPostRestrictionRemovalHandler ,
106110) ;
107111
112+ Devvit . addMenuItem ( {
113+ label : "[RepBot] - Set Flair Management For Specified User" ,
114+ forUserType : "moderator" ,
115+ location : "subreddit" ,
116+ onPress : handleFlairToggleForUser ,
117+ } ) ;
118+
108119Devvit . addMenuItem ( {
109120 label : "[RepBot] - Remove post restriction from user" ,
110121 forUserType : "moderator" ,
@@ -293,7 +304,7 @@ export async function handleFlairToggle(
293304 label : `Flair management for u/${ username } ` ,
294305 defaultValue : currentValue ,
295306 helpText :
296- "enabled = bot manages flair, disabled = bot will not manage flair" ,
307+ "Case insensitive. ' enabled' = bot manages flair, ' disabled' = bot will not manage flair" ,
297308 required : true ,
298309 } ,
299310 ] ;
@@ -364,8 +375,13 @@ export async function manualSetFlairManagementFormHandler(
364375 context : Context ,
365376) {
366377 const value = event . values . isEnabled as string | undefined ;
367-
368- if ( value !== "enabled" && value !== "disabled" ) {
378+ if ( ! value ) {
379+ context . ui . showToast ( "Your entry must contain a value." ) ;
380+ return ;
381+ }
382+ const enabled = / ^ e n a b l e d $ / i;
383+ const disabled = / ^ d i s a b l e d $ / i;
384+ if ( disabled . test ( value ) && ! enabled . test ( value ) ) {
369385 context . ui . showToast ( `You must enter "enabled" or "disabled"` ) ;
370386 return ;
371387 }
@@ -375,7 +391,9 @@ export async function manualSetFlairManagementFormHandler(
375391
376392 try {
377393 if ( context . commentId ) {
378- const comment = await context . reddit . getCommentById ( context . commentId ) ;
394+ const comment = await context . reddit . getCommentById (
395+ context . commentId ,
396+ ) ;
379397 username = comment ?. authorName ?? null ;
380398 } else if ( context . postId ) {
381399 const post = await context . reddit . getPostById ( context . postId ) ;
@@ -401,7 +419,7 @@ export async function manualSetFlairManagementFormHandler(
401419 const key = `flairToggle:${ user . username } ` ;
402420
403421 // enabled = no key
404- if ( value === " enabled" ) {
422+ if ( enabled . test ( value ) ) {
405423 await context . redis . del ( key ) ;
406424 } else {
407425 await context . redis . set ( key , "disabled" ) ;
@@ -412,6 +430,93 @@ export async function manualSetFlairManagementFormHandler(
412430 ) ;
413431}
414432
433+ export async function handleFlairToggleForUser (
434+ _ : MenuItemOnPressEvent ,
435+ context : Context ,
436+ ) {
437+ try {
438+ const fields = [
439+ {
440+ name : "target" ,
441+ type : "string" ,
442+ label : "Target Username (no u/)" ,
443+ defaultValue : "" ,
444+ helpText :
445+ "Case insensitive. The username of the user you want to toggle flair management for" ,
446+ required : true ,
447+ } ,
448+ {
449+ name : "isEnabled" ,
450+ type : "string" ,
451+ label : `Set Flair Management Status` ,
452+ defaultValue : "" ,
453+ helpText :
454+ "Case insensitive. 'enabled' = bot manages flair, 'disabled' = bot will not manage flair" ,
455+ required : true ,
456+ } ,
457+ ] ;
458+
459+ context . ui . showForm ( manualSetFlairManagementForUserForm , { fields } ) ;
460+ } catch ( err ) {
461+ logger . error ( "❌ Failed to toggle flair management" , {
462+ error : String ( err ) ,
463+ } ) ;
464+
465+ context . ui . showToast (
466+ "An error occurred while toggling flair management." ,
467+ ) ;
468+ }
469+ }
470+
471+ export async function manualSetFlairManagementForUserFormHandler (
472+ event : FormOnSubmitEvent < JSONObject > ,
473+ context : Context ,
474+ ) {
475+ const isEnabled = event . values . isEnabled as string | undefined ;
476+ const target = event . values . target as string | undefined ;
477+
478+ if ( ! isEnabled ) {
479+ context . ui . showToast ( "Enablement status is required." ) ;
480+ return ;
481+ }
482+
483+ if ( ! target ) {
484+ context . ui . showToast ( "Target user is required." ) ;
485+ return ;
486+ }
487+
488+ const enabled = / ^ e n a b l e d $ / i;
489+ const disabled = / ^ d i s a b l e d $ / i;
490+
491+ if ( ! disabled . test ( isEnabled ) && ! enabled . test ( isEnabled ) ) {
492+ context . ui . showToast ( `You must enter "enabled" or "disabled"` ) ;
493+ return ;
494+ }
495+
496+ const userRegex = / ^ [ a - z 0 - 9 \_ \- ] { 3 , 21 } $ / i;
497+
498+ if ( ! userRegex . test ( target ) ) {
499+ context . ui . showToast (
500+ "Username must be between 3 and 21 characters long and contain only letters, numbers, underscores, or hyphens." ,
501+ ) ;
502+ return ;
503+ }
504+
505+ // 🔍 Resolve user from target
506+ const key = `flairToggle:${ target } ` ;
507+
508+ // enabled = no key
509+ if ( enabled . test ( isEnabled ) ) {
510+ await context . redis . del ( key ) ;
511+ } else {
512+ await context . redis . set ( key , "disabled" ) ;
513+ }
514+
515+ context . ui . showToast (
516+ `Flair management for u/${ target } is now ${ isEnabled } ` ,
517+ ) ;
518+ }
519+
415520Devvit . configure ( {
416521 redditAPI : true ,
417522 redis : true ,
0 commit comments