PageSourceSearch

https://juankman94.github.io/mylist/assets/main.js

js juankman94.github.io collected 2026-10-03 09:25:46 UTC 3,368 bytes, 116 lines download raw bytes

1/**
2 * Task
3 *
4 * @see https://todotxt.org/
5 *
6 * @typedef {Object} Task
7 * @property {string} task Task description
8 * @property {boolean} done Task completion
9 * @property {string} project Task project
10 * @property {string} context Task context
11 * @property {string} color Task color ID
12 */
13
14window.addEventListener('DOMContentLoaded', init)
15window.APP_NAME = 'MyList'
16window.DEBUG_MODE = false
17window.SORTABLE_INSTANCES = []
18window.STORAGE_NAME = 'todoState'
19window.DEFAULT_SORTABLE_CONFIG = {
20  animation: 150,
21  chosenClass: 'dragging',
22  fallbackOnBody: false,
23  ghostClass: 'zoom-in-out',
24  sort: true,
25  onSort: function(ev) {
26    const newState = StateManager.updateState()
27    postToBackend(newState)
28  },
29}
30window.NEW_LIST_PROMPT = 'What is this list about?'
31window.backendClient = new BackendClient(
32  localStorage.getItem('backend_url'),
33  localStorage.getItem('backend_username'),
34  localStorage.getItem('backend_passphrase'),
35  !!localStorage.getItem('backend_enabled')
36)
37window.AUTO_REMOVE_TIMEOUT = 6500
38
39function cleanUpSortable() {
40  let sortable = null
41
42  while (sortable = SORTABLE_INSTANCES.pop()) {
43    sortable.destroy()
44  }
45}
46
47// TODO: call persistState after an element is moved
48function setupSortable() {
49  cleanUpSortable()
50
51  document.querySelectorAll(`.${TaskList.TAG} .tasks-container`).forEach(tasksContainer => {
52    SORTABLE_INSTANCES.push(new Sortable(
53      tasksContainer,
54      Object.assign({ group: 'tasks', handle: '.task-grabber' }, DEFAULT_SORTABLE_CONFIG)))
55  })
56}
57
58/**
59 * Apply application settings from query string parameters.
60 *
61 * @param config {object}
62 * @return {object} Passed config with values overriden from query string.
63 */
64function applyQueryStringSettings(config) {
65  const url = new URL(window.location);
66  const theme = url.searchParams.get('theme');
67  const queryStringConfig = Object.assign({}, config);
68
69  if (theme != null) {
70    queryStringConfig.theme = theme;
71  }
72
73  applySettings(queryStringConfig);
74
75  return queryStringConfig;
76}
77
78function init(ev) {
79  if (window.DEBUG_MODE) {
80    setupDebugControls()
81  }
82
83  document.addEventListener(LIST_EVENTS.CHANGE, stateUpdated)
84  document.addEventListener(LIST_EVENTS.DELETE, ev => { removeListLink(ev) ; stateUpdated() })
85  document.addEventListener(TASK_EVENTS.CHANGE, stateUpdated)
86  document.addEventListener(TASK_EVENTS.DELETE, stateUpdated)
87
88  document.addEventListener(TodoSettings.SETTINGS_CHANGE_EVENT, (ev) => applySettings(ev.detail))
89
90  document.querySelector('.new-list')?.addEventListener('click', ev => {
91    const listName = TaskList.addList(document.getElementById('lists'))
92
93    if (listName)
94      addListLink(listName)
95  })
96  document.querySelector('#sync_btn')?.addEventListener('click', syncBackend)
97  document.querySelector('#export_json')?.addEventListener(
98    'click',
99    ev => downloadUsingBrowser(`${APP_NAME}.json`, JSON.stringify(StateManager.readState()))
100  )
101  document.querySelector('#import_json')?.addEventListener('change', importJson)
102  document.querySelector('#clear_cache_btn')?.addEventListener('click', requestCacheFlush)
103
104  const todoSettings = document.querySelector(TodoSettings.TAG)
105  let config = StateManager.settings()
106
107  StateManager.loadState()
108  config = applyQueryStringSettings(config);
109
110  window.backendClient.get()
111  setupSortable()
112
113  if (todoSettings) {
114    todoSettings.applyConfig(config)
115  }
116}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.