Skip to content

Commit

Permalink
Merge branch 'feature/event_sync_settings'
Browse files Browse the repository at this point in the history
  • Loading branch information
dexin-qi committed Apr 20, 2023
1 parent ce174c2 commit 5e32df1
Show file tree
Hide file tree
Showing 20 changed files with 1,333 additions and 432 deletions.
112 changes: 112 additions & 0 deletions Injector/Parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { isSortingOption, sortingOptions } from "./Query";
import type { Query } from "./Query";
import YAML from "yaml";

export class ParsingError extends Error {
inner: Error | undefined;

constructor(msg: string, inner: Error | undefined = undefined) {
super(msg);
this.inner = inner;
}

public toString(): string {
if (this.inner) {
return `${this.message}: '${this.inner}'`;
}

return super.toString();
}
}

export function parseQuery(raw: string): Query {
let obj: any;

try {
obj = tryParseAsJson(raw);
} catch (e) {
try {
obj = tryParseAsYaml(raw);
} catch (e) {
throw new ParsingError("Unable to parse as YAML or JSON");
}
}

return parseObject(obj);
}

function tryParseAsJson(raw: string): any {
try {
return JSON.parse(raw);
} catch (e) {
throw new ParsingError("Invalid JSON", e);
}
}

function tryParseAsYaml(raw: string): any {
try {
return YAML.parse(raw);
} catch (e) {
throw new ParsingError("Invalid YAML", e);
}
}

function parseObject(query: any): Query {
if (query.hasOwnProperty("name") && typeof query.name !== "string") {
throw new ParsingError("'name' field must be a string");
}

if (query.hasOwnProperty("filter") && typeof query.filter !== "string") {
throw new ParsingError("'filter' field must be a string");
}

if (query.hasOwnProperty("timeMin")) {
if (typeof query.timeMin !== "string") {
throw new ParsingError("'timeMin' field must be a string");
}
if (!window.moment(query.timeMin).isValid()) {
throw new ParsingError("'timeMin' field must be a valid moment string");
}
}

if (query.hasOwnProperty("timeMax")) {
if (typeof query.timeMax !== "string") {
throw new ParsingError("'timeMax' field must be a string");
}
if (!window.moment(query.timeMax).isValid()) {
throw new ParsingError("'timeMax' field must be a valid moment string");
}
}

if (query.hasOwnProperty("maxEvents") && typeof query.maxEvents !== "number") {
throw new ParsingError("'maxEvents' field must be a number");
}

if (query.hasOwnProperty("group") && typeof query.group != "boolean") {
throw new ParsingError("'group' field must be a boolean.");
}

if (query.hasOwnProperty("sorting")) {
if (!Array.isArray(query.sorting)) {
throw new ParsingError(
`'sorting' field must be an array of strings within the set [${formatSortingOpts()}].`
);
}

const sorting = query.sorting as any[];

for (const element of sorting) {
if (!(typeof element == "string") || !isSortingOption(element)) {
throw new ParsingError(
`'sorting' field must be an array of strings within the set [${formatSortingOpts()}].`
);
}
}
}

return query as Query;
}

function formatSortingOpts(): string {
return sortingOptions.map((e) => `'${e}'`).join(", ");
}
23 changes: 23 additions & 0 deletions Injector/Query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const sortingOptions = [
"date",
"dateDESC",
"priority",
"priorityDESC",
];

export type SortingOption = typeof sortingOptions[number];

export function isSortingOption(value: string): value is SortingOption;
export function isSortingOption(value: any) {
return sortingOptions.includes(value);
}

export type Query = {
name?: string
timeMin?: string;
timeMax?: string;
maxEvents?:number;
filter?: string;
sorting?: SortingOption[];
group?: boolean;
};
55 changes: 37 additions & 18 deletions Injector/QueryInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,24 @@ import {
MarkdownRenderChild,
} from "obsidian";

import SyncCalendarPlugin from "main";
import type SyncCalendarPlugin from "main";
import type GoogleCalendarSync from "../Syncs/GoogleCalendarSync";

import GoogleCalendarSync from "../Syncs/GoogleCalendarSync";
import { parseQuery } from "./Parser";
import { Query } from "./Query";

import TodoistQuery from "../ui/TodoistQuery.svelte";
import type SvelteComponentDev from "../ui/TodoistQuery.svelte";
import ErrorDisplay from "../ui/ErrorDisplay.svelte";
// import SvelteComponentDev
import type { SvelteComponentDev } from "svelte/internal";

export default class QueryInjector {
private app: App;
private pendingQueries: PendingQuery[];

private plugin: SyncCalendarPlugin;
private calendarSync: GoogleCalendarSync;

constructor(plugin: SyncCalendarPlugin, app: App) {
constructor(plugin: SyncCalendarPlugin) {
this.plugin = plugin;
this.app = app;
this.pendingQueries = [];
}

Expand All @@ -33,8 +32,6 @@ export default class QueryInjector {
ctx: ctx,
};
// console.log('source: ' + source);
// console.log('target: ' + el);
// console.log('ctx: ' + ctx);

if (typeof this.calendarSync == "undefined") {
this.pendingQueries.push(pendingQuery);
Expand All @@ -54,16 +51,38 @@ export default class QueryInjector {
}

injectQuery(pendingQuery: PendingQuery) {
const child = new InjectedQuery(pendingQuery.target, (root: HTMLElement) => {
return new TodoistQuery({
target: root,
props: {
plugin: this.plugin,
api: this.calendarSync,

},
let child: InjectedQuery;

try {
let query: Query;
if (pendingQuery.source.length > 0) {
query = parseQuery(pendingQuery.source);
}

child = new InjectedQuery(pendingQuery.target, (root: HTMLElement) => {
return new TodoistQuery({
target: root,
props: {
plugin: this.plugin,
api: this.calendarSync,
query: query,
},
});
});
});
}
catch (e) {
console.error(e);

child = new InjectedQuery(pendingQuery.target, (root: HTMLElement) => {
return new ErrorDisplay({
target: root,
props: {
error: e
},
});
});
}


pendingQuery.ctx.addChild(child);
}
Expand Down
Loading

0 comments on commit 5e32df1

Please sign in to comment.