11import { App , PluginSettingTab , Setting , Modal } from "obsidian" ;
22import TaskProgressBarPlugin from "./taskProgressBarIndex" ;
33import { allStatusCollections } from "./task-status" ;
4+ import { STATE_MARK_MAP , TaskState } from "./taskStatusSwitcher" ;
45
56export interface TaskProgressBarSettings {
7+ showProgressBar : boolean ;
68 addTaskProgressBarToHeading : boolean ;
79 enableHeadingProgressBar : boolean ;
810 addNumberToProgressBar : boolean ;
@@ -37,9 +39,15 @@ export interface TaskProgressBarSettings {
3739 max : number ;
3840 text : string ;
3941 } > ;
42+
43+ // Task status switcher settings
44+ enableTaskStatusSwitcher : boolean ;
45+ taskStatusCycle : string [ ] ;
46+ taskStatusMarks : Record < string , string > ;
4047}
4148
4249export const DEFAULT_SETTINGS : TaskProgressBarSettings = {
50+ showProgressBar : false ,
4351 addTaskProgressBarToHeading : false ,
4452 enableHeadingProgressBar : false ,
4553 addNumberToProgressBar : false ,
@@ -76,6 +84,16 @@ export const DEFAULT_SETTINGS: TaskProgressBarSettings = {
7684 { min : 60 , max : 80 , text : "Good progress {{PROGRESS}}%" } ,
7785 { min : 80 , max : 100 , text : "Almost there {{PROGRESS}}%" } ,
7886 ] ,
87+
88+ // Task status switcher settings
89+ enableTaskStatusSwitcher : false ,
90+ taskStatusCycle : [ "TODO" , "DOING" , "IN-PROGRESS" , "DONE" ] ,
91+ taskStatusMarks : {
92+ TODO : " " ,
93+ DOING : "-" ,
94+ "IN-PROGRESS" : ">" ,
95+ DONE : "x" ,
96+ } ,
7997} ;
8098
8199export class TaskProgressBarSettingTab extends PluginSettingTab {
@@ -102,6 +120,18 @@ export class TaskProgressBarSettingTab extends PluginSettingTab {
102120
103121 containerEl . createEl ( "h2" , { text : "📍 Task Progress Bar" } ) ;
104122
123+ new Setting ( containerEl )
124+ . setName ( "Show progress bar" )
125+ . setDesc ( "Toggle this to show the progress bar." )
126+ . addToggle ( ( toggle ) =>
127+ toggle
128+ . setValue ( this . plugin . settings . showProgressBar )
129+ . onChange ( async ( value ) => {
130+ this . plugin . settings . showProgressBar = value ;
131+ this . applySettingsUpdate ( ) ;
132+ } )
133+ ) ;
134+
105135 new Setting ( containerEl )
106136 . setName ( "Add progress bar to Heading" )
107137 . setDesc (
@@ -501,6 +531,153 @@ export class TaskProgressBarSettingTab extends PluginSettingTab {
501531 ) ;
502532 }
503533
534+ this . containerEl . createEl ( "h2" , { text : "Task Status Switcher" } ) ;
535+
536+ new Setting ( containerEl )
537+ . setName ( "Enable Task Status Switcher" )
538+ . setDesc (
539+ "Enable/disable the ability to cycle through task states by clicking."
540+ )
541+ . addToggle ( ( toggle ) => {
542+ toggle
543+ . setValue ( this . plugin . settings . enableTaskStatusSwitcher )
544+ . onChange ( async ( value ) => {
545+ this . plugin . settings . enableTaskStatusSwitcher = value ;
546+ this . applySettingsUpdate ( ) ;
547+ } ) ;
548+ } ) ;
549+
550+ new Setting ( containerEl )
551+ . setName ( "Task Status Cycle and Marks" )
552+ . setDesc (
553+ "Define task states and their corresponding marks. The order from top to bottom defines the cycling sequence."
554+ ) ;
555+
556+ // Create a container for the task states list
557+ const taskStatesContainer = containerEl . createDiv ( {
558+ cls : "task-states-container" ,
559+ } ) ;
560+
561+ // Function to refresh the task states list
562+ const refreshTaskStatesList = ( ) => {
563+ // Clear the container
564+ taskStatesContainer . empty ( ) ;
565+
566+ // Get current cycle and marks
567+ const cycle = this . plugin . settings . taskStatusCycle ;
568+ const marks = this . plugin . settings . taskStatusMarks ;
569+
570+ // Add each status in the cycle
571+ cycle . forEach ( ( state , index ) => {
572+ const stateRow = taskStatesContainer . createDiv ( {
573+ cls : "task-state-row" ,
574+ } ) ;
575+
576+ // Create the setting
577+ const stateSetting = new Setting ( stateRow )
578+ . setName ( `Status #${ index + 1 } ` )
579+ . addText ( ( text ) => {
580+ text . setValue ( state )
581+ . setPlaceholder ( "Status name" )
582+ . onChange ( ( value ) => {
583+ // Update the state name in both cycle and marks
584+ const oldState = cycle [ index ] ;
585+ cycle [ index ] = value ;
586+
587+ // If the old state had a mark, preserve it with the new name
588+ if ( oldState in marks ) {
589+ marks [ value ] = marks [ oldState ] ;
590+ delete marks [ oldState ] ;
591+ }
592+
593+ this . applySettingsUpdate ( ) ;
594+ } ) ;
595+ } )
596+ . addText ( ( text ) => {
597+ text . setValue ( marks [ state ] || " " )
598+ . setPlaceholder ( "Mark" )
599+ . onChange ( ( value ) => {
600+ // Only use the first character
601+ const mark = value . trim ( ) . charAt ( 0 ) || " " ;
602+ marks [ state ] = mark ;
603+ this . applySettingsUpdate ( ) ;
604+ } ) ;
605+ text . inputEl . maxLength = 1 ;
606+ text . inputEl . style . width = "40px" ;
607+ } ) ;
608+
609+ // Add buttons for moving up/down and removing
610+ stateSetting . addExtraButton ( ( button ) => {
611+ button
612+ . setIcon ( "arrow-up" )
613+ . setTooltip ( "Move up" )
614+ . onClick ( ( ) => {
615+ if ( index > 0 ) {
616+ // Swap with the previous item
617+ [ cycle [ index - 1 ] , cycle [ index ] ] = [
618+ cycle [ index ] ,
619+ cycle [ index - 1 ] ,
620+ ] ;
621+ this . applySettingsUpdate ( ) ;
622+ refreshTaskStatesList ( ) ;
623+ }
624+ } ) ;
625+ button . extraSettingsEl . style . marginRight = "0" ;
626+ } ) ;
627+
628+ stateSetting . addExtraButton ( ( button ) => {
629+ button
630+ . setIcon ( "arrow-down" )
631+ . setTooltip ( "Move down" )
632+ . onClick ( ( ) => {
633+ if ( index < cycle . length - 1 ) {
634+ // Swap with the next item
635+ [ cycle [ index ] , cycle [ index + 1 ] ] = [
636+ cycle [ index + 1 ] ,
637+ cycle [ index ] ,
638+ ] ;
639+ this . applySettingsUpdate ( ) ;
640+ refreshTaskStatesList ( ) ;
641+ }
642+ } ) ;
643+ button . extraSettingsEl . style . marginRight = "0" ;
644+ } ) ;
645+
646+ stateSetting . addExtraButton ( ( button ) => {
647+ button
648+ . setIcon ( "trash" )
649+ . setTooltip ( "Remove" )
650+ . onClick ( ( ) => {
651+ // Remove from cycle
652+ cycle . splice ( index , 1 ) ;
653+ // Don't remove from marks to preserve settings
654+ this . applySettingsUpdate ( ) ;
655+ refreshTaskStatesList ( ) ;
656+ } ) ;
657+ button . extraSettingsEl . style . marginRight = "0" ;
658+ } ) ;
659+ } ) ;
660+
661+ // Add button to add new status
662+ const addButtonContainer = taskStatesContainer . createDiv ( ) ;
663+ new Setting ( addButtonContainer ) . addButton ( ( button ) => {
664+ button
665+ . setButtonText ( "Add Status" )
666+ . setCta ( )
667+ . onClick ( ( ) => {
668+ // Add a new status to the cycle with a default mark
669+ const newStatus = `STATUS_${ cycle . length + 1 } ` ;
670+ cycle . push ( newStatus ) ;
671+ marks [ newStatus ] = " " ;
672+ this . applySettingsUpdate ( ) ;
673+ refreshTaskStatesList ( ) ;
674+ } ) ;
675+ } ) ;
676+ } ;
677+
678+ // Initial render of the task states list
679+ refreshTaskStatesList ( ) ;
680+
504681 this . containerEl . createEl ( "h2" , { text : "Say Thank You" } ) ;
505682
506683 new Setting ( containerEl )
0 commit comments