Skip to content

Commit

Permalink
feat: add option to extend task until next in timeline
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-lednev committed Oct 17, 2023
1 parent b79823d commit ba0c5a2
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
{
"selector": "enum",
"format": [
"StrictPascalCase"
"PascalCase"
]
},
{
Expand All @@ -85,7 +85,7 @@
{
"selector": "interface",
"format": [
"StrictPascalCase"
"PascalCase"
],
"custom": {
"regex": "^I[A-Z]",
Expand Down
4 changes: 3 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ export default class DayPlanner extends Plugin {
private updateStatusBar = async (dataviewTasks: DataArray<STask>) => {
const today = window.moment();

await this.statusBar.update(getTasksForDay(today, dataviewTasks));
await this.statusBar.update(
getTasksForDay(today, dataviewTasks, { ...this.settings() }),
);
};

initWeeklyLeaf = async () => {
Expand Down
10 changes: 5 additions & 5 deletions src/service/dataview-facade.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Moment } from "moment";
import { STask, DateTime } from "obsidian-dataview";

import { defaultDurationMinutes } from "../constants";
import { createPlanItem } from "../parser/parser";
import { timeRegExp } from "../regexp";
import { PlanItem } from "../types";
Expand Down Expand Up @@ -45,17 +44,18 @@ export function sTaskToPlanItem(sTask: STask, day: Moment): PlanItem {
},
});

const durationMinutes = endTime
? getDiffInMinutes(endTime, startTime)
: undefined;

return {
startTime,
rawStartTime: "-",
rawEndTime: "-",
listTokens: `${sTask.symbol} [${sTask.status}] `,
firstLineText,
text,
durationMinutes: getDiffInMinutes(
endTime || startTime.clone().add(defaultDurationMinutes, "minutes"),
startTime,
),
durationMinutes,
startMinutes: getMinutesSinceMidnight(startTime),
location: {
path: sTask.path,
Expand Down
4 changes: 4 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export interface DayPlannerSettings {
timestampFormat: string;
dataviewSource: string;
showDataviewMigrationWarning: boolean;
extendDurationUntilNext: boolean;
defaultDurationMinutes: number;
}

export const defaultSettings = {
Expand All @@ -41,6 +43,8 @@ export const defaultSettings = {
timestampFormat: "HH:mm",
dataviewSource: "",
showDataviewMigrationWarning: true,
extendDurationUntilNext: false,
defaultDurationMinutes: 30,
};

export const defaultSettingsForTests = {
Expand Down
2 changes: 1 addition & 1 deletion src/ui/components/task-container.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
const pointerOffsetY = writable(0);
$: parsedTasks = useTasksForDay({ day, dataviewTasks: $dataviewTasks });
$: parsedTasks = useTasksForDay({ day, dataviewTasks: $dataviewTasks, settings: $settings });
$: ({ startEdit, displayedTasks, cancelEdit, editStatus, confirmEdit } =
useEdit({
Expand Down
10 changes: 8 additions & 2 deletions src/ui/hooks/use-tasks-for-day.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@ import { Moment } from "moment";
import { DataArray, STask } from "obsidian-dataview";

import { addPlacing } from "../../overlap/overlap";
import { DayPlannerSettings } from "../../settings";
import { getTasksForDay } from "../../util/get-tasks-for-day";

interface UseTaskSourceProps {
day: Moment;
dataviewTasks: DataArray<STask>;
settings: DayPlannerSettings;
}

export function useTasksForDay({ day, dataviewTasks }: UseTaskSourceProps) {
export function useTasksForDay({
day,
dataviewTasks,
settings,
}: UseTaskSourceProps) {
if (dataviewTasks.length === 0) {
return [];
}

const tasksForDay = getTasksForDay(day, dataviewTasks);
const tasksForDay = getTasksForDay(day, dataviewTasks, { ...settings });

return addPlacing(tasksForDay);
}
32 changes: 32 additions & 0 deletions src/ui/settings-tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,38 @@ When you open a file, the plugin will search for this heading to detect a day pl
}),
);

containerEl.createEl("h2", { text: "Duration" });

new Setting(containerEl)
.setName("Stretch task until next one in timeline if it has no end time")
.setDesc(
'By "no end time" we mean "- [ ] 10:00 Wake up" instead of "- [ ] 10:00 - 11:00 Wake up"',
)
.addToggle((component) => {
component
.setValue(this.plugin.settings().extendDurationUntilNext)
.onChange((value) => {
this.update({ extendDurationUntilNext: value });
});
});

new Setting(containerEl)
.setName("Default task duration")
.setDesc(
"Used when you create a task with drag-and-drop & when you don't specify an end time",
)
.addSlider((slider) =>
slider
.setLimits(20, 120, 10)
.setValue(Number(this.plugin.settings().defaultDurationMinutes))
.setDynamicTooltip()
.onChange((value: number) => {
this.update({ defaultDurationMinutes: value });
}),
);

containerEl.createEl("h2", { text: "Colors" });

new Setting(containerEl)
.setName("Colorful Timeline")
.setDesc(
Expand Down
41 changes: 39 additions & 2 deletions src/util/get-tasks-for-day.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DataArray, STask } from "obsidian-dataview";

import { timeFromStartRegExp } from "../regexp";
import { sTaskToPlanItem } from "../service/dataview-facade";
import { DayPlannerSettings } from "../settings";
import { PlanItem } from "../types";

function isScheduledForThisDay(task: STask, day: Moment) {
Expand All @@ -29,14 +30,48 @@ function isScheduledForAnotherDay(task: STask, day: Moment) {
return task.scheduled && !isScheduledForThisDay(task, day);
}

export function getTasksForDay(day: Moment, dataviewTasks: DataArray<STask>) {
type DurationOptions = Pick<
DayPlannerSettings,
"defaultDurationMinutes" | "extendDurationUntilNext"
>;

function calculateDuration(tasks: PlanItem[], options: DurationOptions) {
return tasks.map((current, i, array) => {
if (current.durationMinutes) {
return current;
}

const next = array[i + 1];
const shouldExtendUntilNext = next && options.extendDurationUntilNext;

if (shouldExtendUntilNext) {
const minutesUntilNext = next.startMinutes - current.startMinutes;

return {
...current,
durationMinutes: minutesUntilNext,
};
}

return {
...current,
durationMinutes: options.defaultDurationMinutes,
};
});
}

export function getTasksForDay(
day: Moment,
dataviewTasks: DataArray<STask>,
options: DurationOptions,
): PlanItem[] {
if (dataviewTasks.length === 0) {
return [];
}

const noteForThisDay = getDailyNote(day, getAllDailyNotes());

return dataviewTasks
const planItems = dataviewTasks
.where(
(task: STask) =>
isTimeSetOnTask(task) &&
Expand All @@ -47,4 +82,6 @@ export function getTasksForDay(day: Moment, dataviewTasks: DataArray<STask>) {
.map((sTask: STask) => sTaskToPlanItem(sTask, day))
.sort((task: PlanItem) => task.startMinutes)
.array();

return calculateDuration(planItems, options);
}
5 changes: 0 additions & 5 deletions src/util/task-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Moment } from "moment";

import { scheduledDateRegExp } from "../regexp";
import type { PlanItem } from "../types";
import { PlacedPlanItem } from "../types";

Expand Down Expand Up @@ -31,7 +30,3 @@ export function getRenderKey(task: PlacedPlanItem) {
task.isGhost ?? ""
}`;
}

export function getDisplayedText(task: PlanItem) {
return task.text.replace(scheduledDateRegExp, "");
}

0 comments on commit ba0c5a2

Please sign in to comment.