z_mirror/TaskList
git clone https://git.raiguard.me/z_mirror/TaskList
155b98f
trunk
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" ) 36 37local active_task_button =require ( "scripts.gui.active-task-button" ) 38local migrations =require ( "scripts.migrations" ) 39local edit_task_gui =require ( "scripts.gui.edit-task.index" ) 40local player_data =require ( "scripts.player-data" ) 41local task =require ( "scripts.task" ) 42local tasks_gui =require ( "scripts.gui.tasks.index" ) 43local util =require ( "scripts.util" ) 44 45--- @param force LuaForce 46local function init_force ( force ) 47--- @class ForceTable 48storage . forces [ force . index ] ={ 49--- @type number[] 50completed_tasks ={} , 51--- @type number[] 52tasks ={} , 53} 54end 55 56-- BOOTSTRAP 57 58script . on_init ( function () 59--- @type table<uint, ForceTable> 60storage . forces ={} 61storage . next_task_id =1 62--- @type table<uint, PlayerTable> 63storage . players ={} 64--- @type table<number, Task> 65storage . tasks ={} 66 67for _ , force in pairs ( game . forces ) do 68init_force ( force ) 69end 70for _ , player in pairs ( game . players ) do 71player_data . init ( player ) 72end 73 74migrations . generic () 75end ) 76 77script . on_load ( function () 78for _ , Task in pairs ( storage . tasks ) do 79task . load ( Task ) 80end 81 82for _ , player_table in pairs ( storage . players ) do 83tasks_gui . load ( player_table . guis . tasks ) 84if player_table . guis . edit_task then 85edit_task_gui . load ( player_table . guis . edit_task ) 86end 87end 88end ) 89 90script . on_configuration_changed ( function ( e ) 91local old_version =e . mod_changes [ script . mod_name ] and e . mod_changes [ script . mod_name ]. old_version 92if not old_version then 93return 94end 95 96migrations . generic () 97 98for version , migration in pairs ( migrations . versions ) do 99if helpers . compare_versions ( old_version , version ) < 0 then 100migration () 101end 102end 103end ) 104 105-- FORCE 106 107script . on_event ( defines . events . on_force_created , function ( e ) 108init_force ( e . force ) 109end ) 110 111-- INTERACTION 112 113gui . hook_events ( function ( e ) 114local msg =gui . read_action ( e ) 115if msg then 116local Gui =util . get_gui ( e . player_index , msg . gui ) 117if Gui then 118Gui : dispatch ( msg , e ) 119end 120end 121end ) 122 123script . on_event ( "tlst-linked-confirm-gui" , function ( e ) 124local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 125local EditTaskGui =util . get_gui ( e . player_index , "edit_task" ) 126if EditTaskGui then 127EditTaskGui : dispatch ( { action ="confirm" } , e ) 128player . play_sound ( { path ="utility/confirm" } ) 129elseif player . mod_settings [ "tlst-new-task-on-confirm" ]. value then 130local TasksGui =util . get_gui ( e . player_index , "tasks" ) 131if TasksGui and TasksGui . state . visible and not TasksGui . state . pinned then 132TasksGui : dispatch ( { action ="edit_task" , confirmed =true } , e ) 133end 134end 135end ) 136 137--- @param player_index uint 138local function toggle_new_task ( player_index ) 139local EditTaskGui =util . get_gui ( player_index , "edit_task" ) 140if EditTaskGui then 141EditTaskGui : destroy () 142else 143local player =game . get_player ( player_index ) --[[@as LuaPlayer]] 144local player_table =storage . players [ player_index ] 145edit_task_gui . new ( player , player_table , { standalone =true } ) 146end 147end 148 149script . on_event ( "tlst-new-task" , function ( e ) 150toggle_new_task ( e . player_index ) 151end ) 152 153script . on_event ( { "tlst-toggle-gui" , defines . events . on_lua_shortcut } , function ( e ) 154if ( e . input_name or e . prototype_name ) == "tlst-toggle-gui" then 155local player_table =storage . players [ e . player_index ] 156local Gui =util . get_gui ( e . player_index , "tasks" ) 157if Gui then 158Gui : toggle () 159else 160local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 161player_data . refresh ( player , player_table ) 162end 163elseif e . prototype_name == "tlst-new-task" then 164toggle_new_task ( e . player_index ) 165end 166end ) 167 168-- PLAYER 169 170script . on_event ( defines . events . on_player_created , function ( e ) 171local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 172 173player_data . init ( player ) 174player_data . refresh ( player , storage . players [ e . player_index ]) 175end ) 176 177script . on_event ( defines . events . on_player_changed_force , function ( e ) 178local player =game . get_player ( e . player_index ) 179if not player then 180return 181end 182 183local player_table =storage . players [ e . player_index ] 184if not player_table then 185return 186end 187 188player_data . refresh ( player , player_table ) 189end ) 190 191script . on_event ( defines . events . on_player_removed , function ( e ) 192-- Remove all player tasks 193local player_table =storage . players [ e . player_index ] 194for _ , task_ids in pairs ( { player_table . completed_tasks , player_table . tasks } ) do 195for _ , task_id in pairs ( task_ids ) do 196local Task =storage . tasks [ task_id ] 197if Task then 198Task : delete () 199end 200end 201end 202 203storage . players [ e . player_index ] =nil 204end ) 205 206script . on_event ( defines . events . on_runtime_mod_setting_changed , function ( e ) 207if e . setting == "tlst-new-task-on-confirm" then 208local TasksGui =util . get_gui ( e . player_index , "tasks" ) 209if TasksGui then 210local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 211local tooltip ={ "gui.tlst-new-task" } 212if player . mod_settings [ e . setting ]. value then 213tooltip [ 1 ] =tooltip [ 1 ] .. "-instruction" 214end 215TasksGui . refs . new_task_button . tooltip =tooltip 216end 217elseif e . setting == "tlst-show-active-task" or e . setting == "tlst-active-filter-assigned" then 218local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 219local player_table =storage . players [ e . player_index ] 220local value =player . mod_settings [ "tlst-show-active-task" ]. value 221if value == "off" then 222active_task_button . destroy ( player_table ) 223else 224active_task_button . build ( player , player_table ) 225end 226end 227end )