z_mirror/TaskList
git clone https://git.raiguard.me/z_mirror/TaskList
4a85a42
austinrobichaux18/Twiggy/AddPriorityAndArea
1--[[ 2DESIGN GOALS: 3- Extremely simple to-do list 4- Compact and full versions of the UI 5- Compact for reference, full for manipulation 6- Opt-in advanced features 7- Timed reminders (interval, absolute time) 8- Notifications for reminders 9- Task assignment 10- Maybe projects? 11- Current task must be easily visible in some way 12- Consider using the bottom-right of the screen for this 13- "Private" and "public" tasks 14- Private is visible only to you, public is visible to your force 15- An infinite amount of subtask nesting 16- Import and export TODOs 17 18DESIGN NOTES: 19- Each task will have an entirely unique ID 20- Store the next ID in the root of `storage` 21- Tasks will be stored in a one-dimensional table keyed by task ID 22- Tasks can be owned by the force, or by the player 23- Player tasks will be shown separately from force tasks 24- A task can have infinite subtasks 25- Subtasks are just pointers to other tasks, so they support the full feature suite, including more subtasks 26- Subtasks may have a different assignee from their parent 27- Import and export will use the standard method 28- Each owner (force, player, or task) will have a `tasks` array containing the task IDs to show, in order 29- Subtasks are also stored in the same manner, but are in a `subtasks` table instead 30- When a task is completed, it is added to its owners `completed_tasks` array at the front 31- Completed tasks will be listed after active tasks, in the order that they were completed 32- Store completion time? 33]] 34 35local gui =require ( "gui" ) 36local migration =require ( "__flib__.migration" ) 37 38local active_task_button =require ( "scripts.gui.active-task-button" ) 39local migrations =require ( "scripts.migrations" ) 40local edit_task_gui =require ( "scripts.gui.edit-task.index" ) 41local player_data =require ( "scripts.player-data" ) 42local task =require ( "scripts.task" ) 43local tasks_gui =require ( "scripts.gui.tasks.index" ) 44local util =require ( "scripts.util" ) 45 46--- @param force LuaForce 47local function init_force ( force ) 48--- @class ForceTable 49storage . forces [ force . index ] ={ 50--- @type number[] 51completed_tasks ={} , 52--- @type number[] 53tasks ={} , 54} 55end 56 57-- BOOTSTRAP 58 59script . on_init ( function () 60--- @type table<uint, ForceTable> 61storage . forces ={} 62storage . next_task_id =1 63--- @type table<uint, PlayerTable> 64storage . players ={} 65--- @type table<number, Task> 66storage . tasks ={} 67 68for _ , force in pairs ( game . forces ) do 69init_force ( force ) 70end 71for _ , player in pairs ( game . players ) do 72player_data . init ( player ) 73end 74 75migrations . generic () 76end ) 77 78script . on_load ( function () 79for _ , Task in pairs ( storage . tasks ) do 80task . load ( Task ) 81end 82 83for _ , player_table in pairs ( storage . players ) do 84tasks_gui . load ( player_table . guis . tasks ) 85if player_table . guis . edit_task then 86edit_task_gui . load ( player_table . guis . edit_task ) 87end 88end 89end ) 90 91script . on_configuration_changed ( function ( e ) 92if migration . on_config_changed ( e , migrations . versions ) then 93migrations . generic () 94end 95end ) 96 97-- FORCE 98 99script . on_event ( defines . events . on_force_created , function ( e ) 100init_force ( e . force ) 101end ) 102 103-- INTERACTION 104 105gui . hook_events ( function ( e ) 106local msg =gui . read_action ( e ) 107if msg then 108local Gui =util . get_gui ( e . player_index , msg . gui ) 109if Gui then 110Gui : dispatch ( msg , e ) 111end 112end 113end ) 114 115script . on_event ( "tlst-linked-confirm-gui" , function ( e ) 116local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 117local EditTaskGui =util . get_gui ( e . player_index , "edit_task" ) 118if EditTaskGui then 119EditTaskGui : dispatch ( { action ="confirm" } ) 120player . play_sound ( { path ="utility/confirm" } ) 121elseif player . mod_settings [ "tlst-new-task-on-confirm" ]. value then 122local TasksGui =util . get_gui ( e . player_index , "tasks" ) 123if TasksGui and TasksGui . state . visible and not TasksGui . state . pinned then 124TasksGui : dispatch ( { action ="edit_task" , confirmed =true } ) 125end 126end 127end ) 128 129--- @param player_index uint 130local function toggle_new_task ( player_index ) 131local EditTaskGui =util . get_gui ( player_index , "edit_task" ) 132if EditTaskGui then 133EditTaskGui : destroy () 134else 135local player =game . get_player ( player_index ) --[[@as LuaPlayer]] 136local player_table =storage . players [ player_index ] 137edit_task_gui . new ( player , player_table , { standalone =true } ) 138end 139end 140 141script . on_event ( "tlst-new-task" , function ( e ) 142toggle_new_task ( e . player_index ) 143end ) 144 145script . on_event ( { "tlst-toggle-gui" , defines . events . on_lua_shortcut } , function ( e ) 146if ( e . input_name or e . prototype_name ) == "tlst-toggle-gui" then 147local player_table =storage . players [ e . player_index ] 148local Gui =util . get_gui ( e . player_index , "tasks" ) 149if Gui then 150Gui : toggle () 151else 152local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 153player_data . refresh ( player , player_table ) 154end 155elseif e . prototype_name == "tlst-new-task" then 156toggle_new_task ( e . player_index ) 157end 158end ) 159 160-- PLAYER 161 162script . on_event ( defines . events . on_player_created , function ( e ) 163local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 164 165player_data . init ( player ) 166player_data . refresh ( player , storage . players [ e . player_index ]) 167end ) 168 169script . on_event ( defines . events . on_player_changed_force , function ( e ) 170local player =game . get_player ( e . player_index ) 171if not player then 172return 173end 174 175local player_table =storage . players [ e . player_index ] 176if not player_table then 177return 178end 179 180player_data . refresh ( player , player_table ) 181end ) 182 183script . on_event ( defines . events . on_player_removed , function ( e ) 184-- Remove all player tasks 185local player_table =storage . players [ e . player_index ] 186for _ , task_ids in pairs ( { player_table . completed_tasks , player_table . tasks } ) do 187for _ , task_id in pairs ( task_ids ) do 188local Task =storage . tasks [ task_id ] 189if Task then 190Task : delete () 191end 192end 193end 194 195storage . players [ e . player_index ] =nil 196end ) 197 198script . on_event ( defines . events . on_runtime_mod_setting_changed , function ( e ) 199if e . setting == "tlst-new-task-on-confirm" then 200local TasksGui =util . get_gui ( e . player_index , "tasks" ) 201if TasksGui then 202local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 203local tooltip ={ "gui.tlst-new-task" } 204if player . mod_settings [ e . setting ]. value then 205tooltip [ 1 ] =tooltip [ 1 ] .. "-instruction" 206end 207TasksGui . refs . new_task_button . tooltip =tooltip 208end 209elseif e . setting == "tlst-show-active-task" or e . setting == "tlst-active-filter-assigned" then 210local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 211local player_table =storage . players [ e . player_index ] 212local value =player . mod_settings [ "tlst-show-active-task" ]. value 213if value == "off" then 214active_task_button . destroy ( player_table ) 215else 216active_task_button . build ( player , player_table ) 217end 218end 219end )