Skip to content

Commit

Permalink
Merge pull request #18 from terryli710/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
terryli710 authored Aug 25, 2023
2 parents 284b0d3 + 53a4739 commit fb2f1f7
Show file tree
Hide file tree
Showing 24 changed files with 425 additions and 245 deletions.
4 changes: 1 addition & 3 deletions TODOs.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

- TODO: BUG: when indicator tag changes,
- previous cards?
- TODO: BUG: when reset, display button as not warning


## Priority
Expand Down Expand Up @@ -129,8 +128,6 @@

## Project

- TODO: OPTIMIZE: optimize addProjects -> avoid ranking repetitively.

### Functionality

- color is "randomly" generated from project name.
Expand All @@ -152,6 +149,7 @@
# Task adding and editing and deletion

- dropdown menu in preview mode to do attribute adding and editing etc.
- TODO: BUG: the autosuggest filter doesn't work.

## Task Adding

Expand Down
3 changes: 3 additions & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
jest.mock('obsidian', () => ({
Notice: jest.fn().mockImplementation((message) => console.log(`Mock Notice: ${message}`))
}));
4 changes: 2 additions & 2 deletions src/autoSuggestions/Suggester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class AttributeSuggester {
let suggestions: SuggestInformation[] = [];

// Modify regex to capture the due date query
const dueRegexText = `${escapeRegExp(this.startingNotation)}\\s?due:(\\s*)${escapeRegExp(this.endingNotation)}`;
const dueRegexText = `${escapeRegExp(this.startingNotation)}\\s?due:(.*?)${escapeRegExp(this.endingNotation)}`;
const dueRegex = new RegExp(dueRegexText, 'g');
const dueMatch = matchByPositionAndGroup(lineText, dueRegex, cursorPos, 1);
if (!dueMatch) return suggestions; // No match
Expand Down Expand Up @@ -179,7 +179,7 @@ export class AttributeSuggester {
let suggestions: SuggestInformation[] = [];

// Modify regex to capture the project name query
const projectRegexText = `${escapeRegExp(this.startingNotation)}\\s?project:(\\s*)${escapeRegExp(this.endingNotation)}`;
const projectRegexText = `${escapeRegExp(this.startingNotation)}\\s?project:(.*?)${escapeRegExp(this.endingNotation)}`;
const projectRegex = new RegExp( projectRegexText, 'g');
const projectMatch = matchByPositionAndGroup(
lineText,
Expand Down
14 changes: 4 additions & 10 deletions src/renderer/postProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,22 @@ import {
} from '../taskModule/taskSyncManager';
import { logger } from '../utils/log';

export type TaskMode = 'single-line' | 'multi-line';
export interface TaskItemParams {
mode: TaskMode | null;
export type TaskDisplayMode = 'single-line' | 'multi-line';
export interface TaskDisplayParams {
mode: TaskDisplayMode | null;
}

export class TaskItemSvelteAdapter extends MarkdownRenderChild {
taskSync: ObsidianTaskSyncProps;
taskSyncManager: ObsidianTaskSyncManager;
svelteComponent: SvelteComponent;
plugin: TaskCardPlugin;
// params: TaskItemParams;


constructor(taskSync: ObsidianTaskSyncProps, plugin: TaskCardPlugin) {
super(taskSync.taskItemEl);
this.taskSync = taskSync;
this.taskSyncManager = new ObsidianTaskSyncManager(plugin, taskSync);
this.plugin = plugin;
// if (taskSync.obsidianTask.metadata.taskItemParams) {
// this.params = taskSync.obsidianTask.metadata.taskItemParams;
// } else {
// this.params = { mode: get(SettingStore).displaySettings.defaultMode as TaskMode };
// }
}

onload() {
Expand Down
40 changes: 20 additions & 20 deletions src/renderer/store.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Writable, writable } from 'svelte/store';
import { TaskMode } from './postProcessor';
import { TaskDisplayMode } from './postProcessor';
import { SettingStore } from '../settings';
import { MarkdownView, Workspace, WorkspaceLeaf } from 'obsidian';
import { logger } from '../utils/log';
import { ObsidianTaskSyncProps } from '../taskModule/taskSyncManager';

export class TaskStore {
private taskModes: Writable<{ [key: string]: TaskMode }>;
private taskModes: Writable<{ [key: string]: TaskDisplayMode }>;
public readonly subscribe: Function;
private filePath: string = '';
private defaultMode: TaskMode = 'single-line'; // Default value
private defaultMode: TaskDisplayMode = 'single-line'; // Default value

constructor() {
this.taskModes = writable({});
this.subscribe = this.taskModes.subscribe;

SettingStore.subscribe((settings) => {
this.defaultMode = settings.displaySettings.defaultMode as TaskMode;
this.defaultMode = settings.displaySettings.defaultMode as TaskDisplayMode;
});
}

Expand All @@ -26,70 +26,70 @@ export class TaskStore {
if (!view.file) { return; }
const newFilePath = view.file.path;
const mode = view.getMode();
if (mode !== 'preview') { this.clearTaskModes(); }
if (mode !== 'preview') { this.clearTaskDisplayModes(); }
this.setFilePath(newFilePath);
}

private clearTaskModes(): void {
private clearTaskDisplayModes(): void {
this.taskModes.set({});
}

private setFilePath(newFilePath: string): void {
if (newFilePath !== this.filePath) {
this.filePath = newFilePath;
this.clearTaskModes();
this.clearTaskDisplayModes();
}
}

getDefaultMode(): TaskMode {
getDefaultMode(): TaskDisplayMode {
return this.defaultMode;
}

// Mode-related CRUD Operations (By Line Numbers)
setModeByLine(startLine: number, endLine: number, newMode: TaskMode = this.defaultMode): void {
setModeByLine(startLine: number, endLine: number, newMode: TaskDisplayMode = this.defaultMode): void {
this.updateMode(this.generateKey(startLine, endLine), newMode);
}

getModeByLine(startLine: number, endLine: number): TaskMode | null {
getModeByLine(startLine: number, endLine: number): TaskDisplayMode | null {
return this.getModeByKey(this.generateKey(startLine, endLine));
}

updateModeByLine(startLine: number, endLine: number, newMode: TaskMode): void {
updateModeByLine(startLine: number, endLine: number, newMode: TaskDisplayMode): void {
this.ensureMode(this.generateKey(startLine, endLine), newMode);
}

// Mode-related CRUD Operations (By Key)
setModeByKey(key: string, newMode: TaskMode = this.defaultMode): void {
setModeByKey(key: string, newMode: TaskDisplayMode = this.defaultMode): void {
this.updateMode(key, newMode);
}

getModeByKey(key: string): TaskMode | null {
getModeByKey(key: string): TaskDisplayMode | null {
let mode = null;
this.taskModes.subscribe((modes) => {
mode = modes[key] || null;
})();
return mode;
}

updateModeByKey(key: string, newMode: TaskMode): void {
updateModeByKey(key: string, newMode: TaskDisplayMode): void {
this.ensureMode(key, newMode);
}

// Mode-related CRUD Operations (By Task Sync)
setModeBySync(taskSync: ObsidianTaskSyncProps, newMode: TaskMode = this.defaultMode): void {
setModeBySync(taskSync: ObsidianTaskSyncProps, newMode: TaskDisplayMode = this.defaultMode): void {
this.updateMode(this.generateKeyFromSync(taskSync), newMode);
}

getModeBySync(taskSync: ObsidianTaskSyncProps): TaskMode | null {
getModeBySync(taskSync: ObsidianTaskSyncProps): TaskDisplayMode | null {
return this.getModeByKey(this.generateKeyFromSync(taskSync));
}

updateModeBySync(taskSync: ObsidianTaskSyncProps, newMode: TaskMode): void {
updateModeBySync(taskSync: ObsidianTaskSyncProps, newMode: TaskDisplayMode): void {
this.ensureMode(this.generateKeyFromSync(taskSync), newMode);
}

// Ensure Mode Exists
private ensureMode(key: string, newMode: TaskMode): void {
private ensureMode(key: string, newMode: TaskDisplayMode): void {
this.taskModes.update((modes) => {
if (modes[key]) {
modes[key] = newMode;
Expand All @@ -99,7 +99,7 @@ export class TaskStore {
}

// Get All Modes
getAllModes(): { [key: string]: TaskMode } {
getAllModes(): { [key: string]: TaskDisplayMode } {
let modes;
this.taskModes.subscribe((currentModes) => {
modes = { ...currentModes };
Expand All @@ -112,7 +112,7 @@ export class TaskStore {
return `${startLine}-${endLine}`;
}

private updateMode(key: string, newMode: TaskMode): void {
private updateMode(key: string, newMode: TaskDisplayMode): void {
this.taskModes.update((modes) => {
modes[key] = newMode;
return modes;
Expand Down
2 changes: 1 addition & 1 deletion src/taskModule/project/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class ProjectModule {

private sortProjectsByName(): void {
this.projects = new Map([...this.projects.entries()].sort((a, b) => a[1].name.localeCompare(b[1].name)));
logger.debug(`projects are sorted: ${JSON.stringify([...this.projects.values()])}`);
// logger.debug(`projects are sorted: ${JSON.stringify([...this.projects.values()])}`);
}


Expand Down
21 changes: 11 additions & 10 deletions src/taskModule/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { Static } from 'runtypes';
import { String } from 'runtypes';
import { v4 as uuidv4 } from 'uuid';
import { Project } from './project';
import { TaskItemParams } from '../renderer/postProcessor';
import { TaskDisplayParams } from '../renderer/postProcessor';
import { logger } from '../utils/log';

export const DateOnly = String.withConstraint((s) =>
/^\d{4}-\d{2}-\d{2}$/.test(s)
Expand Down Expand Up @@ -32,12 +33,12 @@ export interface TaskProperties {
labels: string[];
completed: boolean;

parent?: TaskProperties | null;
children: TaskProperties[];
parent?: TaskProperties | ObsidianTask | null;
children: TaskProperties[] | ObsidianTask[];

due?: DueDate | null;
metadata?: {
taskItemParams?: TaskItemParams | null;
taskDisplayParams?: TaskDisplayParams | null;
[key: string]: any;
};
}
Expand All @@ -60,7 +61,7 @@ export class ObsidianTask implements TaskProperties {
public due?: DueDate | null;

public metadata?: {
taskItemParams?: TaskItemParams | null;
taskDisplayParams?: TaskDisplayParams | null;
[key: string]: any;
};

Expand Down Expand Up @@ -111,14 +112,14 @@ export class ObsidianTask implements TaskProperties {
return !!this.due.string;
}

setTaskItemParams(key: string, value: any): void {
this.metadata.taskItemParams = {
...this.metadata.taskItemParams,
setTaskDisplayParams(key: string, value: any): void {
this.metadata.taskDisplayParams = {
...this.metadata.taskDisplayParams,
[key]: value
};
}

clearTaskItemParams(): void {
this.metadata.taskItemParams = null;
clearTaskDisplayParams(): void {
this.metadata.taskDisplayParams = null;
}
}
23 changes: 13 additions & 10 deletions src/taskModule/taskFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TaskMode } from '../renderer/postProcessor';
import { TaskDisplayMode } from '../renderer/postProcessor';
import { SettingStore } from '../settings';
import { logger } from '../utils/log';
import { camelToKebab } from '../utils/stringCaseConverter';
Expand All @@ -8,6 +8,7 @@ export class TaskFormatter {
indicatorTag: string;
markdownSuffix: string;
defaultMode: string;
specialAttributes: string[] = ['completed', 'content', 'labels'];

constructor(settingsStore: typeof SettingStore) {
// Subscribe to the settings store
Expand All @@ -19,18 +20,20 @@ export class TaskFormatter {
}

taskToMarkdown(task: ObsidianTask): string {
let markdownLine = `- [${task.completed ? 'x' : ' '}] ${task.content} #${
this.indicatorTag
}\n`;

// add TaskItemParams to task
if (!task.metadata.taskItemParams) {
task.metadata.taskItemParams = { mode: this.defaultMode as TaskMode };
const taskPrefix = `- [${task.completed ? 'x' : ' '}]`;
const labelMarkdown = task.labels.join(' ');
let markdownLine = `${taskPrefix} ${task.content} ${labelMarkdown} #${this.indicatorTag}`;
markdownLine = markdownLine.replace(/\s+/g, ' '); // remove multiple spaces
markdownLine += '\n';

// add TaskDisplayParams to task
if (!task.metadata.taskDisplayParams) {
task.metadata.taskDisplayParams = { mode: this.defaultMode as TaskDisplayMode };
}

// Iterate over keys in task, but exclude 'completed' and 'content'
// Iterate over keys in task, but exclude special attributes
for (let key in task) {
if (key === 'completed' || key === 'content') continue;
if (this.specialAttributes.includes(key)) continue;

let value = task[key];
if (value === undefined) {
Expand Down
11 changes: 10 additions & 1 deletion src/taskModule/taskMonitor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { App, MarkdownView, TFile, WorkspaceLeaf } from 'obsidian';
import TaskCardPlugin from '..';
import { Notice } from 'obsidian';
import { logger } from '../utils/log';


export class TaskMonitor {
plugin: TaskCardPlugin;
Expand Down Expand Up @@ -38,8 +41,14 @@ export class TaskMonitor {
}

updateTaskInLine(line: string, index: number): string {
function announceError(errorMsg: string): void {
// Show a notice popup
new Notice(errorMsg);
// Log the error
logger.error(errorMsg);
}
if (this.plugin.taskValidator.isValidUnformattedTaskMarkdown(line)) {
const task = this.plugin.taskParser.parseTaskMarkdown(line);
const task = this.plugin.taskParser.parseTaskMarkdown(line, announceError);
return this.plugin.taskFormatter.taskToMarkdownOneLine(task);
}
return line;
Expand Down
Loading

0 comments on commit fb2f1f7

Please # to comment.