Skip to content

Commit

Permalink
2.5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Tazman Reinier committed Oct 14, 2024
1 parent c12a675 commit 75922f2
Show file tree
Hide file tree
Showing 17 changed files with 84 additions and 107 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

# Changelog

## 2.5.2 (10/14/2024)
**Changed:**
- "Do now" button is now "Do Today"

**Fixed:**
- No longer displaying [remaining days as decimal](https://github.com/j-palindrome/obsidian-time-ruler/issues/133)
- Support [tag sorting](https://github.com/j-palindrome/obsidian-time-ruler/issues/96)

## 2.5.0 (9/28/2024)

**Added:**
Expand Down
2 changes: 1 addition & 1 deletion dist/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "time-ruler",
"name": "Time Ruler",
"version": "2.5.0",
"version": "2.5.2",
"minAppVersion": "0.15.0",
"description": "A drag-and-drop time ruler combining the best of a task list and a calendar view (integrates with Tasks, Full Calendar, and Dataview).",
"author": "Joshua Tazman Reinier",
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "time-ruler",
"name": "Time Ruler",
"version": "2.5.1",
"version": "2.5.2",
"minAppVersion": "0.15.0",
"description": "A drag-and-drop time ruler combining the best of a task list and a calendar view (integrates with Tasks, Full Calendar, and Dataview).",
"author": "Joshua Tazman Reinier",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"react-timer-hook": "^3.0.7",
"react-usestateref": "^1.0.8",
"tiny-invariant": "^1.3.1",
"typescript": "^5.6.3",
"zustand": "^4.4.6"
},
"devDependencies": {
Expand Down
19 changes: 14 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type AppState = {
calendar?: CalendarAPI
}
dragData: DragData | null
dragMode: 'ripple' | 'normal'
findingTask: string | null
inScroll: number
searchStatus: boolean
Expand Down Expand Up @@ -71,6 +72,7 @@ export const useAppStore = createWithEqualityFn<AppState>(() => ({
inScroll: 0,
searchStatus: false,
viewMode: 'hour',
dragMode: 'normal',
fileOrder: [],
dailyNoteInfo: {
format: 'YYYY-MM-DD',
Expand Down
1 change: 1 addition & 0 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ const Buttons = ({
['path', 'Path', 'folder-tree'],
['priority', 'Priority', 'alert-circle'],
['hybrid', 'Hybrid', 'arrow-down-narrow-wide'],
['tags', 'Tags', 'hash'],
[false, 'None', 'x'],
].map(
([groupBy, title, src]: [
Expand Down
21 changes: 4 additions & 17 deletions src/components/Block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,18 @@ export default function Block({

const sortedGroups = useAppStore((state) => {
switch (state.settings.groupBy) {
case 'priority':
case false:
return _.entries(groupedTasks)
default:
return _.sortBy(
_.entries(groupedTasks),
([group]) => (group === UNGROUPED ? 0 : 1),
0
)
case 'path':
return _.sortBy(
_.entries(groupedTasks),
([group, _tasks]) => (group === UNGROUPED ? 0 : 1),
([group, _tasks]) =>
state.fileOrder.indexOf(parseFileFromPath(group)),
'1.0.position.start.line'
)
case 'hybrid':
return _.sortBy(
_.entries(groupedTasks),
([group, _tasks]) => (group === UNGROUPED ? 0 : 1),
0,
'1.0.priority',
([group, _tasks]) =>
state.fileOrder.indexOf(parseFileFromPath(group)),
'1.0.position.start.line'
)
case false:
return _.entries(groupedTasks)
}
}, shallow)

Expand Down
3 changes: 2 additions & 1 deletion src/components/Day.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export default function Day({
? false
: isDateISO(scheduled)
? scheduled === startDate
: scheduled >= startISO && scheduled < endISO
: (isNow ? scheduled > startDate : scheduled >= startISO) &&
scheduled < endISO

const dueToday =
!showingPastDates &&
Expand Down
26 changes: 19 additions & 7 deletions src/components/NewTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ export default function NewTask({ dragContainer }: { dragContainer: string }) {
: undefined
)

const checkForClick = () => {
if (!getters.get('dragData')) {
setters.set({ newTask: { task: { scheduled: undefined }, type: 'new' } })
}
window.removeEventListener('mouseup', checkForClick)
}

return (
<div className='flex relative z-30 pl-2'>
{draggingTask ? (
Expand All @@ -96,13 +103,18 @@ export default function NewTask({ dragContainer }: { dragContainer: string }) {
)}
</>
) : (
<Button
{...attributes}
{...listeners}
ref={setNodeRef}
className='relative flex-none h-10 w-10 cursor-grab !rounded-full bg-accent child:invert'
src='plus'
/>
<>
<Button
{...attributes}
{...listeners}
onMouseDown={() => {
window.addEventListener('mouseup', checkForClick)
}}
ref={setNodeRef}
className='relative flex-none h-10 w-10 cursor-grab !rounded-full bg-accent child:invert'
src='plus'
/>
</>
)}

{newTaskData && newTask && newTaskMode && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export default function Task({
<Logo src='align-justify' className='py-2 px-1 h-full' />
</div>
</div>
{task.tags.length > 0 && (
{task.tags.length > 0 && groupBy !== 'tags' && (
<div className='no-scrollbar flex space-x-2 overflow-x-auto pl-indent text-xs child:whitespace-nowrap'>
{task.tags.map((tag) => (
<div
Expand Down
28 changes: 15 additions & 13 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getAPI } from 'obsidian-dataview'
import TimeRulerView, { TIME_RULER_VIEW } from './index'
import SettingsTab from './plugin/SettingsTab'
import { openTaskInRuler } from './services/obsidianApi'
import { taskToText, textToTask } from './services/parser'
import { ISO_MATCH, taskToText, textToTask } from './services/parser'
import { getters, setters } from './app/store'
import invariant from 'tiny-invariant'
import { roundMinutes, toISO } from './services/util'
Expand All @@ -35,7 +35,7 @@ type TimeRulerSettings = {
}
showCompleted: boolean
dayStartEnd: [number, number]
groupBy: false | 'priority' | 'path' | 'hybrid'
groupBy: false | 'priority' | 'path' | 'hybrid' | 'tags'
twentyFourHourFormat: boolean
filterFunction: string
addTaskToEnd: boolean
Expand Down Expand Up @@ -156,28 +156,30 @@ export default class TimeRulerPlugin extends Plugin {
menu.addItem((item) =>
item
.setIcon('ruler')
.setTitle('Do now')
.onClick(() => this.editTask(context, cursor.line, 'now'))
)
menu.addItem((item) =>
item
.setIcon('ruler')
.setTitle('Unschedule')
.onClick(() => this.editTask(context, cursor.line, 'unschedule'))
.setTitle('Do today')
.onClick(() => this.editTask(context, cursor.line, 'today'))
)
if (line.match(new RegExp(ISO_MATCH))) {
menu.addItem((item) =>
item
.setIcon('ruler')
.setTitle('Unschedule')
.onClick(() => this.editTask(context, cursor.line, 'unschedule'))
)
}
}

async editTask(
context: MarkdownView,
line: number,
modification: 'now' | 'unschedule'
modification: 'today' | 'unschedule'
) {
invariant(context.file)
const id = context.file.path.replace('.md', '') + '::' + line
let scheduled: TaskProps['scheduled']
switch (modification) {
case 'now':
scheduled = toISO(roundMinutes(DateTime.now()))
case 'today':
scheduled = toISO(roundMinutes(DateTime.now()), true)
break
case 'unschedule':
scheduled = ''
Expand Down
2 changes: 2 additions & 0 deletions src/services/calendarApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ export default class CalendarAPI extends Component {
events[thisId] = props
}
} else {
if (event.summary.includes('TEST')) console.log(event)

let end = DateTime.fromJSDate(event.end).setZone('local')
if (end < dateBounds[0]) continue

Expand Down
58 changes: 2 additions & 56 deletions src/services/dragging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ export const onDragEnd = async (
) => {
const dropData = ev.over?.data.current as DropData | undefined
const dragData = activeDragRef.current
const dragMode = getters.get('dragMode')

if (ev.active.id === ev.over?.id) {
setters.set({ dragData: null })
return
}

if (dragData?.dragType === 'new_button' && !dropData) {
setters.set({ newTask: { task: { scheduled: undefined }, type: 'new' } })
} else if (dragData?.dragType === 'task' && dropData?.type === 'move') {
if (dragData?.dragType === 'task' && dropData?.type === 'move') {
setters.set({ newTask: { task: dragData, type: 'move' } })
} else if (dropData && dragData) {
if (!isTaskProps(dropData)) {
Expand Down Expand Up @@ -67,59 +66,6 @@ export const onDragEnd = async (
}
} else {
switch (dragData.dragType) {
case 'now':
if (!dropData.scheduled) break

const dayStart = getters.get('settings').dayStartEnd[0]
const startOfDay = DateTime.now()
.startOf('day')
.plus({ hours: dayStart })
const today = toISO(startOfDay)
const tomorrow = toISO(startOfDay.plus({ days: 1 }))
const tasks = getters.get('tasks')
const futureTasks: Record<string, TaskProps[]> = {}

for (let task of _.values(tasks)) {
if (task.completed) continue
const scheduled = parseTaskDate(task)
if (
scheduled &&
!isDateISO(scheduled) &&
scheduled >= today &&
scheduled < tomorrow
) {
if (task.queryParent) continue
let parent = task.parent
while (parent) {
if (tasks[parent].queryParent) continue
parent = tasks[parent].parent
}
if (futureTasks[scheduled]) futureTasks[scheduled].push(task)
else futureTasks[scheduled] = [task]
}
}

const tasksByTime = _.sortBy(_.entries(futureTasks), 0)
const { hours: shiftHours, minutes: shiftMinutes } = DateTime.fromISO(
dropData.scheduled
)
.diff(DateTime.fromISO(tasksByTime[0][0]))
.shiftTo('hours', 'minutes')

if (!confirm(`Shift tasks by ${shiftHours}h${shiftMinutes}m?`)) break

for (let [time, tasks] of tasksByTime) {
const timeParse = DateTime.fromISO(time)
await setters.patchTasks(
tasks.map((task) => task.id),
{
scheduled: toISO(
timeParse.plus({ hours: shiftHours, minutes: shiftMinutes })
),
}
)
}
break
case 'new_button':
setters.set({
newTask: { task: { scheduled: dropData.scheduled }, type: 'new' },
Expand Down
2 changes: 1 addition & 1 deletion src/services/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
toISO,
} from './util'

const ISO_MATCH = '\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?'
export const ISO_MATCH = '\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2})?'
const TASKS_EMOJI_SEARCH = new RegExp(
`[${_.values(keyToTasksEmoji).join('')}] ?(${ISO_MATCH})?`,
'giu'
Expand Down
13 changes: 10 additions & 3 deletions src/services/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ export const splitHeading = (heading: string) => {
}

export const getHeading = (
{ path, page, priority }: Pick<TaskProps, 'path' | 'page' | 'priority'>,
{
path,
page,
priority,
tags,
}: Pick<TaskProps, 'path' | 'page' | 'priority' | 'tags'>,
dailyNoteInfo: AppState['dailyNoteInfo'],
groupBy: AppState['settings']['groupBy'],
hidePaths: string[] = []
Expand All @@ -136,9 +141,11 @@ export const getHeading = (
if (
groupBy === 'priority' ||
(groupBy === 'hybrid' && priority !== TaskPriorities.DEFAULT)
)
) {
heading = priorityNumberToSimplePriority[priority]
else if (groupBy === 'path' || groupBy === 'hybrid') {
} else if (groupBy === 'tags') {
heading = tags.sort().join(', ')
} else if (groupBy === 'path' || groupBy === 'hybrid') {
// replace daily note
const file = parseFileFromPath(heading)
const date = parseDateFromPath(file, dailyNoteInfo)
Expand Down
1 change: 0 additions & 1 deletion src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ declare global {
| ({ dragType: 'time' } & { start: string; end?: string })
| ({ dragType: 'due' } & { task: TaskProps })
| { dragType: 'new_button' }
| { dragType: 'now' }

type DropData =
| Partial<TaskProps>
Expand Down

0 comments on commit 75922f2

Please sign in to comment.