From df5f663d327801ff947a4ef40e969ada97a94e95 Mon Sep 17 00:00:00 2001 From: ransome1 Date: Sun, 11 Feb 2024 17:16:12 +0100 Subject: [PATCH] Added function to shorten links longer than 40 characters. Added proof of concept for human friendly dates in the UI (https://github.com/ransome1/sleek/issues/609). Added a setting, which helps to hide todos by prepending a prefix to the beginning of the line (https://github.com/ransome1/sleek/issues/660). --- .github/ISSUE_TEMPLATE/feature_request.md | 4 +-- assets/mas/entitlements.mas.plist | 2 -- flatpak/com.github.ransome1.sleek.appdata.xml | 2 +- package.json | 4 +-- release/app/package.json | 2 +- snap/snapcraft.yaml | 2 +- src/__tests__/__mock__/recurrence.txt | 28 +++++++++---------- src/locales/cs.json | 1 + src/locales/de.json | 1 + src/locales/en-gb.json | 1 + src/locales/en.json | 1 + src/locales/fr.json | 1 + src/locales/hi.json | 1 + src/locales/hu.json | 1 + src/locales/it.json | 1 + src/locales/jp.json | 1 + src/locales/ko.json | 1 + src/locales/pl.json | 1 + src/locales/pt.json | 1 + src/locales/ru.json | 1 + src/locales/tr.json | 1 + src/locales/zh.json | 1 + src/main/config.tsx | 13 ++++----- .../ProcessDataRequest/CreateTodoObjects.tsx | 17 ++++++++--- src/renderer/Drawer/Attributes.tsx | 13 +++++++-- src/renderer/Grid/DatePickerInline.tsx | 11 +++++++- src/renderer/Grid/Renderer.tsx | 25 +++++++++++------ src/renderer/Settings/Settings.tsx | 3 ++ src/renderer/index.ejs | 2 +- 29 files changed, 94 insertions(+), 49 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 4a17381b..ba0643a2 100755 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -9,9 +9,7 @@ labels: 'feature request' ## Feature Request ### Important ### -Please follow this template strictly when requesting features. - -Reports that do not adhere to this template will not be addressed and will be closed. +Requests that do not adhere to this template will not be addressed and will be closed. If your feature request is more of a **loose idea** and you are **unsure about its implementation or potential impact**, please discuss it first in the [GitHub Discussions section](https://github.com/ransome1/sleek/discussions). diff --git a/assets/mas/entitlements.mas.plist b/assets/mas/entitlements.mas.plist index 3d52cfad..88f06214 100644 --- a/assets/mas/entitlements.mas.plist +++ b/assets/mas/entitlements.mas.plist @@ -10,8 +10,6 @@ com.apple.security.network.client - com.apple.security.files.user-selected.read-only - com.apple.security.files.user-selected.read-write com.apple.security.files.bookmarks.document-scope diff --git a/flatpak/com.github.ransome1.sleek.appdata.xml b/flatpak/com.github.ransome1.sleek.appdata.xml index 3601c072..8ff98dc1 100755 --- a/flatpak/com.github.ransome1.sleek.appdata.xml +++ b/flatpak/com.github.ransome1.sleek.appdata.xml @@ -9,7 +9,7 @@ Robin Ahle - + https://github.com/ransome1/sleek https://github.com/ransome1/sleek/issues diff --git a/package.json b/package.json index 91d54e2c..28d6e8e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sleek", - "version": "2.0.9", + "version": "2.0.10-rc.1", "main": "./src/main/main.tsx", "scripts": { "build": "concurrently \"yarn run peggy\" \"yarn run build:main\" \"yarn run build:renderer\"", @@ -147,7 +147,7 @@ "webpack-merge": "^5.9.0" }, "build": { - "buildVersion": "38", + "buildVersion": "39", "asar": true, "asarUnpack": "**\\*.{node,dll}", "files": [ diff --git a/release/app/package.json b/release/app/package.json index 172d3f28..ab6620a7 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "sleek", - "version": "2.0.9", + "version": "2.0.10-rc.1", "description": "todo.txt manager for Linux, Windows and MacOS, free and open-source (FOSS)", "synopsis": "todo.txt manager for Linux, Windows and MacOS, free and open-source (FOSS)", "keywords": [ diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8e536edb..d046701e 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: sleek base: core20 -version: "2.0.9" +version: "2.0.10-rc.1" summary: todo.txt manager for Linux, free and open-source (FOSS) description: | sleek is an open-source (FOSS) todo manager based on the todo.txt syntax. Stripped down to only the most necessary features, and with a clean and simple interface, sleek aims to help you focus on getting things done. diff --git a/src/__tests__/__mock__/recurrence.txt b/src/__tests__/__mock__/recurrence.txt index d75c0e38..75003f2e 100644 --- a/src/__tests__/__mock__/recurrence.txt +++ b/src/__tests__/__mock__/recurrence.txt @@ -1,15 +1,15 @@ -2024-02-09 Line 1 rec:1d due:2024-02-10 -2024-02-09 Line 1 rec:w due:2024-02-16 -2024-02-09 Line 1 rec:2m due:2024-04-09 -2024-02-09 Line 1 rec:+1d due:2024-02-11 -2024-02-09 Line 1 rec:7w due:2024-03-29 -2024-02-09 Line 1 due:2023-07-24 rec:+1b -2024-02-09 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y -2024-02-09 Water plants @home +quick due:2024-02-16 t:2024-02-06 rec:1w -2024-02-09 Line 1 rec:+1d t:2023-09-20 -2024-02-09 Line 1 rec:1d pri:A due:2024-02-10 -2024-02-09 (A) Do something rec:d t:2024-02-10 @SomeContext -2024-02-09 Do something rec:0d -2024-02-09 Do something rec:0d due:2024-02-09 -2024-02-09 Do something rec:0d due:2024-02-09 t:2024-02-09 \ No newline at end of file +2024-02-11 Line 1 rec:1d due:2024-02-12 +2024-02-11 Line 1 rec:w due:2024-02-18 +2024-02-11 Line 1 rec:2m due:2024-04-11 +2024-02-11 Line 1 rec:+1d due:2024-02-13 +2024-02-11 Line 1 rec:7w due:2024-03-31 +2024-02-11 Line 1 due:2023-07-24 rec:+1b +2024-02-11 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y +2024-02-11 Water plants @home +quick due:2024-02-18 t:2024-02-08 rec:1w +2024-02-11 Line 1 rec:+1d t:2023-09-20 +2024-02-11 Line 1 rec:1d pri:A due:2024-02-12 +2024-02-11 (A) Do something rec:d t:2024-02-12 @SomeContext +2024-02-11 Do something rec:0d +2024-02-11 Do something rec:0d due:2024-02-11 +2024-02-11 Do something rec:0d due:2024-02-11 t:2024-02-11 \ No newline at end of file diff --git a/src/locales/cs.json b/src/locales/cs.json index 18e2ab6a..702165d6 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -26,6 +26,7 @@ "settings.matomo": "Povolit analýzu Matomo", "settings.zoom": "Přiblížení", "settings.disableAnimations": "Vypnout animace", + "settings.useHumanFriendlyDates": "Používat lidsky přívětivá data", "drawer.tabs.attributes": "Atributy", "drawer.tabs.filters": "Filtry", "drawer.tabs.sorting": "Řazení", diff --git a/src/locales/de.json b/src/locales/de.json index 2fc2302f..89d27d68 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -26,6 +26,7 @@ "settings.matomo": "Matomo-Analyse zulassen", "settings.zoom": "Vergrößerung", "settings.disableAnimations": "Animationen deaktivieren", + "settings.useHumanFriendlyDates": "Benutze benutzerfreundliche Datumsangaben", "drawer.tabs.attributes": "Attribute", "drawer.tabs.filters": "Filter", "drawer.tabs.sorting": "Sortierung", diff --git a/src/locales/en-gb.json b/src/locales/en-gb.json index 56fe118d..eeeb051e 100644 --- a/src/locales/en-gb.json +++ b/src/locales/en-gb.json @@ -26,6 +26,7 @@ "settings.matomo": "Allow Matomo analytics", "settings.zoom": "Zoom", "settings.disableAnimations": "Disable animations", + "settings.useHumanFriendlyDates": "Use human friendly dates", "drawer.tabs.attributes": "Attributes", "drawer.tabs.filters": "Filters", "drawer.tabs.sorting": "Sorting", diff --git a/src/locales/en.json b/src/locales/en.json index 56fe118d..eeeb051e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -26,6 +26,7 @@ "settings.matomo": "Allow Matomo analytics", "settings.zoom": "Zoom", "settings.disableAnimations": "Disable animations", + "settings.useHumanFriendlyDates": "Use human friendly dates", "drawer.tabs.attributes": "Attributes", "drawer.tabs.filters": "Filters", "drawer.tabs.sorting": "Sorting", diff --git a/src/locales/fr.json b/src/locales/fr.json index 4145df96..86c7db13 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -26,6 +26,7 @@ "settings.matomo": "Autoriser l'analyse Matomo", "settings.zoom": "Zoom", "settings.disableAnimations": "Désactiver les animations", + "settings.useHumanFriendlyDates": "Utiliser des dates conviviales", "drawer.tabs.attributes": "Attributs", "drawer.tabs.filters": "Filtres", "drawer.tabs.sorting": "Tri", diff --git a/src/locales/hi.json b/src/locales/hi.json index 9efbde8d..9bc79049 100644 --- a/src/locales/hi.json +++ b/src/locales/hi.json @@ -26,6 +26,7 @@ "settings.matomo": "मैटोमो विश्लेषण की अनुमति दें", "settings.zoom": "ज़ूम", "settings.disableAnimations": "एनिमेशन अक्षम करें", + "settings.useHumanFriendlyDates": "मानव-मित्रता योग्य तिथियाँ उपयोग करें", "drawer.tabs.attributes": "गुण", "drawer.tabs.filters": "फ़िल्टर", "drawer.tabs.sorting": "क्रमबद्ध करना", diff --git a/src/locales/hu.json b/src/locales/hu.json index 8a247da0..a490561d 100644 --- a/src/locales/hu.json +++ b/src/locales/hu.json @@ -26,6 +26,7 @@ "settings.matomo": "Matomo analitika engedélyezése", "settings.zoom": "Nagyítás", "settings.disableAnimations": "Animációk kikapcsolása", + "settings.useHumanFriendlyDates": "Használjon emberbarát dátumokat", "drawer.tabs.attributes": "Tulajdonságok", "drawer.tabs.filters": "Szűrők", "drawer.tabs.sorting": "Rendezés", diff --git a/src/locales/it.json b/src/locales/it.json index 30e1d893..8902e3a8 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -26,6 +26,7 @@ "settings.matomo": "Consenti analisi Matomo", "settings.zoom": "Zoom", "settings.disableAnimations": "Disattiva animazioni", + "settings.useHumanFriendlyDates": "Usa date user-friendly", "drawer.tabs.attributes": "Attributi", "drawer.tabs.filters": "Filtri", "drawer.tabs.sorting": "Ordinamento", diff --git a/src/locales/jp.json b/src/locales/jp.json index 46a9ab24..b698fe5f 100644 --- a/src/locales/jp.json +++ b/src/locales/jp.json @@ -26,6 +26,7 @@ "settings.matomo": "Matomoアナリティクスを許可する", "settings.zoom": "ズーム", "settings.disableAnimations": "アニメーションを無効にする", + "settings.useHumanFriendlyDates": "使いやすい日付を使用する", "drawer.tabs.attributes": "属性", "drawer.tabs.filters": "フィルター", "drawer.tabs.sorting": "ソート", diff --git a/src/locales/ko.json b/src/locales/ko.json index c45749a3..8971f93d 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -26,6 +26,7 @@ "settings.matomo": "Matomo 분석 허용", "settings.zoom": "줌", "settings.disableAnimations": "애니메이션 비활성화", + "settings.useHumanFriendlyDates": "사용자 친화적인 날짜 사용", "drawer.tabs.attributes": "속성", "drawer.tabs.filters": "필터", "drawer.tabs.sorting": "정렬", diff --git a/src/locales/pl.json b/src/locales/pl.json index 19a4216a..7681a366 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -26,6 +26,7 @@ "settings.matomo": "Zezwalaj na analizy Matomo", "settings.zoom": "Powiększenie", "settings.disableAnimations": "Wyłącz animacje", + "settings.useHumanFriendlyDates": "Używaj przyjaznych dla użytkownika dat", "drawer.tabs.attributes": "Atrybuty", "drawer.tabs.filters": "Filtry", "drawer.tabs.sorting": "Sortowanie", diff --git a/src/locales/pt.json b/src/locales/pt.json index ef864ac9..a6530bba 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -26,6 +26,7 @@ "settings.matomo": "Permitir análise do Matomo", "settings.zoom": "Zoom", "settings.disableAnimations": "Desativar animações", + "settings.useHumanFriendlyDates": "Usar datas amigáveis", "drawer.tabs.attributes": "Atributos", "drawer.tabs.filters": "Filtros", "drawer.tabs.sorting": "Ordenação", diff --git a/src/locales/ru.json b/src/locales/ru.json index 23dbfec0..36c67f28 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -26,6 +26,7 @@ "settings.matomo": "Разрешить аналитику Matomo", "settings.zoom": "Масштаб", "settings.disableAnimations": "Отключить анимации", + "settings.useHumanFriendlyDates": "Использовать удобочитаемые даты", "drawer.tabs.attributes": "Атрибуты", "drawer.tabs.filters": "Фильтры", "drawer.tabs.sorting": "Сортировка", diff --git a/src/locales/tr.json b/src/locales/tr.json index 7b68ae2a..5c81cc56 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -26,6 +26,7 @@ "settings.matomo": "Matomo analitiğine izin ver", "settings.zoom": "Yakınlaştırma", "settings.disableAnimations": "Animasyonları devre dışı bırak", + "settings.useHumanFriendlyDates": "İnsan dostu tarihleri kullan", "drawer.tabs.attributes": "Özellikler", "drawer.tabs.filters": "Filtreler", "drawer.tabs.sorting": "Sıralama", diff --git a/src/locales/zh.json b/src/locales/zh.json index 8bab0a0b..4b0f6cbe 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -26,6 +26,7 @@ "settings.matomo": "允许Matomo分析", "settings.zoom": "缩放", "settings.disableAnimations": "禁用动画", + "settings.useHumanFriendlyDates": "使用人性化日期", "drawer.tabs.attributes": "属性", "drawer.tabs.filters": "过滤器", "drawer.tabs.sorting": "排序", diff --git a/src/main/config.tsx b/src/main/config.tsx index 59db0a65..df742fec 100644 --- a/src/main/config.tsx +++ b/src/main/config.tsx @@ -91,6 +91,11 @@ const config: Store = new Store({ store.set('bulkTodoCreation', false); store.set('disableAnimations', false); }, + '2.0.10': store => { + console.log('Migrating from 2.0.4 → 2.0.10'); + store.set('useHumanFriendlyDates', false); + store.set('excludeLinesWithPrefix', null); + }, } }); @@ -118,14 +123,6 @@ filter.onDidChange('attributes', async () => { } }); -// filter.onDidChange('search', async () => { -// try { -// await processDataRequest(searchString); -// } catch(error: any) { -// console.error(error); -// } -// }); - config.onDidAnyChange(async(settings) => { try { await processDataRequest(searchString); diff --git a/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx b/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx index a7db744c..da5a224b 100644 --- a/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx +++ b/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx @@ -1,5 +1,6 @@ import { app } from 'electron'; import { Item } from 'jstodotxt'; +import { config } from '../../config'; import { handleNotification } from '../Notifications'; import { extractSpeakingDates } from '../Date'; import dayjs from 'dayjs'; @@ -72,13 +73,21 @@ async function createTodoObjects(fileContent: string | null): Promise line.trim() !== ''); - const todoObjects: TodoObject[] = await Promise.all(lines.map((line, i) => { - const todoObject: TodoObject = createTodoObject(i, line); - if(todoObject.body && !todoObject.complete) { + const todoObjects: TodoObject[] = await Promise.all(lines.map(async (line, i) => { + + const excludeLinesWithPrefix: string = config.get('excludeLinesWithPrefix'); + if (line.startsWith(excludeLinesWithPrefix)) { + return null; + } + + const todoObject: TodoObject = await createTodoObject(i, line); + + if (todoObject.body && !todoObject.complete) { handleNotification(todoObject.due, todoObject.body, badge); } + return todoObject; - })); + })).then((objects) => objects.filter(Boolean) as TodoObject[]); app.setBadgeCount(badge.count); diff --git a/src/renderer/Drawer/Attributes.tsx b/src/renderer/Drawer/Attributes.tsx index 080737b3..76ee65ae 100644 --- a/src/renderer/Drawer/Attributes.tsx +++ b/src/renderer/Drawer/Attributes.tsx @@ -10,6 +10,9 @@ import AirIcon from '@mui/icons-material/Air'; import { handleFilterSelect } from '../Shared'; import { withTranslation, WithTranslation } from 'react-i18next'; import { i18n } from '../Settings/LanguageSelector'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; +import duration from 'dayjs/plugin/duration'; import './Attributes.scss'; const { store } = window.api; @@ -33,6 +36,12 @@ const DrawerAttributes: React.FC = memo(({ const firstTabbableElementRef = useRef(null); const [hovered, setHovered] = useState(null); + if(settings.useHumanFriendlyDates) { + dayjs.locale(settings.language); + dayjs.extend(relativeTime); + dayjs.extend(duration); + } + const isAttributesEmpty = (attributes: Attributes | null) => { return !attributes || Object.values(attributes).every((attribute) => !Object.keys(attribute).length); }; @@ -77,6 +86,7 @@ const DrawerAttributes: React.FC = memo(({ const selected = filters && filters[key]?.some((filter: any) => filter.value === value); const disabled = attributes[key][value].count === 0 || !attributes[key][value].visible; const notify = (key === 'due') ? attributes[key][value].notify : false; + const friendlyDate = settings.useHumanFriendlyDates && dayjs(value).isValid() ? dayjs(value).fromNow() : null; return (
= memo(({ } disabled={disabled} > - {value} + {(friendlyDate) ? friendlyDate : value} {(excluded) && ( @@ -132,7 +142,6 @@ const DrawerAttributes: React.FC = memo(({
); })} - ) : null diff --git a/src/renderer/Grid/DatePickerInline.tsx b/src/renderer/Grid/DatePickerInline.tsx index 5f786d31..c579efda 100644 --- a/src/renderer/Grid/DatePickerInline.tsx +++ b/src/renderer/Grid/DatePickerInline.tsx @@ -6,6 +6,8 @@ import Chip from '@mui/material/Chip'; import Badge from '@mui/material/Badge'; import { handleFilterSelect } from '../Shared'; import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; +import duration from 'dayjs/plugin/duration'; const { ipcRenderer } = window.api; @@ -27,6 +29,12 @@ const DatePickerInline: React.FC = ({ const [open, setOpen] = useState(false); const chipText = type === 'due' ? "due:" : type === 't' ? "t:" : null; + if(settings.useHumanFriendlyDates) { + dayjs.locale(settings.language); + dayjs.extend(relativeTime); + dayjs.extend(duration); + } + const handleChange = (date: dayjs.Dayjs | null) => { try { ipcRenderer.send('writeTodoToFile', todoObject.id, todoObject.string, false, type, dayjs(date).format('YYYY-MM-DD')); @@ -51,6 +59,7 @@ const DatePickerInline: React.FC = ({ const ButtonField = ({ ...props }) => { const { disabled, InputProps: { ref } = {}, inputProps: { 'aria-label': ariaLabel } = {} } = props; const mustNotify = (type === 'due') ? !todoObject?.notify : true; + const friendlyDate = settings.useHumanFriendlyDates ? dayjs(date).fromNow() : null; return ( diff --git a/src/renderer/Grid/Renderer.tsx b/src/renderer/Grid/Renderer.tsx index d9f38896..e52e281c 100644 --- a/src/renderer/Grid/Renderer.tsx +++ b/src/renderer/Grid/Renderer.tsx @@ -4,6 +4,7 @@ import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm' import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; +import Tooltip from '@mui/material/Tooltip'; import { ReactComponent as TomatoIconDuo } from '../../../assets/icons/tomato-duo.svg'; import DatePickerInline from './DatePickerInline'; import OpenInNewIcon from '@mui/icons-material/OpenInNew'; @@ -90,15 +91,21 @@ const RendererComponent = ({ todoObject, filters, settings, handleButtonClick }) return modifiedChildren; }, a: ({ children, href }) => { - const match = /([a-zA-Z]+:\/\/\S+)/g.exec(children); - if (match) { - return ( - handleLinkClick(event, children)}> - {children} - - ); - } - return handleLinkClick(event, href)}>{children}; + const match = /([a-zA-Z]+:\/\/\S+)/g.exec(children); + const maxChars = 40; + const truncatedChildren = children.length > maxChars ? children.slice(0, maxChars) + '...' : children; + + const link = ( + handleLinkClick(event, match ? children : href)}> + {truncatedChildren} + + ); + + return children.length > maxChars ? ( + + {link} + + ) : link; }, }; diff --git a/src/renderer/Settings/Settings.tsx b/src/renderer/Settings/Settings.tsx index 9f76eebd..ce1c39a2 100644 --- a/src/renderer/Settings/Settings.tsx +++ b/src/renderer/Settings/Settings.tsx @@ -38,6 +38,9 @@ const visibleSettings: VisibleSettings = { disableAnimations: { style: 'toggle', }, + useHumanFriendlyDates: { + style: 'toggle', + }, notificationsAllowed: { style: 'toggle', }, diff --git a/src/renderer/index.ejs b/src/renderer/index.ejs index 4812f5af..d16229b3 100644 --- a/src/renderer/index.ejs +++ b/src/renderer/index.ejs @@ -4,7 +4,7 @@ sleek