diff --git a/app/components/Cards/CardItem.scss b/app/components/Cards/CardItem.scss index ca857c08..e88ede65 100644 --- a/app/components/Cards/CardItem.scss +++ b/app/components/Cards/CardItem.scss @@ -179,7 +179,18 @@ $code-background: #08090a; } } } - + } + ul { + .task-list-item { + input { + position: relative; + vertical-align: bottom; + opacity: 1; + cursor: pointer; + height: 20px; + width: 20px; + } + } } div { display: flex; diff --git a/app/components/UI/TaskListInput.jsx b/app/components/UI/TaskListInput.jsx index 217571a3..7cc4dd92 100644 --- a/app/components/UI/TaskListInput.jsx +++ b/app/components/UI/TaskListInput.jsx @@ -1,38 +1,80 @@ import React, { Component } from 'react'; +import regexp from 'Utils/regexp'; import PropTypes from 'prop-types'; -class TaskListInput extends Component { +const FORBIDDEN_CHARACTERS = ['#', '*', 'ยด', '~', '`']; + +function dropMdChars(text) { + const textArray = []; + const isNotForbidden = char => FORBIDDEN_CHARACTERS.indexOf(char) === -1; + for (let i = 0; i < text.length; i += 1) { + const char = text[i]; + if (isNotForbidden(char)) { + textArray.push(char); + } + } + return textArray.join(''); +} +function getTaskDataFromInput(text) { + const taskData = { + tasks: [], + completed: 0, + }; + const tasks = text.match(regexp.extractTasksFromMarkdownRegExp)[0].split('- '); + for (let i = 0; i < tasks.length; i += 1) { + const task = tasks[i]; + if (task) { + const rawContent = task.slice(4, task.length - 1).trim(); + const completed = (task.slice(0, 3) === '[X]' && true) || false; + const textContent = dropMdChars(rawContent).trim(); + taskData.tasks.push({ + rawContent, + completed, + textContent, + }); + if (completed) { + taskData.completed += 1; + } + } + } + return taskData; +} + +class TaskListInput extends Component { render() { - const { text, editCard, defaultChecked } = this.props; + const { + text, editCard, defaultChecked, + } = this.props; return ( - { - e.stopPropagation(); - const { card, saveFunc } = editCard; - const inputTextContent = e.target.parentElement.textContent; - let newText = ''; - if (e.target.checked) { - const inputText = `[ ]${inputTextContent}`; - newText = text.replace(inputText, `[X]${inputTextContent}`); - } else { - const inputText = - (text.indexOf(`[X]${inputTextContent}`) !== -1 && `[X]${inputTextContent}`) || - (text.indexOf(`[x]${inputTextContent}`) !== -1 && `[x]${inputTextContent}`) || - null; - newText = text.replace(inputText, `[ ] ${inputTextContent}`); - } - - saveFunc({ - ...card, - text: newText, - }); - }} - /> + + { + e.stopPropagation(); + const { card, saveFunc } = editCard; + const taskData = getTaskDataFromInput(text); + let newText = ''; + const taskIndex = taskData.tasks + .map(t => t.textContent) + .indexOf(e.target.parentElement.textContent.trim()); + if (taskIndex !== -1) { + const task = taskData.tasks[taskIndex]; + const { rawContent, completed } = task; + const newRawContent = completed ? `[ ] ${rawContent}` : `[X] ${rawContent}`; + const targetContent = completed ? `[X] ${rawContent}` : `[ ] ${rawContent}`; + newText = text.replace(targetContent, newRawContent); + } + saveFunc({ + ...card, + text: newText, + }); + }} + /> + ); } } diff --git a/app/package.json b/app/package.json index 1834652a..3aaae765 100644 --- a/app/package.json +++ b/app/package.json @@ -31,7 +31,7 @@ "react-masonry-component": "^6.2.1", "react-redux": "^5.0.6", "react-router-dom": "4.1.1", - "react-showdown": "https://github.com/psybork/react-showdown.git", + "react-showdown": "https://github.com/dmorais92/react-showdown.git", "react-simplemde-editor": "^3.6.16", "react-tooltip": "^3.10.0", "recompose": "^0.30.0", diff --git a/app/utils/regexp.js b/app/utils/regexp.js index 35022de7..92b60d07 100644 --- a/app/utils/regexp.js +++ b/app/utils/regexp.js @@ -1,7 +1,9 @@ const codeRegExp = new RegExp(/`{3}[\s\S]*?`{3}/g); const backticksRegExp = new RegExp(/(?:```[a-z]*)/g); +const extractTasksFromMarkdownRegExp = new RegExp(/^((?:- )?\[( |X)\] [\#\S\w\s\`\*\~]*([\w]*[\`\*\~]+[\w\S\. ]*))/m); export default { codeRegExp, + extractTasksFromMarkdownRegExp, backticksRegExp, };