release 4.9.0

This commit is contained in:
callumalpass 2026-05-24 09:35:31 +10:00
parent 1d127a34d0
commit f45993f476
26 changed files with 488 additions and 101 deletions

View file

@ -6,6 +6,7 @@ Welcome to the TaskNotes release notes. Here you can find detailed information a
### Version 4.x (Current)
- [4.9.0](releases/4.9.0.md)
- [4.8.1](releases/4.8.1.md)
- [4.8.0](releases/4.8.0.md)
- [4.7.2](releases/4.7.2.md)

41
docs/releases/4.9.0.md Normal file
View file

@ -0,0 +1,41 @@
# TaskNotes 4.9.0
## Security
- (#1923) Restricted the HTTP API server to loopback and limited browser CORS access to loopback origins.
- Thanks to @martin-forge for reporting.
## Added
- (#1932) Added middle-click support for opening task cards in a new tab.
- Thanks to @imsuck for the request.
## Fixed
- (#1934) Fixed custom priority colors being overridden by default task-card priority styles in views.
- Thanks to @KittehBit for reporting.
- (#1933) Added the note path to fallback frontmatter parse warnings so malformed task YAML is easier to find.
- Thanks to @rayvermey for reporting.
- (#1931) Made the Pomodoro task chooser open from cached task data and ignore repeated clicks while it is already opening.
- Thanks to @sumiyalairu03 for reporting.
- (#1930) Fixed starting the Pomodoro timer from its hotkey without starting time tracking for the selected Pomodoro task.
- Thanks to @sumiyalairu03 for reporting.
- (#1929) Fixed the bottom Relationships widget overlapping embedded content such as Bases/Kanban views in task notes.
- Thanks to @rchaklashiya for reporting and following up with the embed case.
- (#1922) Restored the native color picker alongside manual color text entry in Create/Edit Timeblock fields.
- Thanks to @AndreMonthy for reporting.
- (#1921) Fixed direct frontmatter edits to lifecycle-relevant task fields not triggering Google Calendar sync or auto-archive side effects.
- Thanks to @martin-forge for reporting and verifying the direct-edit reproduction.
- (#1919) Fixed the Pomodoro view rapidly resizing at certain sidebar sizes.
- Thanks to @RumiaKitinari for reporting.
- (#1898, #1907) Fixed Calendar time labels shifting into the middle of Day and sidebar calendar grids after switching views.
- Thanks to @ddevaal for reporting and confirming the regression, and to @kmaustral for confirming the sidebar case in 4.8.1.
- (#1936) Added a Calendar Base drag/drop resolution option so events can snap to smaller increments than the visible time slot grid.
- Thanks to @benmartinek for suggesting this.
- Improved mobile task cards, inline widgets, modals, and settings layouts so dense controls and long labels fit more comfortably on small screens.
- (#1916) Fixed Markdown task links using Obsidian's generated filename label instead of the TaskNote title in the task link overlay.
- Thanks to @minchinweb for reporting.
- (#1911) Fixed recurrence choices starting from today instead of the selected calendar date when creating a task from Calendar view.
- Thanks to @mikhailmarka for reporting.
- (#1912) Fixed "Create subtask" pre-filling the parent task's full folder path in the Projects field instead of using the normal Obsidian link text.
- Thanks to @pkuehne for reporting and @benmartinek for confirming.

View file

@ -23,42 +23,3 @@ Example:
```
-->
## Security
- (#1923) Restricted the HTTP API server to loopback and limited browser CORS access to loopback origins.
- Thanks to @martin-forge for reporting.
## Added
- (#1932) Added middle-click support for opening task cards in a new tab.
- Thanks to @imsuck for the request.
## Fixed
- (#1934) Fixed custom priority colors being overridden by default task-card priority styles in views.
- Thanks to @KittehBit for reporting.
- (#1933) Added the note path to fallback frontmatter parse warnings so malformed task YAML is easier to find.
- Thanks to @rayvermey for reporting.
- (#1931) Made the Pomodoro task chooser open from cached task data and ignore repeated clicks while it is already opening.
- Thanks to @sumiyalairu03 for reporting.
- (#1930) Fixed starting the Pomodoro timer from its hotkey without starting time tracking for the selected Pomodoro task.
- Thanks to @sumiyalairu03 for reporting.
- (#1929) Fixed the bottom Relationships widget overlapping embedded content such as Bases/Kanban views in task notes.
- Thanks to @rchaklashiya for reporting and following up with the embed case.
- (#1922) Restored the native color picker alongside manual color text entry in Create/Edit Timeblock fields.
- Thanks to @AndreMonthy for reporting.
- (#1921) Fixed direct frontmatter edits to lifecycle-relevant task fields not triggering Google Calendar sync or auto-archive side effects.
- Thanks to @martin-forge for reporting and verifying the direct-edit reproduction.
- (#1919) Fixed the Pomodoro view rapidly resizing at certain sidebar sizes.
- Thanks to @RumiaKitinari for reporting.
- (#1898) Fixed Calendar Day view time labels shifting into the middle of the grid after switching views.
- Thanks to @ddevaal for reporting and confirming the regression.
- (#1936) Added a Calendar Base drag/drop resolution option so events can snap to smaller increments than the visible time slot grid.
- Thanks to @benmartinek for suggesting this.
- (#1916) Fixed Markdown task links using Obsidian's generated filename label instead of the TaskNote title in the task link overlay.
- Thanks to @minchinweb for reporting.
- (#1911) Fixed recurrence choices starting from today instead of the selected calendar date when creating a task from Calendar view.
- Thanks to @mikhailmarka for reporting.
- (#1912) Fixed "Create subtask" pre-filling the parent task's full folder path in the Projects field instead of using the normal Obsidian link text.
- Thanks to @pkuehne for reporting.

View file

@ -179,6 +179,8 @@
"views.basesCalendar.settings.layout.dayEndTimePlaceholder": "0133cae380a25a9edd58d66259a3164cfb8f475e",
"views.basesCalendar.settings.layout.timeSlotDuration": "29f4bf4e4e79c36f8416b3785304f0a28bf6d1ca",
"views.basesCalendar.settings.layout.timeSlotDurationPlaceholder": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"views.basesCalendar.settings.layout.dragDropResolution": "10bae1b83a90069958aeb5e093500223c0719848",
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"views.basesCalendar.settings.layout.weekStartsOn": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"views.basesCalendar.settings.layout.showWeekNumbers": "181797ee5c8edfd86e0166c5012159efdebefee8",
"views.basesCalendar.settings.layout.showNowIndicator": "80bc9e34e9d741ed65ca981c5371f2598870dad8",

View file

@ -720,6 +720,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "b4bbf64dc40534031d82ceb781e7b201e91f68a3"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "c6628f51cebbe1f9be67312022133109c3dd006b"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "7c1c1d81cea7e2e99e17e9f2f47993cf394a3e44"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "c8d224c187903f6721d87209ff3dd3b39a564ecf"
@ -9466,6 +9474,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "84ed6d9e5a3898b4f62d998df68e77624024a797"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "f893179e3146bfae4d8eeea2e4f3710d5b7b5d13"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "22ff72915931f0fa3b045d19295d2d159d0c10bb"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "f4f87c3bb9b4dee13dcdb36ba47ada815c5c840b"
@ -18212,6 +18228,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "f91b444cf92bd0a247a23d6e7d846893676f1efc"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "0ecf86f1a4bacc9053daea31ab9258fd00b2c622"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "36428c14bae6164415659d6a19bd57c9d9580c7e"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "a42d4d52511f97f3946357564da09ba5b9994fb2"
@ -26958,6 +26982,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "11ef7c65a18066af074d8c55613a6a6ff8bc9dbb"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "ca04d38b6f5c4c6b332caa4de6fed81bff845d82"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "413ecfc29e7bff421553e7d6f25665e2ce91bd26"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "bb898d111a5f23ca0cba5dde06064862180fbe80"
@ -35704,6 +35736,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "616865e7b3296dfd2bdb6c6966443f42489d4f73"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "3201b2813062ec065f0f6bea5b93b1a922186ba2"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "c501a5868b1fa3600c551b98db57ad928bf62c15"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "9cc0d3755aa858490230b50cd4c74bf82f718259"
@ -44450,6 +44490,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "99332bae87308c3ce447a78af64c00e2a8b1b8ba"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "6594e906e5d044d74cda586ff5e3597014a90715"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "d03571b31304d80326705349f5a6d061fbeb4813"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "fb33758b0a0a69af8b1f687b3880a7f0ca7986b9"
@ -53196,6 +53244,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "f523d5d23e814daa0c269a9a0c1cff38fb16560d"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "06ef6c342fddeec7341f6fd6c9874652f2004491"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "42237fd5473f5e8a2107a665e51078afc10807a2"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "ef0a6f46cc55b10e8e9c2e9f51724b2867beaf58"
@ -61942,6 +61998,14 @@
"source": "42dcf2fde11e354fe96a959abe2424d9339a8589",
"translation": "fd33b47fedea685a26f4f3b27a7fccf19a0d919d"
},
"views.basesCalendar.settings.layout.dragDropResolution": {
"source": "10bae1b83a90069958aeb5e093500223c0719848",
"translation": "f868576e3459e313ed790332927c45f71515b77a"
},
"views.basesCalendar.settings.layout.dragDropResolutionPlaceholder": {
"source": "3767ff7d284933429f9cb625c21bc84b7ce51780",
"translation": "9660ecf6c7af9b968f34d41b6165767ebf648046"
},
"views.basesCalendar.settings.layout.weekStartsOn": {
"source": "c5ee02903b18157906dd2123eb7caaecc6881b5a",
"translation": "a3088924e1da30ccbee011791ef7101e20016d9a"

View file

@ -1,10 +1,10 @@
{
"id": "tasknotes",
"name": "TaskNotes",
"version": "4.8.1",
"version": "4.9.0",
"minAppVersion": "1.12.2",
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
"author": "Callum Alpass",
"authorUrl": "https://github.com/callumalpass",
"isDesktopOnly": false
}
}

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "tasknotes",
"version": "4.8.1",
"version": "4.9.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "tasknotes",
"version": "4.8.1",
"version": "4.9.0",
"license": "MIT",
"dependencies": {
"@codemirror/view": "^6.38.6",

View file

@ -1,6 +1,6 @@
{
"name": "tasknotes",
"version": "4.8.1",
"version": "4.9.0",
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
"main": "main.js",
"scripts": {

View file

@ -248,6 +248,8 @@ export const de: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss (z.B. 20:00:00)",
timeSlotDuration: "Zeitschlitzdauer",
timeSlotDurationPlaceholder: "HH:mm:ss (z.B. 00:30:00)",
dragDropResolution: "Auflösung für Ziehen/Ablegen",
dragDropResolutionPlaceholder: "HH:mm:ss (z.B. 00:05:00)",
weekStartsOn: "Woche beginnt am",
showWeekNumbers: "Wochennummern anzeigen",
showNowIndicator: "Jetzt-Indikator anzeigen",

View file

@ -248,6 +248,8 @@ export const es: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss (ej. 20:00:00)",
timeSlotDuration: "Duración del intervalo de tiempo",
timeSlotDurationPlaceholder: "HH:mm:ss (ej. 00:30:00)",
dragDropResolution: "Resolución de arrastrar y soltar",
dragDropResolutionPlaceholder: "HH:mm:ss (ej. 00:05:00)",
weekStartsOn: "La semana comienza el",
showWeekNumbers: "Mostrar números de semana",
showNowIndicator: "Mostrar indicador actual",

View file

@ -248,6 +248,8 @@ export const fr: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss (ex. 20:00:00)",
timeSlotDuration: "Durée de la plage horaire",
timeSlotDurationPlaceholder: "HH:mm:ss (ex. 00:30:00)",
dragDropResolution: "Résolution du glisser-déposer",
dragDropResolutionPlaceholder: "HH:mm:ss (ex. 00:05:00)",
weekStartsOn: "La semaine commence le",
showWeekNumbers: "Afficher les numéros de semaine",
showNowIndicator: "Afficher l'indicateur actuel",

View file

@ -248,6 +248,8 @@ export const ja: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss20:00:00",
timeSlotDuration: "タイムスロット期間",
timeSlotDurationPlaceholder: "HH:mm:ss00:30:00",
dragDropResolution: "ドラッグ/ドロップ間隔",
dragDropResolutionPlaceholder: "HH:mm:ss00:05:00",
weekStartsOn: "週の開始曜日",
showWeekNumbers: "週番号を表示",
showNowIndicator: "現在の時刻インジケータを表示",

View file

@ -248,6 +248,8 @@ export const ko: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss (예: 20:00:00)",
timeSlotDuration: "시간 슬롯 간격",
timeSlotDurationPlaceholder: "HH:mm:ss (예: 00:30:00)",
dragDropResolution: "드래그/드롭 간격",
dragDropResolutionPlaceholder: "HH:mm:ss (예: 00:05:00)",
weekStartsOn: "주 시작 요일",
showWeekNumbers: "주 번호 표시",
showNowIndicator: "현재 시간 표시",

View file

@ -248,6 +248,8 @@ export const pt: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss (ex: 20:00:00)",
timeSlotDuration: "Duração do slot de tempo",
timeSlotDurationPlaceholder: "HH:mm:ss (ex: 00:30:00)",
dragDropResolution: "Resolução de arrastar/soltar",
dragDropResolutionPlaceholder: "HH:mm:ss (ex: 00:05:00)",
weekStartsOn: "A semana começa em",
showWeekNumbers: "Mostrar números da semana",
showNowIndicator: "Mostrar indicador 'agora'",

View file

@ -248,6 +248,8 @@ export const ru: TranslationTree = {
dayEndTimePlaceholder: "ЧЧ:мм:сс (например, 20:00:00)",
timeSlotDuration: "Длительность временного слота",
timeSlotDurationPlaceholder: "ЧЧ:мм:сс (например, 00:30:00)",
dragDropResolution: "Шаг перетаскивания",
dragDropResolutionPlaceholder: "ЧЧ:мм:сс (например, 00:05:00)",
weekStartsOn: "Неделя начинается с",
showWeekNumbers: "Показать номера недель",
showNowIndicator: "Показать индикатор текущего времени",

View file

@ -248,6 +248,8 @@ export const zh: TranslationTree = {
dayEndTimePlaceholder: "HH:mm:ss例如20:00:00",
timeSlotDuration: "时间段持续时间",
timeSlotDurationPlaceholder: "HH:mm:ss例如00:30:00",
dragDropResolution: "拖放时间粒度",
dragDropResolutionPlaceholder: "HH:mm:ss例如00:05:00",
weekStartsOn: "一周开始于",
showWeekNumbers: "显示周数",
showNowIndicator: "显示当前时间指示器",

View file

@ -79,7 +79,7 @@ export class CalendarEventCreationModal extends Modal {
onOpen() {
const { contentEl } = this;
contentEl.empty();
contentEl.addClass("calendar-event-creation-modal");
contentEl.addClass("tasknotes-plugin", "calendar-event-creation-modal");
// Global Ctrl/Cmd+Enter shortcut
this.keyboardHandler = (e: KeyboardEvent) => {

View file

@ -341,6 +341,53 @@ body.is-mobile .timeblock-info-modal input.tasknotes-theme-color-picker {
max-width: 2.25rem;
}
body.is-mobile .timeblock-creation-modal .setting-item,
body.is-mobile .timeblock-info-modal .setting-item,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal .setting-item {
align-items: stretch;
flex-direction: column;
gap: var(--size-4-2);
}
body.is-mobile .timeblock-creation-modal .setting-item-control,
body.is-mobile .timeblock-info-modal .setting-item-control,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal .setting-item-control {
justify-content: flex-start;
width: 100%;
}
body.is-mobile .timeblock-creation-modal input,
body.is-mobile .timeblock-creation-modal textarea,
body.is-mobile .timeblock-info-modal input,
body.is-mobile .timeblock-info-modal textarea,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal input,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal textarea,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal select {
width: 100%;
}
body.is-mobile .timeblock-modal-buttons,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal .calendar-event-modal-buttons {
flex-direction: column;
}
body.is-mobile .timeblock-modal-buttons button,
body.is-mobile .tasknotes-plugin.calendar-event-creation-modal .calendar-event-modal-buttons button {
width: 100%;
}
body.is-mobile .timeblock-modal-buttons-right {
display: flex;
flex-direction: column;
gap: 0.5rem;
width: 100%;
}
body.is-mobile .timeblock-attachment-remove {
width: 32px;
height: 32px;
}
/* Attachment Suggestion Modal Styles */
.attachment-suggestion {
padding: 0.5rem;

View file

@ -37,6 +37,7 @@
color: var(--interactive-accent);
display: block;
margin-bottom: var(--size-4-1);
overflow-wrap: anywhere;
}
.tasknotes-plugin .reminder-modal__task-dates {
@ -462,6 +463,13 @@ body.is-mobile .tasknotes-plugin .reminder-modal__action-btn svg {
min-height: 60vh;
max-height: 90vh;
}
.tasknotes-plugin .reminder-modal__header,
.tasknotes-plugin .reminder-modal__content,
.tasknotes-plugin .reminder-modal__actions {
padding-left: var(--size-4-3);
padding-right: var(--size-4-3);
}
.tasknotes-plugin .reminder-modal__quick-buttons {
flex-wrap: wrap;

View file

@ -110,6 +110,10 @@
.tasknotes-plugin .settings-header {
justify-content: flex-start;
}
.tasknotes-plugin .settings-view__tab-nav {
width: 100%;
}
}
/* ================================================
@ -311,6 +315,61 @@ input.tasknotes-theme-color-picker {
cursor: var(--cursor-link, pointer);
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__card-config-row {
align-items: stretch;
flex-direction: column;
gap: var(--tn-spacing-xs);
min-width: 0;
width: 100%;
max-width: 100%;
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__nested-content,
body.is-mobile .tasknotes-plugin .tasknotes-settings__nested-cards,
body.is-mobile .tasknotes-plugin .tasknotes-settings__collapsible-section-content {
min-width: 0;
width: 100%;
max-width: 100%;
}
body.is-mobile .tasknotes-plugin .field-manager,
body.is-mobile .tasknotes-plugin .field-manager__content,
body.is-mobile .tasknotes-plugin .field-manager__cards {
min-width: 0;
max-width: 100%;
}
body.is-mobile .tasknotes-plugin .field-manager__tabs {
max-width: 100%;
overflow-x: auto;
scrollbar-width: thin;
}
body.is-mobile .tasknotes-plugin .field-manager__tab {
flex: 0 0 auto;
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__card-config-label {
min-width: 0;
width: 100%;
margin-right: 0;
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__card-input:not([type="checkbox"]):not([type="color"]) {
min-width: 0;
width: 100%;
max-width: 100%;
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__card-actions {
flex-direction: column;
}
body.is-mobile .tasknotes-plugin .tasknotes-settings__card-action-btn {
justify-content: center;
width: 100%;
}
/* Card Actions */
.tasknotes-settings__card-actions {
padding: 12px 16px;

View file

@ -351,6 +351,8 @@ body.is-mobile .tasknotes-plugin .task-card.task-card--drag-handle-only .task-ca
}
body.is-mobile .tasknotes-plugin .task-card.task-card--drag-handle-only .task-card__drag-handle {
top: var(--tn-spacing-sm);
transform: none;
width: 32px;
height: 32px;
opacity: 0.85;
@ -835,8 +837,8 @@ body.is-mobile .tasknotes-plugin .task-card.task-card--chevron-left .task-card__
}
body.is-mobile .tasknotes-plugin .task-card__context-menu {
min-width: 36px;
min-height: 36px;
min-width: var(--tn-mobile-task-card-menu-size);
min-height: var(--tn-mobile-task-card-menu-size);
opacity: 1;
}
@ -1084,42 +1086,42 @@ body.is-mobile .tasknotes-plugin .task-card__context-menu svg {
/* Mobile & Touch Devices - Use theme colors */
@media (pointer: coarse) {
.tasknotes-plugin .task-card {
body:not(.is-mobile) .tasknotes-plugin .task-card {
padding: 12px 16px;
min-height: 44px;
margin-bottom: 2px;
}
.tasknotes-plugin .task-card:active {
body:not(.is-mobile) .tasknotes-plugin .task-card:active {
background-color: var(--tn-interactive-hover);
}
/* Larger touch targets */
.tasknotes-plugin .task-card__context-menu {
body:not(.is-mobile) .tasknotes-plugin .task-card__context-menu {
min-width: 36px;
min-height: 36px;
opacity: 1;
}
.tasknotes-plugin .task-card__context-menu svg {
body:not(.is-mobile) .tasknotes-plugin .task-card__context-menu svg {
width: 16px;
height: 16px;
}
/* Larger status dots for touch */
.tasknotes-plugin .task-card__status-dot {
body:not(.is-mobile) .tasknotes-plugin .task-card__status-dot {
width: 36px;
height: 36px;
}
.tasknotes-plugin .task-card__priority-dot,
.tasknotes-plugin .task-card__recurring-indicator,
.tasknotes-plugin .task-card__reminder-indicator,
.tasknotes-plugin .task-card__details-indicator,
.tasknotes-plugin .task-card__project-indicator,
.tasknotes-plugin .task-card__chevron,
.tasknotes-plugin .task-card__blocking-toggle,
.tasknotes-plugin .task-card__blocked-toggle {
body:not(.is-mobile) .tasknotes-plugin .task-card__priority-dot,
body:not(.is-mobile) .tasknotes-plugin .task-card__recurring-indicator,
body:not(.is-mobile) .tasknotes-plugin .task-card__reminder-indicator,
body:not(.is-mobile) .tasknotes-plugin .task-card__details-indicator,
body:not(.is-mobile) .tasknotes-plugin .task-card__project-indicator,
body:not(.is-mobile) .tasknotes-plugin .task-card__chevron,
body:not(.is-mobile) .tasknotes-plugin .task-card__blocking-toggle,
body:not(.is-mobile) .tasknotes-plugin .task-card__blocked-toggle {
min-width: 36px;
min-height: 36px;
display: inline-flex;
@ -1128,6 +1130,109 @@ body.is-mobile .tasknotes-plugin .task-card__context-menu svg {
}
}
/* Obsidian mobile cards need compact controls; secondary badges wrap below so
narrow cards keep enough room for the task title and metadata. */
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) {
padding: var(--tn-spacing-sm) var(--tn-spacing-md);
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__main-row {
align-items: center;
flex-wrap: wrap;
gap: var(--tn-spacing-xs);
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__content {
padding-top: 0;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__status-dot {
width: var(--tn-mobile-task-card-indicator-size);
height: var(--tn-mobile-task-card-indicator-size);
min-width: var(--tn-mobile-task-card-indicator-size);
min-height: var(--tn-mobile-task-card-indicator-size);
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__status-dot--icon svg {
width: 18px;
height: 18px;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__priority-dot {
width: var(--tn-mobile-task-card-indicator-size);
height: var(--tn-mobile-task-card-indicator-size);
min-width: var(--tn-mobile-task-card-indicator-size);
min-height: var(--tn-mobile-task-card-indicator-size);
margin: 0;
padding: var(--tn-mobile-task-card-dot-padding);
box-sizing: border-box;
background-clip: content-box;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__priority-dot--icon {
padding: 3px;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__priority-dot--icon svg {
width: 18px;
height: 18px;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__badges {
order: 2;
flex: 1 0 100%;
gap: 2px;
padding-left: calc(var(--tn-mobile-task-card-indicator-size) + var(--tn-spacing-xs));
box-sizing: border-box;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .task-card__metadata-property--projects {
flex-wrap: wrap;
overflow-wrap: anywhere;
white-space: normal;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .task-card__metadata-property--contexts,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .task-card__metadata-value {
flex-wrap: wrap;
overflow-wrap: anywhere;
white-space: normal;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .task-card__project-link {
max-width: 100%;
overflow-wrap: anywhere;
white-space: normal;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .context-tag,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline) .tag {
max-width: 100%;
overflow-wrap: anywhere;
white-space: normal;
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__recurring-indicator,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__reminder-indicator,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__details-indicator,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__project-indicator,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__blocking-toggle,
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__blocked-toggle {
width: var(--tn-mobile-task-card-indicator-size);
height: var(--tn-mobile-task-card-indicator-size);
min-width: var(--tn-mobile-task-card-indicator-size);
min-height: var(--tn-mobile-task-card-indicator-size);
}
body.is-mobile .tasknotes-plugin .task-card:not(.task-card--layout-inline):not(.task-card--layout-compact) .task-card__context-menu {
order: 1;
margin-left: auto;
width: var(--tn-mobile-task-card-menu-size);
height: var(--tn-mobile-task-card-menu-size);
min-width: var(--tn-mobile-task-card-menu-size);
min-height: var(--tn-mobile-task-card-menu-size);
}
/* High density displays */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.tasknotes-plugin .task-card {
@ -1468,7 +1573,7 @@ body.is-mobile .tasknotes-plugin .task-card__context-menu svg {
body.is-mobile .tasknotes-plugin .task-card--layout-inline {
display: inline-flex;
align-items: center;
gap: 0.35em;
gap: 0.25em;
max-width: 100%;
white-space: normal;
vertical-align: middle;
@ -1482,6 +1587,11 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__content {
vertical-align: middle;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__content {
flex-direction: row;
gap: 0.25em;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__title,
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__title-text {
min-width: 0;
@ -1493,61 +1603,65 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__title-tex
max-width: min(42vw, 18em);
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__metadata {
display: none;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__status-dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
width: var(--tn-mobile-inline-indicator-size);
height: var(--tn-mobile-inline-indicator-size);
margin-right: 0;
transform: none;
flex: 0 0 28px;
flex: 0 0 var(--tn-mobile-inline-indicator-size);
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
min-width: 28px;
min-height: 28px;
width: var(--tn-mobile-inline-indicator-size);
height: var(--tn-mobile-inline-indicator-size);
min-width: var(--tn-mobile-inline-indicator-size);
min-height: var(--tn-mobile-inline-indicator-size);
margin: 0;
padding: 8px;
padding: 5px;
box-sizing: border-box;
background-clip: content-box;
transform: none;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon {
padding: 4px;
padding: 2px;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon svg {
width: 20px;
height: 20px;
width: 16px;
height: 16px;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-menu {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
min-width: 32px;
min-height: 32px;
width: var(--tn-mobile-inline-menu-size);
height: var(--tn-mobile-inline-menu-size);
min-width: var(--tn-mobile-inline-menu-size);
min-height: var(--tn-mobile-inline-menu-size);
margin-left: 0.1em;
opacity: 1;
vertical-align: middle;
}
body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-menu svg {
width: 18px;
height: 18px;
width: 16px;
height: 16px;
}
@media (pointer: coarse) {
.tasknotes-plugin .task-card--layout-inline {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline {
display: inline-flex;
align-items: center;
gap: 0.35em;
@ -1556,26 +1670,26 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-m
vertical-align: middle;
}
.tasknotes-plugin .task-card--layout-inline .task-card__main-row,
.tasknotes-plugin .task-card--layout-inline .task-card__content {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__main-row,
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__content {
display: inline-flex;
align-items: center;
min-width: 0;
vertical-align: middle;
}
.tasknotes-plugin .task-card--layout-inline .task-card__title,
.tasknotes-plugin .task-card--layout-inline .task-card__title-text {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__title,
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__title-text {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.tasknotes-plugin .task-card--layout-inline .task-card__title-text {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__title-text {
max-width: min(42vw, 18em);
}
.tasknotes-plugin .task-card--layout-inline .task-card__status-dot {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__status-dot {
display: inline-flex;
align-items: center;
justify-content: center;
@ -1586,7 +1700,7 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-m
flex: 0 0 28px;
}
.tasknotes-plugin .task-card--layout-inline .task-card__priority-dot {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot {
display: inline-flex;
align-items: center;
justify-content: center;
@ -1601,16 +1715,16 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-m
transform: none;
}
.tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon {
padding: 4px;
}
.tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon svg {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__priority-dot--icon svg {
width: 20px;
height: 20px;
}
.tasknotes-plugin .task-card--layout-inline .task-card__context-menu {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__context-menu {
display: inline-flex;
align-items: center;
justify-content: center;
@ -1623,7 +1737,7 @@ body.is-mobile .tasknotes-plugin .task-card--layout-inline .task-card__context-m
vertical-align: middle;
}
.tasknotes-plugin .task-card--layout-inline .task-card__context-menu svg {
body:not(.is-mobile) .tasknotes-plugin .task-card--layout-inline .task-card__context-menu svg {
width: 18px;
height: 18px;
}

View file

@ -805,6 +805,21 @@ body.is-mobile .modal.mod-tasknotes .tn-task-modal__button-bar .tn-task-modal__o
grid-column: 1 / -1;
}
body.is-mobile .tasknotes-plugin .task-project-remove {
width: 32px;
height: 32px;
min-width: 32px;
min-height: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
margin-left: var(--size-4-1);
}
body.is-mobile .tasknotes-plugin .task-project-item--task-card .task-project-remove {
margin-top: var(--size-4-1);
}
/* =====================================================================
SPLIT LAYOUT - BASE STYLES (mobile/narrow screens)
On narrow screens, content flows vertically with details below title

View file

@ -269,6 +269,11 @@
width: 90vw;
}
.time-entry-editor-modal .modal-title {
white-space: normal;
overflow-wrap: anywhere;
}
.time-entry-editor-modal__footer {
flex-direction: column;
align-items: flex-start;

View file

@ -387,4 +387,9 @@
body.is-mobile .tasknotes-plugin {
--tn-nested-task-indent: 12px;
--tn-nested-task-padding: 10px;
--tn-mobile-task-card-indicator-size: 24px;
--tn-mobile-task-card-menu-size: 32px;
--tn-mobile-task-card-dot-padding: 6px;
--tn-mobile-inline-indicator-size: 20px;
--tn-mobile-inline-menu-size: 24px;
}

View file

@ -8,29 +8,77 @@ function readRepoFile(relativePath: string): string {
}
describe("Issue #190: mobile task widget touch targets", () => {
it("keeps task-card action controls visible and larger on Obsidian mobile", () => {
it("keeps Obsidian mobile task-card controls compact on narrow screens", () => {
const variablesCss = readRepoFile("styles/variables.css");
const css = readRepoFile("styles/task-card-bem.css");
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card__context-menu\s*\{[^}]*min-width:\s*36px;[^}]*min-height:\s*36px;[^}]*opacity:\s*1;/s
expect(variablesCss).toMatch(
/body\.is-mobile \.tasknotes-plugin\s*\{[^}]*--tn-mobile-task-card-indicator-size:\s*24px;[^}]*--tn-mobile-task-card-menu-size:\s*32px;[^}]*--tn-mobile-inline-indicator-size:\s*20px;[^}]*--tn-mobile-inline-menu-size:\s*24px;/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__priority-dot\s*\{[^}]*width:\s*28px;[^}]*height:\s*28px;[^}]*background-clip:\s*content-box;/s
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\):not\(\.task-card--layout-compact\) \.task-card__main-row\s*\{[^}]*align-items:\s*center;[^}]*flex-wrap:\s*wrap;/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__context-menu\s*\{[^}]*width:\s*32px;[^}]*height:\s*32px;[^}]*opacity:\s*1;/s
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\):not\(\.task-card--layout-compact\) \.task-card__status-dot\s*\{[^}]*width:\s*var\(--tn-mobile-task-card-indicator-size\);[^}]*height:\s*var\(--tn-mobile-task-card-indicator-size\);/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\):not\(\.task-card--layout-compact\) \.task-card__priority-dot\s*\{[^}]*width:\s*var\(--tn-mobile-task-card-indicator-size\);[^}]*padding:\s*var\(--tn-mobile-task-card-dot-padding\);[^}]*background-clip:\s*content-box;/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\):not\(\.task-card--layout-compact\) \.task-card__context-menu\s*\{[^}]*width:\s*var\(--tn-mobile-task-card-menu-size\);[^}]*height:\s*var\(--tn-mobile-task-card-menu-size\);/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\):not\(\.task-card--layout-compact\) \.task-card__badges\s*\{[^}]*order:\s*2;[^}]*flex:\s*1 0 100%;/s
);
});
it("applies the same inline task-link hardening on coarse pointer devices", () => {
it("uses smaller inline widgets on Obsidian mobile without changing touch-capable desktop rules", () => {
const css = readRepoFile("styles/task-card-bem.css");
expect(css).toContain("@media (pointer: coarse)");
expect(css).toMatch(
/@media \(pointer: coarse\)\s*\{[\s\S]*\.tasknotes-plugin \.task-card--layout-inline \.task-card__priority-dot\s*\{[^}]*width:\s*28px;[^}]*height:\s*28px;[^}]*background-clip:\s*content-box;/s
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__content\s*\{[^}]*flex-direction:\s*row;/s
);
expect(css).toMatch(
/@media \(pointer: coarse\)\s*\{[\s\S]*\.tasknotes-plugin \.task-card--layout-inline \.task-card__context-menu\s*\{[^}]*width:\s*32px;[^}]*height:\s*32px;[^}]*opacity:\s*1;/s
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__metadata\s*\{[^}]*display:\s*none;/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__priority-dot\s*\{[^}]*width:\s*var\(--tn-mobile-inline-indicator-size\);[^}]*height:\s*var\(--tn-mobile-inline-indicator-size\);[^}]*padding:\s*5px;[^}]*background-clip:\s*content-box;/s
);
expect(css).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card--layout-inline \.task-card__context-menu\s*\{[^}]*width:\s*var\(--tn-mobile-inline-menu-size\);[^}]*height:\s*var\(--tn-mobile-inline-menu-size\);[^}]*opacity:\s*1;/s
);
expect(css).toMatch(
/@media \(pointer: coarse\)\s*\{[\s\S]*body:not\(\.is-mobile\) \.tasknotes-plugin \.task-card--layout-inline \.task-card__priority-dot\s*\{[^}]*width:\s*28px;[^}]*height:\s*28px;[^}]*background-clip:\s*content-box;/s
);
});
it("keeps mobile-only modal and settings refinements scoped to Obsidian mobile", () => {
const taskCardCss = readRepoFile("styles/task-card-bem.css");
const taskModalCss = readRepoFile("styles/task-modal.css");
const reminderCss = readRepoFile("styles/reminder-modal.css");
const settingsCss = readRepoFile("styles/settings-view.css");
const calendarCss = readRepoFile("styles/advanced-calendar-view.css");
expect(taskCardCss).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\) \.task-card__metadata-property--projects\s*\{[^}]*flex-wrap:\s*wrap;[^}]*overflow-wrap:\s*anywhere;/s
);
expect(taskCardCss).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-card:not\(\.task-card--layout-inline\) \.task-card__metadata-property--contexts,[\s\S]*?\.task-card__metadata-value\s*\{[^}]*overflow-wrap:\s*anywhere;[^}]*white-space:\s*normal;/s
);
expect(taskModalCss).toMatch(
/body\.is-mobile \.tasknotes-plugin \.task-project-remove\s*\{[^}]*width:\s*32px;[^}]*height:\s*32px;/s
);
expect(reminderCss).toMatch(
/\.tasknotes-plugin \.reminder-modal__task-title\s*\{[^}]*overflow-wrap:\s*anywhere;/s
);
expect(settingsCss).toMatch(
/body\.is-mobile \.tasknotes-plugin \.tasknotes-settings__card-config-row\s*\{[^}]*flex-direction:\s*column;[^}]*width:\s*100%;/s
);
expect(settingsCss).toMatch(
/body\.is-mobile \.tasknotes-plugin \.field-manager__tabs\s*\{[^}]*overflow-x:\s*auto;/s
);
expect(calendarCss).toMatch(
/body\.is-mobile \.timeblock-modal-buttons,\s*body\.is-mobile \.tasknotes-plugin\.calendar-event-creation-modal \.calendar-event-modal-buttons\s*\{[^}]*flex-direction:\s*column;/s
);
});
});

View file

@ -21,5 +21,6 @@
"4.7.1": "1.12.2",
"4.7.2": "1.12.2",
"4.8.0": "1.12.2",
"4.8.1": "1.12.2"
}
"4.8.1": "1.12.2",
"4.9.0": "1.12.2"
}