Source: js/button_controller.js

  1. import { addEvent, addTask, addCustomTag } from './storage.js';
  2. import { getDaysKey } from './date.js';
  3. // import { getDate } from './navigation.js';
  4. /*
  5. button_controller.js
  6. contains tag selection and input bar upload funcionality
  7. */
  8. const tagSelectorDOM = document.getElementById('tag-selection');
  9. /**
  10. * toggle the css display value
  11. * for the tag selection options
  12. */
  13. function toggleOptionsDisplay() {
  14. const optionArr = document.querySelectorAll('.all-tags');
  15. // loop over all the options in the array to toggle the display
  16. for (let i = 0; i < optionArr.length; i += 1) {
  17. const item = optionArr[i];
  18. item.style.display = item.style.display === '' ? 'none' : '';
  19. item.selected = false;
  20. }
  21. }
  22. /**
  23. *
  24. * @param {string} oldTime - "hh:mm (24hr)"
  25. * @returns "hh:mm AM" (12hr)
  26. */
  27. export function convert24To12(oldTime) {
  28. if (oldTime !== '') {
  29. let endHour = oldTime.split(':', 2)[0];
  30. const endMin = oldTime.split(':', 2)[1];
  31. let endSuffix = '';
  32. if (endHour > 12) {
  33. endHour -= 12;
  34. if (endHour < 10) {
  35. endHour = `0${endHour}`;
  36. }
  37. endSuffix = 'PM';
  38. } else {
  39. if (endHour === '12') {
  40. endSuffix = 'PM';
  41. } else {
  42. endSuffix = 'AM';
  43. }
  44. if (endHour === '00') {
  45. endHour = '12';
  46. }
  47. }
  48. return `${endHour}:${endMin} ${endSuffix}`;
  49. }
  50. return '';
  51. }
  52. if (tagSelectorDOM !== null) {
  53. const applyTagsDOM = tagSelectorDOM.querySelector('#apply-tags-option');
  54. const newHeight = '150px'; // new height of tag selection box when clicked on
  55. /**
  56. * handling the click events on the document
  57. */
  58. document.addEventListener('click', (event) => {
  59. const elements = document.elementsFromPoint(
  60. event.clientX,
  61. event.clientY
  62. );
  63. let closeSideBar = true;
  64. let openTagWindow = true;
  65. let closeTagWindow = true;
  66. let closeClock = true;
  67. let closeUpload = true;
  68. for (let i = 0; i < elements.length; i += 1) {
  69. const eleClass = elements[i].getAttribute('class');
  70. const eleId = elements[i].getAttribute('id');
  71. // onclick tag selector, display the elements and
  72. // expand the height of tag selector
  73. if (openTagWindow && elements[i] === applyTagsDOM) {
  74. if (tagSelectorDOM.style.height !== newHeight) {
  75. tagSelectorDOM.style.height = newHeight;
  76. toggleOptionsDisplay();
  77. openTagWindow = false;
  78. }
  79. }
  80. // if you clicked on a element that has class 'all-tags'
  81. // then you cant close tag window
  82. if (eleClass !== null && eleClass.indexOf('all-tags') !== -1)
  83. closeTagWindow = false;
  84. // if you clicked on the sidebar itself
  85. // or the opensidebar button, dont close side bar
  86. if (eleId === 'mySidebar' || eleClass === 'openbtn')
  87. closeSideBar = false;
  88. // if you clicked inside the clock then you shouldn't close it
  89. if (eleId === 'popup-clock' || eleId === 'clock-img')
  90. closeClock = false;
  91. // if you clicked inside the uplaod area
  92. // or on the button itself, then no close
  93. if (eleId === 'popup-media' || eleId === 'media-img')
  94. closeUpload = false;
  95. }
  96. if (closeTagWindow && tagSelectorDOM.style.height !== '') {
  97. tagSelectorDOM.style.height = '';
  98. toggleOptionsDisplay();
  99. }
  100. if (
  101. closeSideBar &&
  102. document.getElementById('mySidebar').style.width !== '0px'
  103. )
  104. document.querySelector('.closebtn').onclick(event);
  105. if (closeClock) {
  106. const clockDOM = document.getElementById('popup-clock');
  107. if (clockDOM.style.display !== 'none')
  108. clockDOM.style.display = 'none';
  109. }
  110. if (closeClock) {
  111. const clockDOM = document.getElementById('popup-clock');
  112. if (clockDOM.style.display !== 'none')
  113. clockDOM.style.display = 'none';
  114. }
  115. if (closeUpload) {
  116. const uploadDOM = document.getElementById('popup-media');
  117. if (uploadDOM.style.display !== 'none')
  118. uploadDOM.style.display = 'none';
  119. }
  120. });
  121. const addTagDOM = document.getElementById('add-tag-option');
  122. addTagDOM.addEventListener('keypress', (button) => {
  123. if (button.key === 'Enter') {
  124. // ensure bar is not empty
  125. if (addTagDOM.value.replace(/\s/g, '').length) {
  126. // replace spaces and dashes with underscores
  127. let tagText = addTagDOM.value;
  128. tagText = tagText.replace(/\s/g, '_');
  129. tagText = tagText.replace('-', '_');
  130. addCustomTag(tagText);
  131. addTagDOM.value = '';
  132. }
  133. }
  134. });
  135. // tag selecting tags onclick
  136. tagSelectorDOM.addEventListener('change', function handleTags() {
  137. if (this.value === 'default') {
  138. return;
  139. }
  140. // skip over the last option which is padding
  141. if (this.value === '') {
  142. this.value = 'default';
  143. return;
  144. }
  145. const tags = this.children;
  146. let selectedCount = 0;
  147. for (let i = 0; i < tags.length; i += 1) {
  148. if (tags[i].innerHTML.includes('✓')) {
  149. selectedCount += 1;
  150. }
  151. }
  152. addTagDOM.placeholder = 'Add Tag Here...';
  153. for (let i = 0; i < tags.length; i += 1) {
  154. if (tags[i].innerHTML === this.value) {
  155. if (tags[i].innerHTML.includes('✓')) {
  156. tags[i].innerHTML = this.value.substring(
  157. 0,
  158. this.value.length - 2
  159. );
  160. } else if (selectedCount < 3) {
  161. // add tag if check not present and less that 3 selected currently
  162. tags[i].innerHTML = `${this.value} ✓`;
  163. } else {
  164. addTagDOM.placeholder = '3 Tags Max!';
  165. }
  166. }
  167. }
  168. this.value = 'default';
  169. });
  170. /*
  171. implements upload button functionality
  172. */
  173. document
  174. .getElementById('task-event-textbox')
  175. .addEventListener('keypress', (button) => {
  176. if (button.key === 'Enter') {
  177. const input = document.getElementById('task-event-textbox');
  178. // ensure bar is not empty
  179. if (!input.value.replace(/\s/g, '').length) {
  180. return;
  181. }
  182. // grab event/tag/time info
  183. const entry = {};
  184. let taskEventChoice = document.getElementById(
  185. 'task-event-selector'
  186. ).value;
  187. if (taskEventChoice === 'default') {
  188. // default to task
  189. taskEventChoice = 'Task';
  190. }
  191. if (taskEventChoice === 'Task') {
  192. /* entry should contain:
  193. *
  194. * content: "Go on a run",
  195. * completed: true/false,
  196. * tags: ["Other", ...]
  197. */
  198. entry.content = input.value;
  199. entry.completed = false;
  200. entry.tags = [];
  201. // collect selected tags from tag bar
  202. const tags =
  203. document.getElementById('tag-selection').children;
  204. for (let i = 0; i < tags.length; i += 1) {
  205. if (tags[i].innerHTML.includes('✓')) {
  206. entry.tags.push(
  207. tags[i].innerHTML.substring(
  208. 0,
  209. tags[i].innerHTML.length - 2
  210. )
  211. );
  212. }
  213. }
  214. // initialize task element
  215. const newEntry = document.createElement('task-log');
  216. newEntry.content = entry;
  217. // Append task element to log (subject to change according to log css etc.)
  218. const taskSpace = document.getElementById('log-tasks-area');
  219. taskSpace.appendChild(newEntry);
  220. addTask(getDaysKey(window.curDate), entry);
  221. } else if (taskEventChoice === 'Event') {
  222. /* entry should contain:
  223. *
  224. * content: "CSE 110 Lecture",
  225. * tags: ["Lecture", ...],
  226. * from: 1621308663, (currently contains hh:mm A/PM)
  227. * to: 1621367364 (currently contains hh:mm A/PM)
  228. */
  229. entry.content = input.value;
  230. entry.tags = [];
  231. // collect selected tags from tag bar
  232. const tags =
  233. document.getElementById('tag-selection').children;
  234. for (let i = 0; i < tags.length; i += 1) {
  235. if (tags[i].innerHTML.includes('✓')) {
  236. entry.tags.push(
  237. tags[i].innerHTML.substring(
  238. 0,
  239. tags[i].innerHTML.length - 2
  240. )
  241. );
  242. }
  243. }
  244. // pull time info from clock icon
  245. const from24 =
  246. document.getElementById('start-time').children[0].value;
  247. const to24 =
  248. document.getElementById('end-time').children[0].value;
  249. const fromTime = convert24To12(from24);
  250. const toTime = convert24To12(to24);
  251. /**
  252. * Flipped Time cases(from is after to):
  253. * AM to AM/ PM to PM: flip times and create event normally
  254. * PM to AM: create two events through the night, split at 00:00
  255. */
  256. // check if times flipped(from hour is greater, or same hour & from minutes greater)
  257. if (
  258. from24.substring(0, 2) > to24.substring(0, 2) ||
  259. (from24.substring(0, 2) === to24.substring(0, 2) &&
  260. from24.substring(3, 5) > to24.substring(3, 5))
  261. ) {
  262. // check PM to AM
  263. if (
  264. fromTime.substring(
  265. fromTime.length - 2,
  266. fromTime.length
  267. ) === 'PM' &&
  268. toTime.substring(
  269. toTime.length - 2,
  270. toTime.length
  271. ) === 'AM'
  272. ) {
  273. // create two events
  274. // create and add tomorrow's event, change entry.to to 23:59
  275. const tomorrowEntry =
  276. document.createElement('event-log');
  277. entry.from = '12:00 AM';
  278. entry.to = toTime;
  279. tomorrowEntry.content = entry;
  280. window.curDate.setDate(
  281. window.curDate.getDate() + 1
  282. );
  283. addEvent(getDaysKey(window.curDate), entry);
  284. window.curDate.setDate(
  285. window.curDate.getDate() - 1
  286. );
  287. // resume entry for today's event
  288. entry.from = fromTime;
  289. entry.to = '11:59 PM';
  290. } else {
  291. // flip times
  292. entry.from = toTime;
  293. entry.to = fromTime;
  294. }
  295. } else {
  296. // normal time case
  297. entry.from = fromTime;
  298. entry.to = toTime;
  299. }
  300. // initialize event element
  301. const newEntry = document.createElement('event-log');
  302. newEntry.content = entry;
  303. // Append event element to log (subject to change)
  304. const eventSpace =
  305. document.getElementById('log-events-area');
  306. eventSpace.appendChild(newEntry);
  307. addEvent(getDaysKey(window.curDate), entry);
  308. }
  309. // clear input bar
  310. input.value = '';
  311. }
  312. });
  313. }
  314. export default toggleOptionsDisplay;