From 39ccdd7a517abc4ca3410b0cac01aa803da19be3 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 13:31:03 +0200 Subject: [PATCH 1/6] feat(list): add info dialoge to show list description --- package.json | 1 + src/components/home/TheNavigation.vue | 18 +++++++++-- src/components/input/editor.vue | 40 ++---------------------- src/helpers/markdownRenderer.ts | 44 +++++++++++++++++++++++++++ src/i18n/lang/en.json | 1 + src/icons.ts | 10 +++--- src/router/index.ts | 10 ++++++ src/views/list/ListInfo.vue | 43 ++++++++++++++++++++++++++ yarn.lock | 9 +++++- 9 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 src/helpers/markdownRenderer.ts create mode 100644 src/views/list/ListInfo.vue diff --git a/package.json b/package.json index b68a1798e..2a1173a08 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "@cypress/vite-dev-server": "3.1.1", "@cypress/vue": "4.2.0", "@faker-js/faker": "7.5.0", + "@types/dompurify": "^2.3.4", "@types/flexsearch": "0.7.3", "@typescript-eslint/eslint-plugin": "5.37.0", "@typescript-eslint/parser": "5.37.0", diff --git a/src/components/home/TheNavigation.vue b/src/components/home/TheNavigation.vue index dbe6fefaa..b52686110 100644 --- a/src/components/home/TheNavigation.vue +++ b/src/components/home/TheNavigation.vue @@ -16,6 +16,10 @@ {{ currentList.title === '' ? $t('misc.loading') : getListTitle(currentList) }} + + + + @@ -282,12 +286,22 @@ $hamburger-menu-icon-width: 28px; margin: 0; } - :deep(.dropdown-trigger) { + :deep(.dropdown-trigger), .info-button { color: var(--grey-400); - margin-left: 1rem; + margin-left: .5rem; height: 1rem; width: 1rem; cursor: pointer; } + + .info-button { + text-align: center; + height: 1.25rem; + line-height: 1.25rem; + width: 2rem; + margin-top: .25rem; + padding: 0 .5rem; + color: var(--grey-400); + } } \ No newline at end of file diff --git a/src/components/input/editor.vue b/src/components/input/editor.vue index 839df3386..b3ad026c6 100644 --- a/src/components/input/editor.vue +++ b/src/components/input/editor.vue @@ -72,7 +72,7 @@ import {defineComponent} from 'vue' import VueEasymde from './vue-easymde.vue' import {marked} from 'marked' import DOMPurify from 'dompurify' -import hljs from 'highlight.js/lib/common' +import {setupMarkdownRenderer} from '@/helpers/markdownRenderer' import {createEasyMDEConfig} from './editorConfig' @@ -222,43 +222,7 @@ export default defineComponent({ return checkboxes[n] }, renderPreview() { - const renderer = new marked.Renderer() - const linkRenderer = renderer.link - - let checkboxNum = -1 - marked.use({ - renderer: { - image: (src, title, text) => { - - title = title ? ` title="${title}` : '' - - // If the url starts with the api url, the image is likely an attachment and - // we'll need to download and parse it properly. - if (src.substr(0, window.API_URL.length + 7) === `${window.API_URL}/tasks/`) { - return `${text}` - } - - return `${text}` - }, - checkbox: (checked) => { - if (checked) { - checked = ' checked="checked"' - } - - checkboxNum++ - return `` - }, - link: (href, title, text) => { - const isLocal = href.startsWith(`${location.protocol}//${location.hostname}`) - const html = linkRenderer.call(renderer, href, title, text) - return isLocal ? html : html.replace(/^ { + + title = title ? ` title="${title}` : '' + + // If the url starts with the api url, the image is likely an attachment and + // we'll need to download and parse it properly. + if (src.substr(0, window.API_URL.length + 7) === `${window.API_URL}/tasks/`) { + return `${text}` + } + + return `${text}` + }, + checkbox: (checked) => { + if (checked) { + checked = ' checked="checked"' + } + + checkboxNum++ + return `` + }, + link: (href, title, text) => { + const isLocal = href.startsWith(`${location.protocol}//${location.hostname}`) + const html = linkRenderer.call(renderer, href, title, text) + return isLocal ? html : html.replace(/^ import('../views/list/ListInfo.vue') // List Settings import ListSettingEdit from '../views/list/settings/edit.vue' @@ -336,6 +337,15 @@ const router = createRouter({ showAsModal: true, }, }, + { + path: '/lists/:listId/info', + name: 'list.info', + component: ListInfo, + meta: { + showAsModal: true, + }, + props: route => ({ listId: parseInt(route.params.listId as string) }), + }, { path: '/lists/:listId', name: 'list.index', diff --git a/src/views/list/ListInfo.vue b/src/views/list/ListInfo.vue new file mode 100644 index 000000000..33d4164e6 --- /dev/null +++ b/src/views/list/ListInfo.vue @@ -0,0 +1,43 @@ + + + diff --git a/yarn.lock b/yarn.lock index 49c7566bd..d6a3143e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2168,6 +2168,13 @@ dependencies: "@types/node" "*" +"@types/dompurify@^2.3.4": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.3.4.tgz#94e997e30338ea24d4c8d08beca91ce4dd17a1b4" + integrity sha512-EXzDatIb5EspL2eb/xPGmaC8pePcTHrkDCONjeisusLFrVfl38Pjea/R0YJGu3k9ZQadSvMqW0WXPI2hEo2Ajg== + dependencies: + "@types/trusted-types" "*" + "@types/download@^8.0.0": version "8.0.1" resolved "https://registry.yarnpkg.com/@types/download/-/download-8.0.1.tgz#9653e0deb52f1b47f659e8e8be1651c8515bc0a7" @@ -2386,7 +2393,7 @@ dependencies: "@types/estree" "*" -"@types/trusted-types@^2.0.2": +"@types/trusted-types@*", "@types/trusted-types@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== -- 2.40.1 From 8c866401b0c7575b22a7c7852842708e82e75df6 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 14:23:46 +0200 Subject: [PATCH 2/6] fix: properly pass checkbox id to markdown renderer --- src/components/input/editor.vue | 2 +- src/helpers/markdownRenderer.ts | 4 ++-- src/views/list/ListInfo.vue | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/input/editor.vue b/src/components/input/editor.vue index b3ad026c6..fde440b8e 100644 --- a/src/components/input/editor.vue +++ b/src/components/input/editor.vue @@ -222,7 +222,7 @@ export default defineComponent({ return checkboxes[n] }, renderPreview() { - setupMarkdownRenderer() + setupMarkdownRenderer(this.checkboxId) this.preview = DOMPurify.sanitize(marked(this.text), {ADD_ATTR: ['target']}) diff --git a/src/helpers/markdownRenderer.ts b/src/helpers/markdownRenderer.ts index eaf461105..4737b6659 100644 --- a/src/helpers/markdownRenderer.ts +++ b/src/helpers/markdownRenderer.ts @@ -1,7 +1,7 @@ import {marked} from 'marked' import hljs from 'highlight.js/lib/common' -export function setupMarkdownRenderer() { +export function setupMarkdownRenderer(checkboxId: string) { const renderer = new marked.Renderer() const linkRenderer = renderer.link @@ -26,7 +26,7 @@ export function setupMarkdownRenderer() { } checkboxNum++ - return `` + return `` }, link: (href, title, text) => { const isLocal = href.startsWith(`${location.protocol}//${location.hostname}`) diff --git a/src/views/list/ListInfo.vue b/src/views/list/ListInfo.vue index 33d4164e6..bd6c9a16d 100644 --- a/src/views/list/ListInfo.vue +++ b/src/views/list/ListInfo.vue @@ -19,6 +19,7 @@ import {useStore} from '@/store' import {setupMarkdownRenderer} from '@/helpers/markdownRenderer' import {marked} from 'marked' import DOMPurify from 'dompurify' +import {createRandomID} from '@/helpers/randomId' const props = defineProps({ listId: { @@ -37,7 +38,7 @@ const htmlDescription = computed(() => { return '' } - setupMarkdownRenderer() + setupMarkdownRenderer(createRandomID()) return DOMPurify.sanitize(marked(description), {ADD_ATTR: ['target']}) }) -- 2.40.1 From 3bc0b294539a5fccdc552ed05c1159905c99021c Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 14:24:37 +0200 Subject: [PATCH 3/6] chore: remove indention --- src/components/home/TheNavigation.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/home/TheNavigation.vue b/src/components/home/TheNavigation.vue index b52686110..17f31932f 100644 --- a/src/components/home/TheNavigation.vue +++ b/src/components/home/TheNavigation.vue @@ -293,15 +293,15 @@ $hamburger-menu-icon-width: 28px; width: 1rem; cursor: pointer; } +} - .info-button { - text-align: center; - height: 1.25rem; - line-height: 1.25rem; - width: 2rem; - margin-top: .25rem; - padding: 0 .5rem; - color: var(--grey-400); - } +.info-button { + text-align: center; + height: 1.25rem; + line-height: 1.25rem; + width: 2rem; + margin-top: .25rem; + padding: 0 .5rem; + color: var(--grey-400); } \ No newline at end of file -- 2.40.1 From 7e80de81f75089d670e73e9d28b46c9111628099 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 14:25:27 +0200 Subject: [PATCH 4/6] chore: put computed in one line --- src/views/list/ListInfo.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/views/list/ListInfo.vue b/src/views/list/ListInfo.vue index bd6c9a16d..fb311a67e 100644 --- a/src/views/list/ListInfo.vue +++ b/src/views/list/ListInfo.vue @@ -29,9 +29,7 @@ const props = defineProps({ }) const store = useStore() -const list = computed(() => { - return store.getters['lists/getListById'](props.listId) -}) +const list = computed(() => store.getters['lists/getListById'](props.listId)) const htmlDescription = computed(() => { const description = list.value?.description || '' if (description === '') { -- 2.40.1 From 7c4b3c3be5804600c925692215a71345cc7f7e11 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 14:28:15 +0200 Subject: [PATCH 5/6] fix: styling --- src/components/home/TheNavigation.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/home/TheNavigation.vue b/src/components/home/TheNavigation.vue index 17f31932f..331a8aa5c 100644 --- a/src/components/home/TheNavigation.vue +++ b/src/components/home/TheNavigation.vue @@ -286,7 +286,7 @@ $hamburger-menu-icon-width: 28px; margin: 0; } - :deep(.dropdown-trigger), .info-button { + :deep(.dropdown-trigger) { color: var(--grey-400); margin-left: .5rem; height: 1rem; @@ -303,5 +303,6 @@ $hamburger-menu-icon-width: 28px; margin-top: .25rem; padding: 0 .5rem; color: var(--grey-400); + margin-left: .5rem; } \ No newline at end of file -- 2.40.1 From 6e0e4f8f35abc85f9a74392d5b4c489b07d54926 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 15 Sep 2022 14:28:42 +0200 Subject: [PATCH 6/6] chore: use Number() instead of parseInt --- src/router/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/index.ts b/src/router/index.ts index 290a9ff28..2b3e63043 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -344,7 +344,7 @@ const router = createRouter({ meta: { showAsModal: true, }, - props: route => ({ listId: parseInt(route.params.listId as string) }), + props: route => ({ listId: Number(route.params.listId as string) }), }, { path: '/lists/:listId', -- 2.40.1