} props
- * @returns {void}
- */
- $set(props) {
- if (this.$$set && !is_empty(props)) {
- this.$$.skip_bound = true;
- this.$$set(props);
- this.$$.skip_bound = false;
- }
- }
-}
-const PUBLIC_VERSION = "4";
-if (typeof window !== "undefined")
- (window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION);
-function __awaiter(thisArg, _arguments, P, generator) {
- function adopt(value) {
- return value instanceof P ? value : new P(function(resolve) {
- resolve(value);
- });
- }
- return new (P || (P = Promise))(function(resolve, reject) {
- function fulfilled(value) {
- try {
- step(generator.next(value));
- } catch (e) {
- reject(e);
- }
- }
- function rejected(value) {
- try {
- step(generator["throw"](value));
- } catch (e) {
- reject(e);
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
- }
- step((generator = generator.apply(thisArg, [])).next());
- });
-}
-function create_if_block_2$1(ctx) {
- let div;
- let span0;
- let svg;
- let path;
- let span0_title_value;
- let t0;
- let span1;
- let t1;
- let mounted;
- let dispose;
- return {
- c() {
- div = element("div");
- span0 = element("span");
- svg = svg_element("svg");
- path = svg_element("path");
- t0 = space();
- span1 = element("span");
- t1 = text(
- /*title*/
- ctx[5]
- );
- attr(path, "d", "m6 9 6 6 6-6");
- attr(svg, "xmlns", "http://www.w3.org/2000/svg");
- attr(svg, "width", "24");
- attr(svg, "height", "24");
- attr(svg, "viewBox", "0 0 24 24");
- attr(svg, "fill", "none");
- attr(svg, "stroke", "currentColor");
- attr(svg, "stroke-width", "2");
- attr(svg, "stroke-linecap", "round");
- attr(svg, "stroke-linejoin", "round");
- attr(svg, "class", "lucide lucide-chevron-down");
- attr(span0, "role", "button");
- attr(
- span0,
- "data-collapsed",
- /*isCollapsed*/
- ctx[7]
- );
- attr(span0, "class", "collapse-button svelte-1d2sruf");
- attr(span0, "title", span0_title_value = /*isCollapsed*/
- ctx[7] ? "Expand" : "Collapse");
- attr(span1, "role", "link");
- attr(span1, "class", "clickable-link svelte-1d2sruf");
- attr(
- span1,
- "data-title",
- /*title*/
- ctx[5]
- );
- attr(div, "class", "daily-note-title inline-title svelte-1d2sruf");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- append(div, span0);
- append(span0, svg);
- append(svg, path);
- append(div, t0);
- append(div, span1);
- append(span1, t1);
- if (!mounted) {
- dispose = [
- listen(
- span0,
- "click",
- /*toggleCollapse*/
- ctx[10]
- ),
- listen(
- span1,
- "click",
- /*handleFileIconClick*/
- ctx[8]
- )
- ];
- mounted = true;
- }
- },
- p(ctx2, dirty) {
- if (dirty & /*isCollapsed*/
- 128) {
- attr(
- span0,
- "data-collapsed",
- /*isCollapsed*/
- ctx2[7]
- );
- }
- if (dirty & /*isCollapsed*/
- 128 && span0_title_value !== (span0_title_value = /*isCollapsed*/
- ctx2[7] ? "Expand" : "Collapse")) {
- attr(span0, "title", span0_title_value);
- }
- if (dirty & /*title*/
- 32)
- set_data(
- t1,
- /*title*/
- ctx2[5]
- );
- if (dirty & /*title*/
- 32) {
- attr(
- span1,
- "data-title",
- /*title*/
- ctx2[5]
- );
- }
- },
- d(detaching) {
- if (detaching) {
- detach(div);
- }
- mounted = false;
- run_all$1(dispose);
- }
- };
-}
-function create_if_block_1$1(ctx) {
- let div;
- return {
- c() {
- div = element("div");
- div.textContent = "Loading...";
- attr(div, "class", "editor-placeholder svelte-1d2sruf");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- },
- d(detaching) {
- if (detaching) {
- detach(div);
- }
- }
- };
-}
-function create_if_block$1(ctx) {
- let div;
- return {
- c() {
- div = element("div");
- div.textContent = "Scroll to view content";
- attr(div, "class", "editor-placeholder svelte-1d2sruf");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- },
- d(detaching) {
- if (detaching) {
- detach(div);
- }
- }
- };
-}
-function create_fragment$1(ctx) {
- let div2;
- let div1;
- let t0;
- let div0;
- let t1;
- let div2_data_id_value;
- let mounted;
- let dispose;
- let if_block0 = (
- /*title*/
- ctx[5] && create_if_block_2$1(ctx)
- );
- let if_block1 = !/*rendered*/
- ctx[3] && /*shouldRender*/
- ctx[1] && create_if_block_1$1();
- let if_block2 = !/*shouldRender*/
- ctx[1] && !/*rendered*/
- ctx[3] && create_if_block$1();
- return {
- c() {
- div2 = element("div");
- div1 = element("div");
- if (if_block0)
- if_block0.c();
- t0 = space();
- div0 = element("div");
- if (if_block1)
- if_block1.c();
- t1 = space();
- if (if_block2)
- if_block2.c();
- attr(div0, "class", "daily-note-editor svelte-1d2sruf");
- attr(
- div0,
- "data-collapsed",
- /*isCollapsed*/
- ctx[7]
- );
- attr(div0, "aria-hidden", "true");
- attr(
- div0,
- "data-title",
- /*title*/
- ctx[5]
- );
- attr(div1, "class", "daily-note svelte-1d2sruf");
- attr(div2, "class", "daily-note-container");
- attr(div2, "data-id", div2_data_id_value = "dn-editor-" + /*file*/
- ctx[0].path);
- set_style(
- div2,
- "min-height",
- /*isCollapsed*/
- ctx[7] ? "auto" : (
- /*editorHeight*/
- ctx[6] + "px"
- )
- );
- },
- m(target, anchor) {
- insert(target, div2, anchor);
- append(div2, div1);
- if (if_block0)
- if_block0.m(div1, null);
- append(div1, t0);
- append(div1, div0);
- if (if_block1)
- if_block1.m(div0, null);
- append(div0, t1);
- if (if_block2)
- if_block2.m(div0, null);
- ctx[13](div0);
- ctx[14](div2);
- if (!mounted) {
- dispose = listen(
- div0,
- "click",
- /*handleEditorClick*/
- ctx[9]
- );
- mounted = true;
- }
- },
- p(ctx2, [dirty]) {
- if (
- /*title*/
- ctx2[5]
- ) {
- if (if_block0) {
- if_block0.p(ctx2, dirty);
- } else {
- if_block0 = create_if_block_2$1(ctx2);
- if_block0.c();
- if_block0.m(div1, t0);
- }
- } else if (if_block0) {
- if_block0.d(1);
- if_block0 = null;
- }
- if (!/*rendered*/
- ctx2[3] && /*shouldRender*/
- ctx2[1]) {
- if (if_block1)
- ;
- else {
- if_block1 = create_if_block_1$1();
- if_block1.c();
- if_block1.m(div0, t1);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- if (!/*shouldRender*/
- ctx2[1] && !/*rendered*/
- ctx2[3]) {
- if (if_block2)
- ;
- else {
- if_block2 = create_if_block$1();
- if_block2.c();
- if_block2.m(div0, null);
- }
- } else if (if_block2) {
- if_block2.d(1);
- if_block2 = null;
- }
- if (dirty & /*isCollapsed*/
- 128) {
- attr(
- div0,
- "data-collapsed",
- /*isCollapsed*/
- ctx2[7]
- );
- }
- if (dirty & /*title*/
- 32) {
- attr(
- div0,
- "data-title",
- /*title*/
- ctx2[5]
- );
- }
- if (dirty & /*file*/
- 1 && div2_data_id_value !== (div2_data_id_value = "dn-editor-" + /*file*/
- ctx2[0].path)) {
- attr(div2, "data-id", div2_data_id_value);
- }
- if (dirty & /*isCollapsed, editorHeight*/
- 192) {
- set_style(
- div2,
- "min-height",
- /*isCollapsed*/
- ctx2[7] ? "auto" : (
- /*editorHeight*/
- ctx2[6] + "px"
- )
- );
- }
- },
- i: noop,
- o: noop,
- d(detaching) {
- if (detaching) {
- detach(div2);
- }
- if (if_block0)
- if_block0.d();
- if (if_block1)
- if_block1.d();
- if (if_block2)
- if_block2.d();
- ctx[13](null);
- ctx[14](null);
- mounted = false;
- dispose();
- }
- };
-}
-function instance$1($$self, $$props, $$invalidate) {
- let { file } = $$props;
- let { plugin } = $$props;
- let { leaf } = $$props;
- let { shouldRender = true } = $$props;
- let editorEl;
- let containerEl;
- let title;
- let rendered = false;
- let createdLeaf;
- let unloadTimeout = null;
- let editorHeight = 100;
- let isDestroying = false;
- let isCollapsed = false;
- onMount(() => {
- if (file instanceof require$$0.TFile) {
- $$invalidate(5, title = file.basename);
- }
- });
- console.log(shouldRender, rendered);
- onDestroy(() => {
- isDestroying = true;
- if (unloadTimeout) {
- window.clearTimeout(unloadTimeout);
- }
- if (rendered && createdLeaf) {
- unloadEditor();
- }
- });
- function showEditor() {
- if (!(file instanceof require$$0.TFile))
- return;
- if (rendered)
- return;
- if (isDestroying)
- return;
- if (unloadTimeout) {
- window.clearTimeout(unloadTimeout);
- unloadTimeout = null;
- }
- try {
- const fileName = file instanceof require$$0.TFile ? file.basename : "unknown";
- console.log(`Loading editor for ${fileName}`);
- [createdLeaf] = spawnLeafView(plugin, editorEl, leaf);
- createdLeaf.setPinned(true);
- createdLeaf.setViewState({
- type: "markdown",
- state: {
- file: file.path,
- mode: "source",
- source: false,
- backlinks: !plugin.settings.hideBacklinks,
- backlinkOpts: {
- collapseAll: false,
- extraContext: false,
- sortOrder: "alphabetical",
- showSearch: false,
- searchQuery: "",
- backlinkCollapsed: false,
- unlinkedCollapsed: true
- }
- }
- });
- createdLeaf.parentLeaf = leaf;
- $$invalidate(3, rendered = true);
- const timeout = window.setTimeout(
- () => {
- var _a, _b, _c;
- if (createdLeaf && containerEl) {
- if (!(createdLeaf.view instanceof require$$0.MarkdownView))
- return;
- const actualHeight = (_c = (_b = (_a = createdLeaf.view.editMode) === null || _a === void 0 ? void 0 : _a.editor) === null || _b === void 0 ? void 0 : _b.cm) === null || _c === void 0 ? void 0 : _c.dom.innerHeight;
- if (actualHeight > 0) {
- $$invalidate(6, editorHeight = actualHeight);
- $$invalidate(4, containerEl.style.minHeight = `${editorHeight}px`, containerEl);
- window.clearTimeout(timeout);
- }
- }
- },
- 400
- );
- } catch (error) {
- console.error("Error creating leaf view:", error);
- }
- }
- function scheduleUnload() {
- if (unloadTimeout) {
- window.clearTimeout(unloadTimeout);
- }
- unloadTimeout = window.setTimeout(
- () => {
- if (!shouldRender && rendered) {
- unloadEditor();
- }
- },
- 1e3
- );
- }
- function unloadEditor() {
- if (!rendered || !createdLeaf)
- return;
- try {
- const fileName = file instanceof require$$0.TFile ? file.basename : "unknown";
- console.log(`Unloading editor for ${fileName}`);
- if (createdLeaf.detach) {
- createdLeaf.detach();
- }
- if (editorEl) {
- editorEl.empty();
- }
- $$invalidate(3, rendered = false);
- } catch (error) {
- console.error(
- "Error unloading editor:",
- error
- );
- }
- }
- function handleFileIconClick() {
- if (!(file instanceof require$$0.TFile))
- return;
- if (leaf && !(leaf === null || leaf === void 0 ? void 0 : leaf.pinned)) {
- leaf.openFile(file);
- } else
- plugin.app.workspace.getLeaf(false).openFile(file);
- }
- function handleEditorClick() {
- var _a, _b;
- const editor = (_b = (_a = createdLeaf === null || createdLeaf === void 0 ? void 0 : createdLeaf.view) === null || _a === void 0 ? void 0 : _a.editMode) === null || _b === void 0 ? void 0 : _b.editor;
- if (editor && !editor.hasFocus()) {
- editor.focus();
- }
- }
- function toggleCollapse() {
- $$invalidate(7, isCollapsed = !isCollapsed);
- }
- function div0_binding($$value) {
- binding_callbacks$1[$$value ? "unshift" : "push"](() => {
- editorEl = $$value;
- $$invalidate(2, editorEl);
- });
- }
- function div2_binding($$value) {
- binding_callbacks$1[$$value ? "unshift" : "push"](() => {
- containerEl = $$value;
- $$invalidate(4, containerEl);
- });
- }
- $$self.$$set = ($$props2) => {
- if ("file" in $$props2)
- $$invalidate(0, file = $$props2.file);
- if ("plugin" in $$props2)
- $$invalidate(11, plugin = $$props2.plugin);
- if ("leaf" in $$props2)
- $$invalidate(12, leaf = $$props2.leaf);
- if ("shouldRender" in $$props2)
- $$invalidate(1, shouldRender = $$props2.shouldRender);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty & /*editorEl, shouldRender, rendered*/
- 14) {
- if (editorEl && shouldRender && !rendered) {
- showEditor();
- } else if (editorEl && !shouldRender && rendered) {
- scheduleUnload();
- }
- }
- };
- return [
- file,
- shouldRender,
- editorEl,
- rendered,
- containerEl,
- title,
- editorHeight,
- isCollapsed,
- handleFileIconClick,
- handleEditorClick,
- toggleCollapse,
- plugin,
- leaf,
- div0_binding,
- div2_binding
- ];
-}
-class DailyNote extends SvelteComponent {
- constructor(options) {
- super();
- init(this, options, instance$1, create_fragment$1, safe_not_equal, {
- file: 0,
- plugin: 11,
- leaf: 12,
- shouldRender: 1
- });
- }
-}
-function run(fn) {
- return fn();
-}
-function run_all(fns) {
- fns.forEach(run);
-}
-const dirty_components = [];
-const binding_callbacks = [];
-const render_callbacks = [];
-const flush_callbacks = [];
-const resolved_promise = Promise.resolve();
-let update_scheduled = false;
-function schedule_update() {
- if (!update_scheduled) {
- update_scheduled = true;
- resolved_promise.then(flush);
- }
-}
-function tick() {
- schedule_update();
- return resolved_promise;
-}
-function add_render_callback(fn) {
- render_callbacks.push(fn);
-}
-const seen_callbacks = /* @__PURE__ */ new Set();
-let flushidx = 0;
-function flush() {
- do {
- while (flushidx < dirty_components.length) {
- const component = dirty_components[flushidx];
- flushidx++;
- update(component.$$);
- }
- dirty_components.length = 0;
- flushidx = 0;
- while (binding_callbacks.length)
- binding_callbacks.pop()();
- for (let i = 0; i < render_callbacks.length; i += 1) {
- const callback = render_callbacks[i];
- if (!seen_callbacks.has(callback)) {
- seen_callbacks.add(callback);
- callback();
- }
- }
- render_callbacks.length = 0;
- } while (dirty_components.length);
- while (flush_callbacks.length) {
- flush_callbacks.pop()();
- }
- update_scheduled = false;
- seen_callbacks.clear();
-}
-function update($$) {
- if ($$.fragment !== null) {
- $$.update();
- run_all($$.before_update);
- const dirty = $$.dirty;
- $$.dirty = [-1];
- $$.fragment && $$.fragment.p($$.ctx, dirty);
- $$.after_update.forEach(add_render_callback);
- }
-}
-const defaultOptions = {
- root: null,
- rootMargin: "0px",
- threshold: 0,
- unobserveOnEnter: false
-};
-const createEvent = (name, detail) => new CustomEvent(name, { detail });
-function inview(node, options = {}) {
- const { root, rootMargin, threshold, unobserveOnEnter } = Object.assign(Object.assign({}, defaultOptions), options);
- let prevPos = {
- x: void 0,
- y: void 0
- };
- let scrollDirection = {
- vertical: void 0,
- horizontal: void 0
- };
- if (typeof IntersectionObserver !== "undefined" && node) {
- const observer = new IntersectionObserver((entries, _observer) => {
- entries.forEach((singleEntry) => {
- if (prevPos.y > singleEntry.boundingClientRect.y) {
- scrollDirection.vertical = "up";
- } else {
- scrollDirection.vertical = "down";
- }
- if (prevPos.x > singleEntry.boundingClientRect.x) {
- scrollDirection.horizontal = "left";
- } else {
- scrollDirection.horizontal = "right";
- }
- prevPos = {
- y: singleEntry.boundingClientRect.y,
- x: singleEntry.boundingClientRect.x
- };
- const detail = {
- inView: singleEntry.isIntersecting,
- entry: singleEntry,
- scrollDirection,
- node,
- observer: _observer
- };
- node.dispatchEvent(createEvent("inview_change", detail));
- node.dispatchEvent(createEvent("change", detail));
- if (singleEntry.isIntersecting) {
- node.dispatchEvent(createEvent("inview_enter", detail));
- node.dispatchEvent(createEvent("enter", detail));
- unobserveOnEnter && _observer.unobserve(node);
- } else {
- node.dispatchEvent(createEvent("inview_leave", detail));
- node.dispatchEvent(createEvent("leave", detail));
- }
- });
- }, {
- root,
- rootMargin,
- threshold
- });
- tick().then(() => {
- node.dispatchEvent(createEvent("inview_init", { observer, node }));
- node.dispatchEvent(
- //@ts-expect-error only for backward compatibility
- createEvent("init", { observer, node })
- );
- });
- observer.observe(node);
- return {
- destroy() {
- observer.unobserve(node);
- }
- };
- }
-}
-class FileManager {
- constructor(options) {
- this.allFiles = [];
- this.filteredFiles = [];
- this.hasFetched = false;
- this.hasCurrentDay = true;
- this.cacheDailyNotes = {};
- this.options = options;
- this.fetchFiles();
- }
- /**
- * Helper method to parse time field and check if it's reverse
- * @param timeField The time field to parse
- * @returns An object containing isReverse flag and baseTimeField
- */
- parseTimeField(timeField) {
- const field = timeField || "mtime";
- const isReverse = field.endsWith("Reverse");
- const baseTimeField = isReverse ? field.replace("Reverse", "") : field;
- return { isReverse, baseTimeField };
- }
- /**
- * Helper method to sort files by time field
- * @param files The files to sort
- * @param timeField The time field to sort by
- * @returns Sorted files
- */
- sortFilesByTimeField(files, timeField) {
- const { isReverse, baseTimeField } = this.parseTimeField(timeField);
- return [...files].sort((a, b) => {
- if (baseTimeField === "name") {
- if (isReverse) {
- return b.name.localeCompare(a.name);
- }
- return a.name.localeCompare(b.name);
- }
- if (isReverse) {
- return a.stat[baseTimeField] - b.stat[baseTimeField];
- }
- return b.stat[baseTimeField] - a.stat[baseTimeField];
- });
- }
- fetchFiles() {
- if (this.hasFetched)
- return;
- switch (this.options.mode) {
- case "daily":
- this.fetchDailyNotes();
- break;
- case "folder":
- this.fetchFolderFiles();
- break;
- case "tag":
- this.fetchTaggedFiles();
- break;
- }
- this.hasFetched = true;
- this.checkDailyNote();
- this.filterFilesByRange();
- }
- fetchDailyNotes() {
- this.cacheDailyNotes = getAllDailyNotes_1();
- const notes = Object.values(this.cacheDailyNotes);
- const { isReverse, baseTimeField } = this.parseTimeField(
- this.options.timeField
- );
- if (baseTimeField === "name") {
- this.allFiles = [...notes].sort((a, b) => {
- const result = a.name.localeCompare(b.name);
- return isReverse ? -result : result;
- });
- } else {
- for (const string of Object.keys(this.cacheDailyNotes).sort().reverse()) {
- this.allFiles.push(this.cacheDailyNotes[string]);
- }
- if (baseTimeField !== "ctime" && baseTimeField !== "mtime") {
- this.allFiles = this.sortFilesByTimeField(
- this.allFiles,
- this.options.timeField
- );
- }
- }
- }
- fetchFolderFiles() {
- if (!this.options.target || !this.options.app)
- return;
- const allFiles = this.options.app.vault.getMarkdownFiles();
- this.allFiles = allFiles.filter((file) => {
- var _a;
- const folderPath = ((_a = file.parent) == null ? void 0 : _a.path) || "";
- return folderPath === this.options.target || folderPath.startsWith(this.options.target + "/");
- });
- this.allFiles = this.sortFilesByTimeField(
- this.allFiles,
- this.options.timeField
- );
- }
- fetchTaggedFiles() {
- if (!this.options.target || !this.options.app)
- return;
- const allFiles = this.options.app.vault.getMarkdownFiles();
- const targetTag = this.options.target.startsWith("#") ? this.options.target : "#" + this.options.target;
- this.allFiles = allFiles.filter((file) => {
- var _a;
- const fileCache = (_a = this.options.app) == null ? void 0 : _a.metadataCache.getFileCache(file);
- if (!fileCache || !fileCache.tags)
- return false;
- return fileCache.tags.some((tag) => tag.tag === targetTag);
- });
- this.allFiles = this.sortFilesByTimeField(
- this.allFiles,
- this.options.timeField
- );
- }
- filterFilesByRange() {
- if (!this.options.timeRange) {
- this.filteredFiles = [...this.allFiles];
- return this.filteredFiles;
- }
- this.filteredFiles = [];
- if (this.options.timeRange === "all") {
- this.filteredFiles = [...this.allFiles];
- return this.filteredFiles;
- }
- if (this.options.mode === "daily") {
- this.filterDailyNotesByRange();
- } else {
- this.filterFilesByTimeRange();
- }
- return this.filteredFiles;
- }
- /**
- * Filter files by time range
- * Applicable to folder and tag modes
- */
- filterFilesByTimeRange() {
- const now = require$$0.moment();
- const { isReverse, baseTimeField } = this.parseTimeField(
- this.options.timeField
- );
- this.filteredFiles = this.allFiles.filter((file) => {
- const fileDate = require$$0.moment(file.stat[baseTimeField]);
- return this.isDateInRange(fileDate, now);
- });
- if (isReverse) {
- this.filteredFiles.reverse();
- }
- }
- /**
- * Filter daily notes by date
- * Applicable to daily mode
- */
- filterDailyNotesByRange() {
- const now = require$$0.moment();
- const fileFormat = getDailyNoteSettings_1().format || DEFAULT_DAILY_NOTE_FORMAT_1;
- this.filteredFiles = this.allFiles.filter((file) => {
- const fileDate = require$$0.moment(file.basename, fileFormat);
- return this.isDateInRange(fileDate, now);
- });
- }
- /**
- * Check if the file date is in the range
- * @param fileDate file date
- * @param now current date
- * @returns whether in the range
- */
- isDateInRange(fileDate, now) {
- switch (this.options.timeRange) {
- case "week":
- return fileDate.isSame(now, "week");
- case "month":
- return fileDate.isSame(now, "month");
- case "year":
- return fileDate.isSame(now, "year");
- case "last-week":
- return fileDate.isBetween(
- require$$0.moment().subtract(1, "week").startOf("week"),
- require$$0.moment().subtract(1, "week").endOf("week"),
- null,
- "[]"
- );
- case "last-month":
- return fileDate.isBetween(
- require$$0.moment().subtract(1, "month").startOf("month"),
- require$$0.moment().subtract(1, "month").endOf("month"),
- null,
- "[]"
- );
- case "last-year":
- return fileDate.isBetween(
- require$$0.moment().subtract(1, "year").startOf("year"),
- require$$0.moment().subtract(1, "year").endOf("year"),
- null,
- "[]"
- );
- case "quarter":
- return fileDate.isSame(now, "quarter");
- case "last-quarter":
- return fileDate.isBetween(
- require$$0.moment().subtract(1, "quarter").startOf("quarter"),
- require$$0.moment().subtract(1, "quarter").endOf("quarter"),
- null,
- "[]"
- );
- case "custom":
- if (this.options.customRange) {
- const startDate = require$$0.moment(this.options.customRange.start);
- const endDate = require$$0.moment(this.options.customRange.end);
- return fileDate.isBetween(startDate, endDate, null, "[]");
- }
- return false;
- default:
- return true;
- }
- }
- checkDailyNote() {
- if (this.options.mode !== "daily") {
- this.hasCurrentDay = true;
- return true;
- }
- this.cacheDailyNotes = getAllDailyNotes_1();
- const currentDate = require$$0.moment();
- const currentDailyNote = getDailyNote_1(
- currentDate,
- this.cacheDailyNotes
- );
- if (!currentDailyNote) {
- this.hasCurrentDay = false;
- return false;
- }
- if (this.hasCurrentDay === false) {
- this.allFiles = [];
- this.fetchDailyNotes();
- this.filterFilesByRange();
- }
- this.hasCurrentDay = true;
- return true;
- }
- async createNewDailyNote() {
- if (this.options.mode !== "daily" || this.hasCurrentDay) {
- return null;
- }
- const currentDate = require$$0.moment();
- const currentDailyNote = await createDailyNote_1(currentDate);
- if (currentDailyNote) {
- this.allFiles.push(currentDailyNote);
- this.allFiles = this.sortDailyNotes(this.allFiles);
- this.hasCurrentDay = true;
- this.filterFilesByRange();
- return currentDailyNote;
- }
- return null;
- }
- fileCreate(file) {
- if (this.options.mode === "daily") {
- this.handleDailyNoteCreate(file);
- } else if (this.options.mode === "folder") {
- this.handleFolderFileCreate(file);
- } else if (this.options.mode === "tag") {
- this.handleTaggedFileCreate(file);
- }
- }
- handleDailyNoteCreate(file) {
- const fileDate = getDateFromFile_1(file, "day");
- const fileFormat = getDailyNoteSettings_1().format || DEFAULT_DAILY_NOTE_FORMAT_1;
- if (!fileDate)
- return;
- if (this.filteredFiles.length === 0) {
- this.allFiles.push(file);
- this.allFiles = this.sortDailyNotes(this.allFiles);
- this.filterFilesByRange();
- return;
- }
- const lastFilteredFile = this.filteredFiles[this.filteredFiles.length - 1];
- const firstFilteredFile = this.filteredFiles[0];
- const lastFilteredFileDate = require$$0.moment(
- lastFilteredFile.basename,
- fileFormat
- );
- const firstFilteredFileDate = require$$0.moment(
- firstFilteredFile.basename,
- fileFormat
- );
- if (fileDate.isBetween(lastFilteredFileDate, firstFilteredFileDate)) {
- this.filteredFiles.push(file);
- this.filteredFiles = this.sortDailyNotes(this.filteredFiles);
- } else if (fileDate.isBefore(lastFilteredFileDate)) {
- this.allFiles.push(file);
- this.allFiles = this.sortDailyNotes(this.allFiles);
- this.filterFilesByRange();
- } else if (fileDate.isAfter(firstFilteredFileDate)) {
- this.filteredFiles.push(file);
- this.filteredFiles = this.sortDailyNotes(this.filteredFiles);
- }
- if (fileDate.isSame(require$$0.moment(), "day"))
- this.hasCurrentDay = true;
- }
- handleFolderFileCreate(file) {
- var _a;
- if (!this.options.target)
- return;
- const folderPath = ((_a = file.parent) == null ? void 0 : _a.path) || "";
- if (folderPath === this.options.target || folderPath.startsWith(this.options.target + "/")) {
- this.allFiles.push(file);
- this.allFiles = this.sortFilesByTimeField(
- this.allFiles,
- this.options.timeField
- );
- this.filterFilesByRange();
- }
- }
- handleTaggedFileCreate(file) {
- if (!this.options.target || !this.options.app)
- return;
- const targetTag = this.options.target.startsWith("#") ? this.options.target : "#" + this.options.target;
- const fileCache = this.options.app.metadataCache.getFileCache(file);
- if (!fileCache || !fileCache.tags)
- return;
- if (fileCache.tags.some((tag) => tag.tag === targetTag)) {
- this.allFiles.push(file);
- this.allFiles = this.sortFilesByTimeField(
- this.allFiles,
- this.options.timeField
- );
- this.filterFilesByRange();
- }
- }
- fileDelete(file) {
- if (this.options.mode === "daily" && getDateFromFile_1(file, "day")) {
- this.filteredFiles = this.filteredFiles.filter((f) => {
- return f.basename !== file.basename;
- });
- this.allFiles = this.allFiles.filter((f) => {
- return f.basename !== file.basename;
- });
- this.filterFilesByRange();
- this.checkDailyNote();
- } else {
- this.filteredFiles = this.filteredFiles.filter((f) => {
- return f.basename !== file.basename;
- });
- this.allFiles = this.allFiles.filter((f) => {
- return f.basename !== file.basename;
- });
- }
- }
- sortDailyNotes(notes) {
- const { isReverse, baseTimeField } = this.parseTimeField(
- this.options.timeField
- );
- if (baseTimeField === "name") {
- return [...notes].sort((a, b) => {
- if (isReverse) {
- return b.name.localeCompare(a.name);
- }
- return a.name.localeCompare(b.name);
- });
- }
- return this.sortFilesByTimeField(notes, this.options.timeField);
- }
- getAllFiles() {
- return this.allFiles;
- }
- getFilteredFiles() {
- return this.filteredFiles;
- }
- hasCurrentDayNote() {
- return this.hasCurrentDay;
- }
- updateOptions(options) {
- this.options = { ...this.options, ...options };
- if (options.timeRange || options.customRange) {
- this.filterFilesByRange();
- }
- if (options.mode || options.target) {
- this.allFiles = [];
- this.filteredFiles = [];
- this.hasFetched = false;
- this.fetchFiles();
- }
- }
-}
-function get_each_context(ctx, list, i) {
- const child_ctx = ctx.slice();
- child_ctx[29] = list[i];
- return child_ctx;
-}
-function create_if_block_2(ctx) {
- let div1;
- return {
- c() {
- div1 = element("div");
- div1.innerHTML = `No files found
`;
- attr(div1, "class", "dn-stock svelte-4q3cv7");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- },
- d(detaching) {
- if (detaching) {
- detach(div1);
- }
- }
- };
-}
-function create_if_block_1(ctx) {
- let div1;
- let mounted;
- let dispose;
- return {
- c() {
- div1 = element("div");
- div1.innerHTML = `Create a daily note for today ✍
`;
- attr(div1, "class", "dn-blank-day svelte-4q3cv7");
- attr(div1, "aria-hidden", "true");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- if (!mounted) {
- dispose = listen(
- div1,
- "click",
- /*createNewDailyNote*/
- ctx[12]
- );
- mounted = true;
- }
- },
- p: noop,
- d(detaching) {
- if (detaching) {
- detach(div1);
- }
- mounted = false;
- dispose();
- }
- };
-}
-function create_each_block(key_1, ctx) {
- let div;
- let dailynote;
- let inview_action;
- let current;
- let mounted;
- let dispose;
- dailynote = new DailyNote({
- props: {
- file: (
- /*file*/
- ctx[29]
- ),
- plugin: (
- /*plugin*/
- ctx[0]
- ),
- leaf: (
- /*leaf*/
- ctx[1]
- ),
- shouldRender: (
- /*visibleNotes*/
- ctx[4].has(
- /*file*/
- ctx[29].path
- )
- )
- }
- });
- function inview_change_handler(...args) {
- return (
- /*inview_change_handler*/
- ctx[22](
- /*file*/
- ctx[29],
- ...args
- )
- );
- }
- return {
- key: key_1,
- first: null,
- c() {
- div = element("div");
- create_component(dailynote.$$.fragment);
- attr(div, "class", "daily-note-wrapper svelte-4q3cv7");
- this.first = div;
- },
- m(target, anchor) {
- insert(target, div, anchor);
- mount_component(dailynote, div, null);
- current = true;
- if (!mounted) {
- dispose = [
- action_destroyer(inview_action = inview.call(null, div, {
- rootMargin: "80%",
- unobserveOnEnter: false,
- root: (
- /*leaf*/
- ctx[1].view.contentEl
- )
- })),
- listen(div, "inview_change", inview_change_handler)
- ];
- mounted = true;
- }
- },
- p(new_ctx, dirty) {
- ctx = new_ctx;
- const dailynote_changes = {};
- if (dirty[0] & /*renderedFiles*/
- 64)
- dailynote_changes.file = /*file*/
- ctx[29];
- if (dirty[0] & /*plugin*/
- 1)
- dailynote_changes.plugin = /*plugin*/
- ctx[0];
- if (dirty[0] & /*leaf*/
- 2)
- dailynote_changes.leaf = /*leaf*/
- ctx[1];
- if (dirty[0] & /*visibleNotes, renderedFiles*/
- 80)
- dailynote_changes.shouldRender = /*visibleNotes*/
- ctx[4].has(
- /*file*/
- ctx[29].path
- );
- dailynote.$set(dailynote_changes);
- if (inview_action && is_function(inview_action.update) && dirty[0] & /*leaf*/
- 2)
- inview_action.update.call(null, {
- rootMargin: "80%",
- unobserveOnEnter: false,
- root: (
- /*leaf*/
- ctx[1].view.contentEl
- )
- });
- },
- i(local) {
- if (current)
- return;
- transition_in(dailynote.$$.fragment, local);
- current = true;
- },
- o(local) {
- transition_out(dailynote.$$.fragment, local);
- current = false;
- },
- d(detaching) {
- if (detaching) {
- detach(div);
- }
- destroy_component(dailynote);
- mounted = false;
- run_all$1(dispose);
- }
- };
-}
-function create_if_block(ctx) {
- let div;
- return {
- c() {
- div = element("div");
- div.textContent = "—— No more of results ——";
- attr(div, "class", "no-more-text svelte-4q3cv7");
- },
- m(target, anchor) {
- insert(target, div, anchor);
- },
- d(detaching) {
- if (detaching) {
- detach(div);
- }
- }
- };
-}
-function create_fragment(ctx) {
- var _a;
- let div1;
- let t0;
- let show_if = (
- /*selectionMode*/
- ctx[3] === "daily" && !/*fileManager*/
- ((_a = ctx[5]) == null ? void 0 : _a.hasCurrentDayNote()) && /*selectedRange*/
- (ctx[2] === "all" || /*selectedRange*/
- ctx[2] === "week" || /*selectedRange*/
- ctx[2] === "month" || /*selectedRange*/
- ctx[2] === "year" || /*selectedRange*/
- ctx[2] === "quarter")
- );
- let t1;
- let each_blocks = [];
- let each_1_lookup = /* @__PURE__ */ new Map();
- let t2;
- let div0;
- let inview_action;
- let t3;
- let current;
- let mounted;
- let dispose;
- let if_block0 = (
- /*renderedFiles*/
- ctx[6].length === 0 && create_if_block_2()
- );
- let if_block1 = show_if && create_if_block_1(ctx);
- let each_value = ensure_array_like(
- /*renderedFiles*/
- ctx[6]
- );
- const get_key = (ctx2) => (
- /*file*/
- ctx2[29].path
- );
- for (let i = 0; i < each_value.length; i += 1) {
- let child_ctx = get_each_context(ctx, each_value, i);
- let key = get_key(child_ctx);
- each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));
- }
- let if_block2 = !/*hasMore*/
- ctx[7] && create_if_block();
- return {
- c() {
- div1 = element("div");
- if (if_block0)
- if_block0.c();
- t0 = space();
- if (if_block1)
- if_block1.c();
- t1 = space();
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].c();
- }
- t2 = space();
- div0 = element("div");
- t3 = space();
- if (if_block2)
- if_block2.c();
- attr(div0, "class", "dn-view-loader");
- attr(div1, "class", "daily-note-view");
- },
- m(target, anchor) {
- insert(target, div1, anchor);
- if (if_block0)
- if_block0.m(div1, null);
- append(div1, t0);
- if (if_block1)
- if_block1.m(div1, null);
- append(div1, t1);
- for (let i = 0; i < each_blocks.length; i += 1) {
- if (each_blocks[i]) {
- each_blocks[i].m(div1, null);
- }
- }
- append(div1, t2);
- append(div1, div0);
- ctx[23](div0);
- append(div1, t3);
- if (if_block2)
- if_block2.m(div1, null);
- current = true;
- if (!mounted) {
- dispose = [
- action_destroyer(inview_action = inview.call(null, div0, { root: (
- /*leaf*/
- ctx[1].view.containerEl
- ) })),
- listen(
- div0,
- "inview_init",
- /*startFillViewport*/
- ctx[9]
- ),
- listen(
- div0,
- "inview_change",
- /*infiniteHandler*/
- ctx[11]
- ),
- listen(
- div0,
- "inview_leave",
- /*stopFillViewport*/
- ctx[10]
- )
- ];
- mounted = true;
- }
- },
- p(ctx2, dirty) {
- var _a2;
- if (
- /*renderedFiles*/
- ctx2[6].length === 0
- ) {
- if (if_block0)
- ;
- else {
- if_block0 = create_if_block_2();
- if_block0.c();
- if_block0.m(div1, t0);
- }
- } else if (if_block0) {
- if_block0.d(1);
- if_block0 = null;
- }
- if (dirty[0] & /*selectionMode, fileManager, selectedRange*/
- 44)
- show_if = /*selectionMode*/
- ctx2[3] === "daily" && !/*fileManager*/
- ((_a2 = ctx2[5]) == null ? void 0 : _a2.hasCurrentDayNote()) && /*selectedRange*/
- (ctx2[2] === "all" || /*selectedRange*/
- ctx2[2] === "week" || /*selectedRange*/
- ctx2[2] === "month" || /*selectedRange*/
- ctx2[2] === "year" || /*selectedRange*/
- ctx2[2] === "quarter");
- if (show_if) {
- if (if_block1) {
- if_block1.p(ctx2, dirty);
- } else {
- if_block1 = create_if_block_1(ctx2);
- if_block1.c();
- if_block1.m(div1, t1);
- }
- } else if (if_block1) {
- if_block1.d(1);
- if_block1 = null;
- }
- if (dirty[0] & /*leaf, handleNoteVisibilityChange, renderedFiles, plugin, visibleNotes*/
- 8275) {
- each_value = ensure_array_like(
- /*renderedFiles*/
- ctx2[6]
- );
- group_outros();
- each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx2, each_value, each_1_lookup, div1, outro_and_destroy_block, create_each_block, t2, get_each_context);
- check_outros();
- }
- if (inview_action && is_function(inview_action.update) && dirty[0] & /*leaf*/
- 2)
- inview_action.update.call(null, { root: (
- /*leaf*/
- ctx2[1].view.containerEl
- ) });
- if (!/*hasMore*/
- ctx2[7]) {
- if (if_block2)
- ;
- else {
- if_block2 = create_if_block();
- if_block2.c();
- if_block2.m(div1, null);
- }
- } else if (if_block2) {
- if_block2.d(1);
- if_block2 = null;
- }
- },
- i(local) {
- if (current)
- return;
- for (let i = 0; i < each_value.length; i += 1) {
- transition_in(each_blocks[i]);
- }
- current = true;
- },
- o(local) {
- for (let i = 0; i < each_blocks.length; i += 1) {
- transition_out(each_blocks[i]);
- }
- current = false;
- },
- d(detaching) {
- if (detaching) {
- detach(div1);
- }
- if (if_block0)
- if_block0.d();
- if (if_block1)
- if_block1.d();
- for (let i = 0; i < each_blocks.length; i += 1) {
- each_blocks[i].d();
- }
- ctx[23](null);
- if (if_block2)
- if_block2.d();
- mounted = false;
- run_all$1(dispose);
- }
- };
-}
-const size = 1;
-function instance($$self, $$props, $$invalidate) {
- let fileManagerOptions;
- let { plugin } = $$props;
- let { leaf } = $$props;
- let { selectedRange = "all" } = $$props;
- let { customRange = null } = $$props;
- let { selectionMode = "daily" } = $$props;
- let { target = "" } = $$props;
- let { timeField = "mtime" } = $$props;
- let intervalId;
- let renderedFiles = [];
- let filteredFiles = [];
- let visibleNotes = /* @__PURE__ */ new Set();
- let hasMore = true;
- let firstLoaded = true;
- let loaderRef;
- let fileManager;
- onMount(() => {
- $$invalidate(5, fileManager = new FileManager(fileManagerOptions));
- $$invalidate(21, filteredFiles = fileManager.getFilteredFiles());
- $$invalidate(7, hasMore = filteredFiles.length > 0);
- startFillViewport();
- updateTitleElement();
- });
- function updateTitleElement() {
- if (!leaf || !leaf.view || !leaf.view.titleEl)
- return;
- const titleEl = leaf.view.titleEl;
- titleEl.empty();
- let titleText = "";
- if (selectionMode === "daily" && selectedRange !== "all") {
- if (selectedRange === "custom" && customRange) {
- titleText = `Showing notes from: ${require$$0.moment(customRange.start).format("YYYY-MM-DD")} to ${require$$0.moment(customRange.end).format("YYYY-MM-DD")}`;
- } else {
- titleText = `Showing notes for: ${selectedRange}`;
- }
- } else if (selectionMode === "folder") {
- titleText = `Showing files from folder: ${target}`;
- if (selectedRange !== "all") {
- titleText += ` (${timeField === "ctime" ? "created" : "modified"} ${selectedRange})`;
- }
- } else if (selectionMode === "tag") {
- titleText = `Showing files with tag: ${target}`;
- if (selectedRange !== "all") {
- titleText += ` (${timeField === "ctime" ? "created" : "modified"} ${selectedRange})`;
- }
- }
- if (titleText) {
- titleEl.setText(titleText);
- } else {
- titleEl.setText("Daily Notes");
- }
- }
- function startFillViewport() {
- if (!intervalId) {
- intervalId = setInterval(infiniteHandler, 1);
- }
- }
- function stopFillViewport() {
- clearInterval(intervalId);
- intervalId = null;
- }
- function infiniteHandler() {
- if (leaf.height === 0)
- return;
- if (!fileManager || !hasMore)
- return;
- if (filteredFiles.length === 0) {
- $$invalidate(7, hasMore = false);
- } else {
- $$invalidate(6, renderedFiles = [...renderedFiles, ...filteredFiles.splice(0, size)]);
- if (firstLoaded) {
- window.setTimeout(
- () => {
- ensureViewFilled();
- firstLoaded = false;
- },
- 100
- );
- }
- }
- }
- function ensureViewFilled() {
- if (!loaderRef)
- return;
- const loaderRect = loaderRef.getBoundingClientRect();
- const viewportHeight = window.innerHeight;
- const contentHeight = leaf.view.contentEl.clientHeight || leaf.view.contentEl.innerHeight || viewportHeight;
- const effectiveHeight = Math.max(viewportHeight, contentHeight) + 200;
- if (loaderRect.top < effectiveHeight) {
- infiniteHandler();
- window.setTimeout(
- () => {
- if (hasMore && loaderRef && loaderRef.getBoundingClientRect().top < effectiveHeight) {
- ensureViewFilled();
- }
- },
- 50
- );
- }
- }
- function createNewDailyNote() {
- return __awaiter(this, void 0, void 0, function* () {
- const newNote = yield fileManager.createNewDailyNote();
- if (newNote) {
- $$invalidate(6, renderedFiles = [newNote, ...renderedFiles]);
- visibleNotes.add(newNote.path);
- $$invalidate(4, visibleNotes);
- }
- });
- }
- function tick2() {
- check();
- $$invalidate(6, renderedFiles), $$invalidate(5, fileManager), $$invalidate(2, selectedRange), $$invalidate(14, customRange), $$invalidate(3, selectionMode), $$invalidate(15, target), $$invalidate(16, timeField), $$invalidate(4, visibleNotes), $$invalidate(21, filteredFiles);
- }
- function check() {
- const hadDailyNote = fileManager.hasCurrentDayNote();
- fileManager.checkDailyNote();
- const hasDailyNote = fileManager.hasCurrentDayNote();
- if (hadDailyNote !== hasDailyNote || selectionMode === "daily" && selectedRange !== "all") {
- $$invalidate(21, filteredFiles = fileManager.getFilteredFiles());
- if (selectionMode === "daily") {
- $$invalidate(6, renderedFiles = []);
- visibleNotes.clear();
- $$invalidate(7, hasMore = filteredFiles.length > 0);
- firstLoaded = true;
- startFillViewport();
- }
- }
- }
- function fileCreate(file) {
- fileManager.fileCreate(file);
- if (selectionMode === "daily") {
- const filteredFiles2 = fileManager.getFilteredFiles();
- if (filteredFiles2.some((f) => f.basename === file.basename) && !renderedFiles.some((f) => f.basename === file.basename)) {
- $$invalidate(6, renderedFiles = [file, ...renderedFiles]);
- visibleNotes.add(file.path);
- $$invalidate(4, visibleNotes);
- }
- } else {
- $$invalidate(6, renderedFiles = fileManager.getFilteredFiles().slice(0, renderedFiles.length));
- }
- }
- function fileDelete(file) {
- fileManager.fileDelete(file);
- $$invalidate(6, renderedFiles = renderedFiles.filter((dailyNote) => {
- return dailyNote.basename !== file.basename;
- }));
- if (visibleNotes.has(file.path)) {
- visibleNotes.delete(file.path);
- $$invalidate(4, visibleNotes);
- }
- }
- function handleNoteVisibilityChange(file, isVisible) {
- console.log("inview", isVisible);
- if (isVisible) {
- visibleNotes.add(file.path);
- } else {
- visibleNotes.delete(file.path);
- }
- $$invalidate(4, visibleNotes);
- }
- const inview_change_handler = (file, { detail }) => handleNoteVisibilityChange(file, detail.inView);
- function div0_binding($$value) {
- binding_callbacks$1[$$value ? "unshift" : "push"](() => {
- loaderRef = $$value;
- $$invalidate(8, loaderRef);
- });
- }
- $$self.$$set = ($$props2) => {
- if ("plugin" in $$props2)
- $$invalidate(0, plugin = $$props2.plugin);
- if ("leaf" in $$props2)
- $$invalidate(1, leaf = $$props2.leaf);
- if ("selectedRange" in $$props2)
- $$invalidate(2, selectedRange = $$props2.selectedRange);
- if ("customRange" in $$props2)
- $$invalidate(14, customRange = $$props2.customRange);
- if ("selectionMode" in $$props2)
- $$invalidate(3, selectionMode = $$props2.selectionMode);
- if ("target" in $$props2)
- $$invalidate(15, target = $$props2.target);
- if ("timeField" in $$props2)
- $$invalidate(16, timeField = $$props2.timeField);
- };
- $$self.$$.update = () => {
- if ($$self.$$.dirty[0] & /*selectionMode, target, selectedRange, customRange, plugin, timeField*/
- 114701) {
- fileManagerOptions = {
- mode: selectionMode,
- target,
- timeRange: selectedRange,
- customRange,
- app: plugin.app,
- timeField
- };
- }
- if ($$self.$$.dirty[0] & /*fileManager, selectedRange, customRange, selectionMode, target, timeField, visibleNotes, filteredFiles*/
- 2211900) {
- if (fileManager && (selectedRange !== fileManager.options.timeRange || customRange !== fileManager.options.customRange || selectionMode !== fileManager.options.mode || target !== fileManager.options.target || timeField !== fileManager.options.timeField)) {
- fileManager.updateOptions({
- timeRange: selectedRange,
- customRange,
- mode: selectionMode,
- target,
- timeField
- });
- $$invalidate(6, renderedFiles = []);
- visibleNotes.clear();
- $$invalidate(21, filteredFiles = fileManager.getFilteredFiles());
- $$invalidate(7, hasMore = filteredFiles.length > 0);
- firstLoaded = true;
- startFillViewport();
- updateTitleElement();
- }
- }
- };
- return [
- plugin,
- leaf,
- selectedRange,
- selectionMode,
- visibleNotes,
- fileManager,
- renderedFiles,
- hasMore,
- loaderRef,
- startFillViewport,
- stopFillViewport,
- infiniteHandler,
- createNewDailyNote,
- handleNoteVisibilityChange,
- customRange,
- target,
- timeField,
- tick2,
- check,
- fileCreate,
- fileDelete,
- filteredFiles,
- inview_change_handler,
- div0_binding
- ];
-}
-class DailyNoteEditorView extends SvelteComponent {
- constructor(options) {
- super();
- init(
- this,
- options,
- instance,
- create_fragment,
- safe_not_equal,
- {
- plugin: 0,
- leaf: 1,
- selectedRange: 2,
- customRange: 14,
- selectionMode: 3,
- target: 15,
- timeField: 16,
- tick: 17,
- check: 18,
- fileCreate: 19,
- fileDelete: 20
- },
- null,
- [-1, -1]
- );
- }
- get tick() {
- return this.$$.ctx[17];
- }
- get check() {
- return this.$$.ctx[18];
- }
- get fileCreate() {
- return this.$$.ctx[19];
- }
- get fileDelete() {
- return this.$$.ctx[20];
- }
-}
-const DAILY_NOTE_VIEW_TYPE = "daily-note-editor-view";
-class DailyNoteView extends require$$0.ItemView {
- constructor(leaf, plugin) {
- super(leaf);
- this.selectedDaysRange = "all";
- this.selectionMode = "daily";
- this.target = "";
- this.timeField = "mtime";
- this.customRange = null;
- this.getMode = () => {
- return "source";
- };
- this.onFileCreate = (file) => {
- if (file instanceof require$$0.TFile)
- this.view.fileCreate(file);
- };
- this.onFileDelete = (file) => {
- if (file instanceof require$$0.TFile)
- this.view.fileDelete(file);
- };
- this.plugin = plugin;
- this.scope = new require$$0.Scope(plugin.app.scope);
- }
- getViewType() {
- return DAILY_NOTE_VIEW_TYPE;
- }
- getDisplayText() {
- if (this.selectionMode === "daily") {
- return "Daily Notes";
- } else if (this.selectionMode === "folder") {
- return `Folder: ${this.target}`;
- } else if (this.selectionMode === "tag") {
- return `Tag: ${this.target}`;
- }
- return "Notes";
- }
- getIcon() {
- if (this.selectionMode === "daily") {
- return "calendar";
- } else if (this.selectionMode === "folder") {
- return "folder";
- } else if (this.selectionMode === "tag") {
- return "tag";
- }
- return "document";
- }
- setSelectedRange(range) {
- this.selectedDaysRange = range;
- if (this.view) {
- if (range === "custom") {
- this.view.$set({
- selectedRange: range,
- customRange: this.customRange
- });
- } else {
- this.view.$set({ selectedRange: range });
- }
- }
- }
- setSelectionMode(mode, target = "") {
- this.selectionMode = mode;
- this.target = target;
- if (this.view) {
- this.view.$set({
- selectionMode: mode,
- target
- });
- }
- }
- saveCurrentSelectionAsPreset() {
- if (this.selectionMode !== "daily" && this.target) {
- const existingPresetIndex = this.plugin.settings.preset.findIndex(
- (p) => p.type === this.selectionMode && p.target === this.target
- );
- if (existingPresetIndex === -1) {
- this.plugin.settings.preset.push({
- type: this.selectionMode,
- target: this.target
- });
- this.plugin.saveSettings();
- }
- }
- }
- getState() {
- const state2 = super.getState();
- return {
- ...state2,
- selectionMode: this.selectionMode,
- target: this.target,
- timeField: this.timeField,
- selectedRange: this.selectedDaysRange,
- customRange: this.customRange
- };
- }
- async setState(state2, result) {
- await super.setState(state2, result);
- if (state2 && typeof state2 === "object" && !this.view) {
- const customState = state2;
- if (customState.selectionMode)
- this.selectionMode = customState.selectionMode;
- if (customState.target)
- this.target = customState.target;
- if (customState.timeField)
- this.timeField = customState.timeField;
- if (customState.selectedRange)
- this.selectedDaysRange = customState.selectedRange;
- if (customState.customRange)
- this.customRange = customState.customRange;
- this.view = new DailyNoteEditorView({
- target: this.contentEl,
- props: {
- plugin: this.plugin,
- leaf: this.leaf,
- selectedRange: this.selectedDaysRange,
- customRange: this.customRange,
- selectionMode: this.selectionMode,
- target: this.target,
- timeField: this.timeField
- }
- });
- this.app.workspace.onLayoutReady(this.view.tick.bind(this));
- this.registerInterval(
- window.setInterval(async () => {
- this.view.check();
- }, 1e3 * 60 * 60)
- );
- }
- }
- setTimeField(field) {
- this.timeField = field;
- if (this.view) {
- this.view.$set({ timeField: field });
- }
- }
- openDailyNoteEditor() {
- this.plugin.openDailyNoteEditor();
- }
- async onOpen() {
- this.scope.register(["Mod"], "f", (e) => {
- });
- this.addAction("clock", "Select time field", (e) => {
- const menu = new require$$0.Menu();
- const addTimeFieldOption = (title, field) => {
- menu.addItem((item) => {
- item.setTitle(title);
- item.setChecked(this.timeField === field);
- item.onClick(() => {
- this.setTimeField(field);
- });
- });
- };
- addTimeFieldOption("Creation Time", "ctime");
- addTimeFieldOption("Modification Time", "mtime");
- addTimeFieldOption("Creation Time (Reverse)", "ctimeReverse");
- addTimeFieldOption("Modification Time (Reverse)", "mtimeReverse");
- addTimeFieldOption("Name (A-Z)", "name");
- addTimeFieldOption("Name (Z-A)", "nameReverse");
- menu.showAtMouseEvent(e);
- });
- this.addAction("layers-2", "Select view mode", (e) => {
- const menu = new require$$0.Menu();
- const addModeOption = (title, mode) => {
- menu.addItem((item) => {
- item.setTitle(title);
- item.setChecked(
- this.selectionMode === mode && !this.target
- );
- item.onClick(() => {
- if (mode === "daily") {
- this.setSelectionMode(mode);
- } else {
- const modal = new SelectTargetModal(
- this.plugin.app,
- mode,
- (target) => {
- this.setSelectionMode(mode, target);
- this.saveCurrentSelectionAsPreset();
- }
- );
- modal.open();
- }
- });
- });
- };
- addModeOption("Daily Notes", "daily");
- addModeOption("Folder", "folder");
- addModeOption("Tag", "tag");
- if (this.plugin.settings.preset.length > 0) {
- menu.addSeparator();
- menu.addItem((item) => {
- item.setTitle("Saved Presets");
- item.setDisabled(true);
- });
- for (const preset of this.plugin.settings.preset) {
- const title = preset.type === "folder" ? `Folder: ${preset.target}` : `Tag: ${preset.target}`;
- menu.addItem((item) => {
- item.setTitle(title);
- item.setChecked(
- this.selectionMode === preset.type && this.target === preset.target
- );
- item.onClick(() => {
- this.setSelectionMode(preset.type, preset.target);
- });
- });
- }
- }
- menu.showAtMouseEvent(e);
- });
- this.addAction("calendar-range", "Select date range", (e) => {
- const menu = new require$$0.Menu();
- const addRangeOption = (title, range) => {
- menu.addItem((item) => {
- item.setTitle(title);
- item.setChecked(this.selectedDaysRange === range);
- item.onClick(() => {
- this.setSelectedRange(range);
- });
- });
- };
- addRangeOption("All Notes", "all");
- addRangeOption("This Week", "week");
- addRangeOption("This Month", "month");
- addRangeOption("This Year", "year");
- addRangeOption("Last Week", "last-week");
- addRangeOption("Last Month", "last-month");
- addRangeOption("Last Year", "last-year");
- addRangeOption("This Quarter", "quarter");
- addRangeOption("Last Quarter", "last-quarter");
- menu.addSeparator();
- menu.addItem((item) => {
- item.setTitle("Custom Date Range");
- item.setChecked(this.selectedDaysRange === "custom");
- item.onClick(() => {
- const modal = new CustomRangeModal(this.app, (range) => {
- this.customRange = range;
- this.setSelectedRange("custom");
- });
- modal.open();
- });
- });
- menu.showAtMouseEvent(e);
- });
- this.addAction("refresh", "Refresh", () => {
- if (this.view) {
- this.view.check();
- this.view.tick();
- this.view.$set({
- selectedRange: this.selectedDaysRange,
- customRange: this.customRange
- });
- }
- });
- this.app.vault.on("create", this.onFileCreate);
- this.app.vault.on("delete", this.onFileDelete);
- }
- onPaneMenu(menu, source) {
- if (source === "tab-header" || source === "more-options") {
- menu.addItem((item) => {
- item.setIcon(this.leaf.pinned ? "pin-off" : "pin");
- item.setTitle(this.leaf.pinned ? "Unpin" : "Pin");
- item.onClick(() => {
- this.leaf.togglePinned();
- });
- });
- }
- }
- /**
- * Refresh the view for a new day
- * This is called when the date changes (e.g., after midnight)
- */
- refreshForNewDay() {
- if (this.selectionMode === "daily") {
- if (this.view) {
- this.view.check();
- this.view.tick();
- this.view.$set({
- selectedRange: this.selectedDaysRange,
- customRange: this.customRange
- });
- }
- }
- }
-}
-class CustomRangeModal extends require$$0.Modal {
- constructor(app2, saveCallback) {
- super(app2);
- this.saveCallback = saveCallback;
- this.startDate = /* @__PURE__ */ new Date();
- this.endDate = /* @__PURE__ */ new Date();
- }
- onOpen() {
- const { contentEl } = this;
- contentEl.createEl("h2", { text: "Select Custom Date Range" });
- const startDateContainer = contentEl.createEl("div", {
- cls: "custom-range-date-container"
- });
- startDateContainer.createEl("span", { text: "Start Date: " });
- const startDatePicker = startDateContainer.createEl("input", {
- type: "date",
- value: this.formatDate(this.startDate)
- });
- startDatePicker.addEventListener("change", (e) => {
- this.startDate = new Date(e.target.value);
- });
- const endDateContainer = contentEl.createEl("div", {
- cls: "custom-range-date-container"
- });
- endDateContainer.createEl("span", { text: "End Date: " });
- const endDatePicker = endDateContainer.createEl("input", {
- type: "date",
- value: this.formatDate(this.endDate)
- });
- endDatePicker.addEventListener("change", (e) => {
- this.endDate = new Date(e.target.value);
- });
- const buttonContainer = contentEl.createEl("div", {
- cls: "custom-range-button-container"
- });
- new require$$0.ButtonComponent(buttonContainer).setButtonText("Cancel").onClick(() => {
- this.close();
- });
- new require$$0.ButtonComponent(buttonContainer).setButtonText("Confirm").setCta().onClick(() => {
- this.saveCallback({
- start: this.startDate,
- end: this.endDate
- });
- this.close();
- });
- }
- formatDate(date) {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
- }
- onClose() {
- this.contentEl.empty();
- }
-}
-class SelectTargetModal extends require$$0.Modal {
- constructor(app2, mode, saveCallback) {
- super(app2);
- this.mode = mode;
- this.saveCallback = saveCallback;
- }
- onOpen() {
- const { contentEl } = this;
- contentEl.empty();
- contentEl.createEl("h2", {
- text: this.mode === "folder" ? "Select Folder" : "Select Tag"
- });
- const form = contentEl.createEl("form");
- form.addEventListener("submit", (e) => {
- e.preventDefault();
- this.save();
- });
- const targetSetting = form.createDiv();
- targetSetting.addClass("setting-item");
- const targetSettingInfo = targetSetting.createDiv();
- targetSettingInfo.addClass("setting-item-info");
- targetSettingInfo.createEl("div", {
- text: this.mode === "folder" ? "Folder Path" : "Tag Name",
- cls: "setting-item-name"
- });
- targetSettingInfo.createEl("div", {
- text: this.mode === "folder" ? "Enter the path to the folder (e.g., 'folder/subfolder')" : "Enter the tag name without the '#' (e.g., 'tag')",
- cls: "setting-item-description"
- });
- const targetSettingControl = targetSetting.createDiv();
- targetSettingControl.addClass("setting-item-control");
- this.targetInput = targetSettingControl.createEl("input", {
- type: "text",
- value: ""
- });
- this.targetInput.addClass("target-input");
- const footerEl = contentEl.createDiv();
- footerEl.addClass("modal-button-container");
- footerEl.createEl("button", {
- text: "Cancel",
- cls: "mod-warning",
- attr: {
- type: "button"
- }
- }).addEventListener("click", () => {
- this.close();
- });
- footerEl.createEl("button", {
- text: "Save",
- cls: "mod-cta",
- attr: {
- type: "submit"
- }
- }).addEventListener("click", (e) => {
- e.preventDefault();
- this.save();
- });
- }
- save() {
- const target = this.targetInput.value.trim();
- if (target) {
- this.saveCallback(target);
- this.close();
- }
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
-}
-class DailyNoteViewPlugin extends require$$0.Plugin {
- async onload() {
- this.addSettingTab(new DailyNoteSettingTab(this.app, this));
- await this.loadSettings();
- this.patchWorkspace();
- this.patchWorkspaceLeaf();
- addIconList();
- this.lastCheckedDay = require$$0.moment().format("YYYY-MM-DD");
- this.settings.useArrowUpOrDownToNavigate && this.registerEditorExtension([
- createUpDownNavigationExtension({
- app: this.app,
- plugin: this
- })
- // setActiveEditorExt({ app: this.app, plugin: this }),
- ]);
- this.registerView(
- DAILY_NOTE_VIEW_TYPE,
- (leaf) => this.view = new DailyNoteView(leaf, this)
- );
- this.addRibbonIcon(
- "calendar-range",
- "Open Daily Note Editor",
- (evt) => this.openDailyNoteEditor()
- );
- this.addCommand({
- id: "open-daily-note-editor",
- name: "Open Daily Note Editor",
- callback: () => this.openDailyNoteEditor()
- });
- this.initCssRules();
- if (this.settings.createAndOpenOnStartup) {
- this.app.workspace.onLayoutReady(async () => {
- await this.ensureTodaysDailyNoteExists();
- if (this.app.workspace.getLeavesOfType(DAILY_NOTE_VIEW_TYPE).length > 0)
- return;
- await this.openDailyNoteEditor();
- });
- }
- this.registerInterval(
- window.setInterval(this.checkDayChange.bind(this), 1e3 * 60 * 15)
- );
- this.app.workspace.on("file-menu", (menu, file, source, leaf) => {
- if (file instanceof require$$0.TFolder) {
- menu.addItem((item) => {
- item.setIcon("calendar-range");
- item.setTitle("Open daily notes for this folder");
- item.onClick(() => {
- this.openFolderView(file.path);
- });
- });
- }
- });
- }
- onunload() {
- this.app.workspace.detachLeavesOfType(DAILY_NOTE_VIEW_TYPE);
- document.body.toggleClass("daily-notes-hide-frontmatter", false);
- document.body.toggleClass("daily-notes-hide-backlinks", false);
- }
- async openDailyNoteEditor() {
- const workspace = this.app.workspace;
- const leaf = workspace.getLeaf(true);
- await leaf.setViewState({ type: DAILY_NOTE_VIEW_TYPE });
- workspace.revealLeaf(leaf);
- }
- async openFolderView(folderPath, timeField = "mtime") {
- const workspace = this.app.workspace;
- const leaf = workspace.getLeaf(true);
- await leaf.setViewState({ type: DAILY_NOTE_VIEW_TYPE });
- const view2 = leaf.view;
- view2.setSelectionMode("folder", folderPath);
- view2.setTimeField(timeField);
- workspace.revealLeaf(leaf);
- }
- async openTagView(tagName, timeField = "mtime") {
- const workspace = this.app.workspace;
- const leaf = workspace.getLeaf(true);
- await leaf.setViewState({ type: DAILY_NOTE_VIEW_TYPE });
- const view2 = leaf.view;
- view2.setSelectionMode("tag", tagName);
- view2.setTimeField(timeField);
- workspace.revealLeaf(leaf);
- }
- async ensureTodaysDailyNoteExists() {
- try {
- const currentDate = require$$0.moment();
- const allDailyNotes = getAllDailyNotes_1();
- const currentDailyNote = getDailyNote_1(currentDate, allDailyNotes);
- if (!currentDailyNote) {
- await createDailyNote_1(currentDate);
- }
- } catch (error) {
- console.error("Failed to create daily note:", error);
- }
- }
- initCssRules() {
- document.body.toggleClass(
- "daily-notes-hide-frontmatter",
- this.settings.hideFrontmatter
- );
- document.body.toggleClass(
- "daily-notes-hide-backlinks",
- this.settings.hideBacklinks
- );
- }
- patchWorkspace() {
- let layoutChanging = false;
- const uninstaller = around(require$$0.Workspace.prototype, {
- getActiveViewOfType: (next) => function(t) {
- const result = next.call(this, t);
- if (!result) {
- if ((t == null ? void 0 : t.VIEW_TYPE) === "markdown") {
- const activeLeaf = this.activeLeaf;
- if ((activeLeaf == null ? void 0 : activeLeaf.view) instanceof DailyNoteView) {
- return activeLeaf.view.editMode;
- } else {
- return result;
- }
- }
- }
- return result;
- },
- changeLayout(old) {
- return async function(workspace) {
- layoutChanging = true;
- try {
- await old.call(this, workspace);
- } finally {
- layoutChanging = false;
- }
- };
- },
- iterateLeaves(old) {
- return function(arg1, arg2) {
- if (old.call(this, arg1, arg2))
- return true;
- const cb = typeof arg1 === "function" ? arg1 : arg2;
- const parent = typeof arg1 === "function" ? arg2 : arg1;
- if (!parent)
- return false;
- if (layoutChanging)
- return false;
- if (!require$$0.requireApiVersion("0.15.0")) {
- if (parent === this.app.workspace.rootSplit || require$$0.WorkspaceContainer && parent instanceof require$$0.WorkspaceContainer) {
- for (const popover of DailyNoteEditor.popoversForWindow(
- parent.win
- )) {
- if (old.call(this, cb, popover.rootSplit))
- return true;
- }
- }
- }
- return false;
- };
- },
- setActiveLeaf: (next) => function(e, t) {
- if (e.parentLeaf) {
- e.parentLeaf.activeTime = 17e11;
- next.call(this, e.parentLeaf, t);
- if (e.view.editMode) {
- this.activeEditor = e.view;
- e.parentLeaf.view.editMode = e.view;
- }
- return;
- }
- return next.call(this, e, t);
- }
- });
- this.register(uninstaller);
- }
- // Used for patch workspaceleaf pinned behaviors
- patchWorkspaceLeaf() {
- this.register(
- around(require$$0.WorkspaceLeaf.prototype, {
- getRoot(old) {
- return function() {
- const top = old.call(this);
- return (top == null ? void 0 : top.getRoot) === this.getRoot ? top : top == null ? void 0 : top.getRoot();
- };
- },
- setPinned(old) {
- return function(pinned) {
- old.call(this, pinned);
- if (isDailyNoteLeaf(this) && !pinned)
- this.setPinned(true);
- };
- },
- openFile(old) {
- return function(file, openState) {
- if (isDailyNoteLeaf(this)) {
- setTimeout(
- around(require$$0.Workspace.prototype, {
- recordMostRecentOpenedFile(old2) {
- return function(_file) {
- if (_file !== file) {
- return old2.call(this, _file);
- }
- };
- }
- }),
- 1
- );
- const recentFiles = this.app.plugins.plugins["recent-files-obsidian"];
- if (recentFiles)
- setTimeout(
- around(recentFiles, {
- shouldAddFile(old2) {
- return function(_file) {
- return _file !== file && old2.call(this, _file);
- };
- }
- }),
- 1
- );
- }
- return old.call(this, file, openState);
- };
- }
- })
- );
- }
- async loadSettings() {
- this.settings = Object.assign(
- {},
- DEFAULT_SETTINGS,
- await this.loadData()
- );
- }
- async saveSettings() {
- await this.saveData(this.settings);
- }
- async checkDayChange() {
- const currentDay = require$$0.moment().format("YYYY-MM-DD");
- if (currentDay !== this.lastCheckedDay) {
- this.lastCheckedDay = currentDay;
- console.log("Day changed, updating daily notes view");
- await this.ensureTodaysDailyNoteExists();
- const dailyNoteLeaves = this.app.workspace.getLeavesOfType(DAILY_NOTE_VIEW_TYPE);
- if (dailyNoteLeaves.length > 0) {
- for (const leaf of dailyNoteLeaves) {
- const view2 = leaf.view;
- if (view2) {
- view2.refreshForNewDay();
- }
- }
- }
- }
- }
-}
-module.exports = DailyNoteViewPlugin;
-
-
-/* nosourcemap */
\ No newline at end of file
diff --git a/.obsidian/plugins/daily-notes-editor/manifest.json b/.obsidian/plugins/daily-notes-editor/manifest.json
deleted file mode 100644
index a8b8646..0000000
--- a/.obsidian/plugins/daily-notes-editor/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "id": "daily-notes-editor",
- "name": "Daily Notes Editor",
- "version": "1.1.0",
- "minAppVersion": "0.15.0",
- "description": "Edit a bunch of daily notes in one page(inline), which works similar to Roam Research's default daily note view.",
- "author": "Boninall",
- "authorUrl": "https://github.com/Quorafind",
- "fundingUrl": {
- "Buy Me a Coffee": "https://www.buymeacoffee.com/boninall",
- "爱发电": "https://afdian.net/a/boninall",
- "支付宝": "https://cdn.jsdelivr.net/gh/Quorafind/.github@main/IMAGE/%E6%94%AF%E4%BB%98%E5%AE%9D%E4%BB%98%E6%AC%BE%E7%A0%81.jpg"
- },
- "isDesktopOnly": false
-}
\ No newline at end of file
diff --git a/.obsidian/plugins/daily-notes-editor/styles.css b/.obsidian/plugins/daily-notes-editor/styles.css
deleted file mode 100644
index 33df896..0000000
--- a/.obsidian/plugins/daily-notes-editor/styles.css
+++ /dev/null
@@ -1,220 +0,0 @@
-.dn-editor {
- /*overflow-y: hidden;*/
-}
-
-.dn-editor .cm-scroller {
- /*overflow-y: hidden;*/
- padding: unset;
-}
-
-.dn-editor .workspace-leaf {
- all: unset;
-}
-
-.dn-editor .dn-content {
- display: none;
- /*margin: 0;*/
- /*border-radius: var(--he-popover-border-radius);*/
- /*overflow: hidden;*/
- /*height: 100%;*/
-}
-
-.dn-editor .workspace-leaf,
-.dn-editor .workspace-split {
- height: 100%;
- width: 100%;
-}
-
-.dn-editor .markdown-source-view.mod-cm6 .cm-editor {
- min-height: auto;
-}
-
-.dn-editor .cm-content {
- padding-bottom: 0 !important;
- padding-top: 0 !important;
-}
-
-.dn-editor .view-content {
- background: none !important;
-}
-
-.dn-editor .cm-scroller {
- padding: 0 !important;
- overflow-y: clip;
-}
-.daily-note-view .daily-note-wrapper::before {
- content: "";
- display: block;
- height: 1px;
- width: var(--file-line-width);
- margin-bottom: 30px;
- margin-left: auto;
- margin-right: auto;
- background-color: var(--background-modifier-border);
-}
-
-.daily-note-view .daily-note-wrapper:first-of-type::before {
- height: 0px;
-}
-
-.daily-note-view .dn-range-indicator + .daily-note-container::before {
- height: 0px;
-}
-
-.is-popout-window .dn-editor .dn-content {
- margin: 0;
- border-radius: var(--he-popover-border-radius);
- overflow: hidden;
- height: auto;
-}
-
-.is-popout-window .dn-editor .workspace-leaf,
-.is-popout-window .dn-editor .workspace-split {
- height: auto;
- width: 100%;
-}
-
-.is-popout-window .dn-editor .cm-scroller {
- height: auto;
-}
-
-.is-popout-window .dn-editor .markdown-source-view.mod-cm6 {
- height: auto;
-}
-
-.is-popout-window .dn-editor .view-content {
- height: auto;
-}
-
-.is-popout-window .dn-editor .workspace-leaf-content {
- height: auto;
-}
-
-.daily-note-view .embedded-backlinks {
- min-height: unset !important;
-}
-
-.daily-note-view {
- display: flex;
- flex-direction: column;
- gap: var(--size-4-4);
- overflow-x: hidden;
-}
-
-body.daily-notes-hide-frontmatter
- .daily-note-view
- .markdown-source-view.is-live-preview.show-properties
- .metadata-container {
- display: none;
-}
-
-body.daily-notes-hide-backlinks .daily-note-view .embedded-backlinks {
- display: none;
-}
-
-/* Custom Range Modal Styles */
-.custom-range-date-container {
- margin-bottom: var(--size-4-2);
- display: flex;
- align-items: center;
-}
-
-.custom-range-date-container span {
- width: 100px;
- display: inline-block;
-}
-
-.custom-range-date-container input {
- flex: 1;
-}
-
-.custom-range-button-container {
- display: flex;
- justify-content: flex-end;
- margin-top: var(--size-4-4);
- gap: var(--size-4-2);
-}
-
-/* Preset management styles */
-.preset-container {
- margin-bottom: var(--size-4-4);
-}
-
-.no-presets-message {
- color: var(--text-muted);
- font-style: italic;
- margin: var(--size-4-2) 0;
-}
-
-.preset-list {
- display: flex;
- flex-direction: column;
- gap: var(--size-4-2);
- margin: var(--size-4-2) 0;
-}
-
-.preset-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: var(--size-2-4) var(--size-4-3);
- background-color: var(--background-secondary);
- border-radius: var(--radius-s);
-}
-
-.preset-info {
- display: flex;
- align-items: center;
-}
-
-.preset-type {
- font-weight: bold;
- margin-right: var(--size-2-2);
-}
-
-.preset-actions {
- display: flex;
- gap: var(--size-4-2);
-}
-
-.preset-action-button {
- padding: var(--size-2-2) var(--size-2-4);
- border-radius: var(--radius-s);
- font-size: var(--font-ui-small);
- cursor: pointer;
-}
-
-.preset-open-button {
- background-color: var(--interactive-accent);
- color: var(--text-on-accent);
-}
-
-.preset-delete-button {
- background-color: var(--background-modifier-error);
- color: var(--text-on-accent);
-}
-
-/* Add preset modal styles */
-.setting-item {
- margin-bottom: var(--size-4-4);
-}
-
-.target-input {
- width: 100%;
- padding: var(--size-2-3);
- border-radius: var(--radius-s);
- border: 1px solid var(--background-modifier-border);
- background-color: var(--background-primary);
-}
-
-.modal-button-container {
- display: flex;
- justify-content: flex-end;
- gap: var(--size-4-2);
- margin-top: var(--size-4-4);
-}
-
-.is-phone .mod-root .workspace-tabs:not(.mod-visible):has(.daily-note-view) {
- display: flex !important;
-}
-.daily-note.svelte-1d2sruf.svelte-1d2sruf{margin-bottom:var(--size-4-5);padding-bottom:var(--size-4-8)}.daily-note.svelte-1d2sruf.svelte-1d2sruf:has(.daily-note-editor[data-collapsed="true"]){margin-bottom:0;padding-bottom:0}.daily-note-editor.svelte-1d2sruf.svelte-1d2sruf{min-height:100px}.daily-note-editor[data-collapsed="true"].svelte-1d2sruf.svelte-1d2sruf{display:none}.daily-note.svelte-1d2sruf .collapse-button.svelte-1d2sruf{display:none}.daily-note.svelte-1d2sruf:hover .collapse-button.svelte-1d2sruf{display:block}.daily-note.svelte-1d2sruf .collapse-button.svelte-1d2sruf{color:var(--text-muted)}.daily-note.svelte-1d2sruf .collapse-button.svelte-1d2sruf:hover{color:var(--text-normal)}.daily-note.svelte-1d2sruf:has(.is-readable-line-width) .daily-note-title.svelte-1d2sruf{max-width:calc(var(--file-line-width) + var(--size-4-4));width:calc(var(--file-line-width) + var(--size-4-4));margin-left:auto;margin-right:auto;margin-bottom:var(--size-4-8);display:flex;align-items:center;justify-content:start;gap:var(--size-4-2)}.collapse-button.svelte-1d2sruf.svelte-1d2sruf{margin-left:calc(var(--size-4-8) * -1)}.collapse-button[data-collapsed="true"].svelte-1d2sruf.svelte-1d2sruf{transform:rotate(-90deg);transition:transform 0.2s ease}.daily-note.svelte-1d2sruf:not(:has(.is-readable-line-width)) .daily-note-title.svelte-1d2sruf{display:flex;justify-content:start;align-items:center;width:100%;padding-left:calc(calc(100% - var(--file-line-width)) / 2 - var(--size-4-2));padding-right:calc(calc(100% - var(--file-line-width)) / 2 - var(--size-4-2));margin-top:var(--size-4-8);gap:var(--size-4-2)}.clickable-link.svelte-1d2sruf.svelte-1d2sruf{cursor:pointer;text-decoration:none}.clickable-link.svelte-1d2sruf.svelte-1d2sruf:hover{color:var(--color-accent);text-decoration:underline}.editor-placeholder.svelte-1d2sruf.svelte-1d2sruf{display:flex;justify-content:center;align-items:center;height:100px;color:var(--text-muted);font-style:italic}.collapse-button.svelte-1d2sruf.svelte-1d2sruf{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;color:var(--text-muted);transition:background-color 0.2s ease}.collapse-button.svelte-1d2sruf.svelte-1d2sruf:hover{color:var(--text-normal)}.dn-stock.svelte-4q3cv7{height:1000px;width:100%;display:flex;justify-content:center;align-items:center}.dn-stock-text.svelte-4q3cv7{text-align:center}.no-more-text.svelte-4q3cv7{margin-left:auto;margin-right:auto;text-align:center}.dn-blank-day.svelte-4q3cv7{display:flex;margin-left:auto;margin-right:auto;max-width:var(--file-line-width);color:var(--color-base-40);padding-top:20px;padding-bottom:20px;transition:all 300ms}.dn-blank-day.svelte-4q3cv7:hover{padding-top:40px;padding-bottom:40px;transition:padding 300ms}.dn-blank-day-text.svelte-4q3cv7{margin-left:auto;margin-right:auto;text-align:center}.daily-note-wrapper.svelte-4q3cv7{width:100%}
\ No newline at end of file
diff --git a/.obsidian/plugins/tasknotes/data.json b/.obsidian/plugins/tasknotes/data.json
index cd16208..324e7b8 100644
--- a/.obsidian/plugins/tasknotes/data.json
+++ b/.obsidian/plugins/tasknotes/data.json
@@ -1,5 +1,5 @@
{
- "tasksFolder": "tasks",
+ "tasksFolder": "",
"moveArchivedTasks": false,
"archiveFolder": "TaskNotes/Archive",
"taskTag": "type/task",
@@ -72,7 +72,7 @@
"pomodoroAutoStartBreaks": false,
"pomodoroAutoStartWork": false,
"pomodoroNotifications": true,
- "pomodoroSoundEnabled": true,
+ "pomodoroSoundEnabled": false,
"pomodoroSoundVolume": 50,
"pomodoroStorageLocation": "daily-notes",
"pomodoroMobileSidebar": "tab",
@@ -431,7 +431,8 @@
"status",
"priority",
"blocked",
- "blocking"
+ "blocking",
+ "totalTrackedTime"
],
"inlineVisibleProperties": [
"status",
@@ -461,7 +462,7 @@
"microsoftOAuthClientSecret": "",
"enableGoogleCalendar": false,
"enableMicrosoftCalendar": false,
- "disableCalendarOnMobile": false,
+ "disableCalendarOnMobile": true,
"enabledGoogleCalendars": [],
"googleCalendarSyncTokens": {},
"enabledMicrosoftCalendars": [],
@@ -469,10 +470,10 @@
"googleCalendarExport": {
"enabled": false,
"targetCalendarId": "",
- "syncOnTaskCreate": true,
- "syncOnTaskUpdate": true,
- "syncOnTaskComplete": true,
- "syncOnTaskDelete": true,
+ "syncOnTaskCreate": false,
+ "syncOnTaskUpdate": false,
+ "syncOnTaskComplete": false,
+ "syncOnTaskDelete": false,
"eventTitleTemplate": "{{title}}",
"includeDescription": true,
"eventColorId": null,
@@ -483,36 +484,5 @@
"defaultReminderMinutes": null
},
"enableDebugLogging": false,
- "googleCalendarSyncQueue": [
- {
- "taskPath": "timestamped/YYYY-MM-DD_HH-mm-ss.md",
- "requestedAt": 1780346458397,
- "attempts": 0,
- "lastError": "Google Calendar sync is not ready"
- },
- {
- "taskPath": "timestamped/2026-06-01_16-44-31.md",
- "requestedAt": 1780346671952,
- "attempts": 0,
- "lastError": "Google Calendar sync is not ready"
- },
- {
- "taskPath": "timestamped/2026-06-01_16-54-37.md",
- "requestedAt": 1780347277788,
- "attempts": 0,
- "lastError": "Google Calendar sync is not ready"
- },
- {
- "taskPath": "timestamped/2026-06-01_17-07-41.md",
- "requestedAt": 1780348061498,
- "attempts": 0,
- "lastError": "Google Calendar sync is not ready"
- },
- {
- "taskPath": "timestamped/2026-06-01_17-09-04.md",
- "requestedAt": 1780348144101,
- "attempts": 0,
- "lastError": "Google Calendar sync is not ready"
- }
- ]
+ "googleCalendarSyncQueue": []
}
\ No newline at end of file
diff --git a/periodic/daily/2026-05-31.md b/periodic/daily/2026-05-31.md
new file mode 100644
index 0000000..9393518
--- /dev/null
+++ b/periodic/daily/2026-05-31.md
@@ -0,0 +1,10 @@
+---
+id: 2026-05-31
+title: 2026-05-31
+tags: []
+weekly: "[[2026w23]]"
+monthly: "[[2026-05]]"
+quarterly: "[[2026q2]]"
+previous: "[[2026-05-30]]"
+---
+# 2026-05-31
diff --git a/periodic/daily/2026-06-03.md b/periodic/daily/2026-06-03.md
index 0e0cda1..86ad3a7 100644
--- a/periodic/daily/2026-06-03.md
+++ b/periodic/daily/2026-06-03.md
@@ -8,5 +8,3 @@ quarterly: "[[2026q2]]"
previous: "[[2026-06-02]]"
---
# 2026-06-03
-
-testing^[[[2025-08-15_14-15-41]]]
diff --git a/periodic/daily/2026-06-04.md b/periodic/daily/2026-06-04.md
new file mode 100644
index 0000000..abdcf7b
--- /dev/null
+++ b/periodic/daily/2026-06-04.md
@@ -0,0 +1,10 @@
+---
+id: 2026-06-04
+title: 2026-06-04
+tags: []
+weekly: "[[2026w23]]"
+monthly: "[[2026-06]]"
+quarterly: "[[2026q2]]"
+previous: "[[2026-06-03]]"
+---
+# 2026-06-04
diff --git a/periodic/daily/2026-06-05.md b/periodic/daily/2026-06-05.md
new file mode 100644
index 0000000..2335cdb
--- /dev/null
+++ b/periodic/daily/2026-06-05.md
@@ -0,0 +1,16 @@
+---
+id: 2026-06-05
+title: 2026-06-05
+tags: []
+weekly: "[[2026w23]]"
+monthly: "[[2026-06]]"
+quarterly: "[[2026q2]]"
+previous: "[[2026-06-04]]"
+---
+# 2026-06-05
+
+When I got to work today, around 08:15,
+I watched one of the robot dogs plow into a bollard fixture.
+Unfortunately it kept going,
+and too fast for me to catch up
+to point and laugh into its camera.
diff --git a/tasks/views/calendar-default.base b/tasks/views/calendar-default.base
index aec5e16..9f5c0e9 100644
--- a/tasks/views/calendar-default.base
+++ b/tasks/views/calendar-default.base
@@ -1,55 +1,51 @@
-# Calendar
-
filters:
and:
- file.hasTag("type/task")
- file.inFolder("templates") != true
-
formulas:
- priorityWeight: 'if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))'
- daysUntilDue: 'if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)'
- dueIn: 'if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))'
- daysUntilScheduled: 'if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)'
- daysSinceCreated: '((number(now()) - number(file.ctime)) / 86400000).floor()'
- daysSinceModified: '((number(now()) - number(file.mtime)) / 86400000).floor()'
- isOverdue: '(due.isEmpty() == false) && date(due) < today() && status != "done"'
- isDueToday: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isDueThisWeek: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")'
- isScheduledToday: '(scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isRecurring: 'recurrence && !recurrence.isEmpty()'
- hasTimeEstimate: 'timeEstimate && timeEstimate > 0'
- timeRemaining: 'if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)'
- efficiencyRatio: 'if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)'
- timeTrackedThisWeek: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- timeTrackedToday: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- dueMonth: 'if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")'
- dueWeek: 'if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")'
- scheduledMonth: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")'
- scheduledWeek: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")'
- dueDateCategory: 'if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))'
- timeEstimateCategory: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))'
- ageCategory: 'if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))'
- createdMonth: 'file.ctime.format("YYYY-MM")'
- modifiedMonth: 'file.mtime.format("YYYY-MM")'
- priorityCategory: 'if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))'
- projectCount: 'if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))'
- contextCount: 'if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))'
- trackingStatus: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))'
- nextDate: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))'
- daysUntilNext: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))'
- hasDate: '(due.isEmpty() == false) || (scheduled.isEmpty() == false)'
- isToday: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))'
- isThisWeek: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))'
- nextDateCategory: 'if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))'
- nextDateMonth: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))'
- nextDateWeek: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))'
- urgencyScore: 'if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))'
- timeTrackedFormatted: 'if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")'
- dueDateDisplay: 'if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))'
-
+ priorityWeight: if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))
+ daysUntilDue: if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)
+ dueIn: if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))
+ daysUntilScheduled: if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)
+ daysSinceCreated: ((number(now()) - number(file.ctime)) / 86400000).floor()
+ daysSinceModified: ((number(now()) - number(file.mtime)) / 86400000).floor()
+ isOverdue: (due.isEmpty() == false) && date(due) < today() && status != "done"
+ isDueToday: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isDueThisWeek: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ isScheduledToday: (scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isRecurring: recurrence && !recurrence.isEmpty()
+ hasTimeEstimate: timeEstimate && timeEstimate > 0
+ timeRemaining: if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)
+ efficiencyRatio: if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)
+ timeTrackedThisWeek: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ timeTrackedToday: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ dueMonth: if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")
+ dueWeek: if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")
+ scheduledMonth: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")
+ scheduledWeek: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")
+ dueDateCategory: if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))
+ timeEstimateCategory: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))
+ ageCategory: if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))
+ createdMonth: file.ctime.format("YYYY-MM")
+ modifiedMonth: file.mtime.format("YYYY-MM")
+ priorityCategory: if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))
+ projectCount: if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))
+ contextCount: if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))
+ trackingStatus: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))
+ nextDate: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))
+ daysUntilNext: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))
+ hasDate: (due.isEmpty() == false) || (scheduled.isEmpty() == false)
+ isToday: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))
+ isThisWeek: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))
+ nextDateCategory: if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))
+ nextDateMonth: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))
+ nextDateWeek: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))
+ urgencyScore: if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))
+ timeTrackedFormatted: if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")
+ dueDateDisplay: if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))
views:
- type: tasknotesCalendar
- name: "Calendar"
+ name: Calendar
order:
- status
- priority
@@ -66,7 +62,7 @@ views:
showTimeblocks: true
showPropertyBasedEvents: true
createDailyNotesFromDateLinks: true
- calendarView: "timeGridWeek"
+ calendarView: timeGridWeek
customDayCount: 3
firstDay: 0
- slotDuration: "00:30:00"
+ slotDuration: 00:30:00
diff --git a/tasks/views/kanban-default.base b/tasks/views/kanban-default.base
index 1e52f55..a8ce688 100644
--- a/tasks/views/kanban-default.base
+++ b/tasks/views/kanban-default.base
@@ -1,55 +1,57 @@
-# Kanban Board
-
filters:
and:
- file.hasTag("type/task")
- file.inFolder("templates") != true
-
formulas:
- priorityWeight: 'if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))'
- daysUntilDue: 'if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)'
- dueIn: 'if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))'
- daysUntilScheduled: 'if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)'
- daysSinceCreated: '((number(now()) - number(file.ctime)) / 86400000).floor()'
- daysSinceModified: '((number(now()) - number(file.mtime)) / 86400000).floor()'
- isOverdue: '(due.isEmpty() == false) && date(due) < today() && status != "done"'
- isDueToday: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isDueThisWeek: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")'
- isScheduledToday: '(scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isRecurring: 'recurrence && !recurrence.isEmpty()'
- hasTimeEstimate: 'timeEstimate && timeEstimate > 0'
- timeRemaining: 'if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)'
- efficiencyRatio: 'if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)'
- timeTrackedThisWeek: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- timeTrackedToday: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- dueMonth: 'if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")'
- dueWeek: 'if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")'
- scheduledMonth: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")'
- scheduledWeek: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")'
- dueDateCategory: 'if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))'
- timeEstimateCategory: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))'
- ageCategory: 'if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))'
- createdMonth: 'file.ctime.format("YYYY-MM")'
- modifiedMonth: 'file.mtime.format("YYYY-MM")'
- priorityCategory: 'if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))'
- projectCount: 'if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))'
- contextCount: 'if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))'
- trackingStatus: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))'
- nextDate: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))'
- daysUntilNext: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))'
- hasDate: '(due.isEmpty() == false) || (scheduled.isEmpty() == false)'
- isToday: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))'
- isThisWeek: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))'
- nextDateCategory: 'if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))'
- nextDateMonth: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))'
- nextDateWeek: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))'
- urgencyScore: 'if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))'
- timeTrackedFormatted: 'if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")'
- dueDateDisplay: 'if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))'
-
+ priorityWeight: if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))
+ daysUntilDue: if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)
+ dueIn: if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))
+ daysUntilScheduled: if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)
+ daysSinceCreated: ((number(now()) - number(file.ctime)) / 86400000).floor()
+ daysSinceModified: ((number(now()) - number(file.mtime)) / 86400000).floor()
+ isOverdue: (due.isEmpty() == false) && date(due) < today() && status != "done"
+ isDueToday: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isDueThisWeek: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ isScheduledToday: (scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isRecurring: recurrence && !recurrence.isEmpty()
+ hasTimeEstimate: timeEstimate && timeEstimate > 0
+ timeRemaining: if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)
+ efficiencyRatio: if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)
+ timeTrackedThisWeek: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ timeTrackedToday: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ dueMonth: if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")
+ dueWeek: if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")
+ scheduledMonth: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")
+ scheduledWeek: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")
+ dueDateCategory: if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))
+ timeEstimateCategory: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))
+ ageCategory: if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))
+ createdMonth: file.ctime.format("YYYY-MM")
+ modifiedMonth: file.mtime.format("YYYY-MM")
+ priorityCategory: if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))
+ projectCount: if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))
+ contextCount: if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))
+ trackingStatus: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))
+ nextDate: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))
+ daysUntilNext: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))
+ hasDate: (due.isEmpty() == false) || (scheduled.isEmpty() == false)
+ isToday: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))
+ isThisWeek: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))
+ nextDateCategory: if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))
+ nextDateMonth: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))
+ nextDateWeek: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))
+ urgencyScore: if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))
+ timeTrackedFormatted: if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")
+ dueDateDisplay: if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))
views:
- type: tasknotesKanban
- name: "Kanban Board"
+ name: Kanban Board
+ filters:
+ and:
+ - recurrence.isEmpty()
+ groupBy:
+ property: status
+ direction: ASC
order:
- status
- priority
@@ -59,11 +61,8 @@ views:
- complete_instances
- file.tasks
sort:
- - column: tasknotes_manual_order
+ - property: tasknotes_manual_order
direction: DESC
- groupBy:
- property: status
- direction: ASC
options:
columnWidth: 280
hideEmptyColumns: false
diff --git a/tasks/views/mini-calendar-default.base b/tasks/views/mini-calendar-default.base
index 33c9cd5..bc0f62f 100644
--- a/tasks/views/mini-calendar-default.base
+++ b/tasks/views/mini-calendar-default.base
@@ -1,56 +1,51 @@
-# Mini Calendar
-# Generated with your TaskNotes settings
-
filters:
and:
- file.hasTag("type/task")
- file.inFolder("templates") != true
-
formulas:
- priorityWeight: 'if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))'
- daysUntilDue: 'if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)'
- dueIn: 'if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))'
- daysUntilScheduled: 'if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)'
- daysSinceCreated: '((number(now()) - number(file.ctime)) / 86400000).floor()'
- daysSinceModified: '((number(now()) - number(file.mtime)) / 86400000).floor()'
- isOverdue: '(due.isEmpty() == false) && date(due) < today() && status != "done"'
- isDueToday: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isDueThisWeek: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")'
- isScheduledToday: '(scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isRecurring: 'recurrence && !recurrence.isEmpty()'
- hasTimeEstimate: 'timeEstimate && timeEstimate > 0'
- timeRemaining: 'if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)'
- efficiencyRatio: 'if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)'
- timeTrackedThisWeek: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- timeTrackedToday: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- dueMonth: 'if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")'
- dueWeek: 'if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")'
- scheduledMonth: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")'
- scheduledWeek: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")'
- dueDateCategory: 'if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))'
- timeEstimateCategory: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))'
- ageCategory: 'if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))'
- createdMonth: 'file.ctime.format("YYYY-MM")'
- modifiedMonth: 'file.mtime.format("YYYY-MM")'
- priorityCategory: 'if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))'
- projectCount: 'if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))'
- contextCount: 'if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))'
- trackingStatus: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))'
- nextDate: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))'
- daysUntilNext: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))'
- hasDate: '(due.isEmpty() == false) || (scheduled.isEmpty() == false)'
- isToday: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))'
- isThisWeek: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))'
- nextDateCategory: 'if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))'
- nextDateMonth: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))'
- nextDateWeek: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))'
- urgencyScore: 'if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))'
- timeTrackedFormatted: 'if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")'
- dueDateDisplay: 'if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))'
-
+ priorityWeight: if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))
+ daysUntilDue: if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)
+ dueIn: if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))
+ daysUntilScheduled: if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)
+ daysSinceCreated: ((number(now()) - number(file.ctime)) / 86400000).floor()
+ daysSinceModified: ((number(now()) - number(file.mtime)) / 86400000).floor()
+ isOverdue: (due.isEmpty() == false) && date(due) < today() && status != "done"
+ isDueToday: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isDueThisWeek: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ isScheduledToday: (scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isRecurring: recurrence && !recurrence.isEmpty()
+ hasTimeEstimate: timeEstimate && timeEstimate > 0
+ timeRemaining: if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)
+ efficiencyRatio: if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)
+ timeTrackedThisWeek: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ timeTrackedToday: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ dueMonth: if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")
+ dueWeek: if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")
+ scheduledMonth: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")
+ scheduledWeek: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")
+ dueDateCategory: if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))
+ timeEstimateCategory: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))
+ ageCategory: if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))
+ createdMonth: file.ctime.format("YYYY-MM")
+ modifiedMonth: file.mtime.format("YYYY-MM")
+ priorityCategory: if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))
+ projectCount: if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))
+ contextCount: if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))
+ trackingStatus: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))
+ nextDate: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))
+ daysUntilNext: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))
+ hasDate: (due.isEmpty() == false) || (scheduled.isEmpty() == false)
+ isToday: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))
+ isThisWeek: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))
+ nextDateCategory: if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))
+ nextDateMonth: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))
+ nextDateWeek: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))
+ urgencyScore: if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))
+ timeTrackedFormatted: if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")
+ dueDateDisplay: if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))
views:
- type: tasknotesMiniCalendar
- name: "Due"
+ name: Due
order:
- status
- priority
@@ -64,12 +59,12 @@ views:
direction: ASC
dateProperty: due
- type: tasknotesMiniCalendar
- name: "Scheduled"
+ name: Scheduled
order: []
dateProperty: scheduled
- type: tasknotesMiniCalendar
- name: "Created"
+ name: Created
dateProperty: file.ctime
- type: tasknotesMiniCalendar
- name: "Modified"
+ name: Modified
dateProperty: file.mtime
diff --git a/tasks/views/tasks-default.base b/tasks/views/tasks-default.base
index b544e1c..1230622 100644
--- a/tasks/views/tasks-default.base
+++ b/tasks/views/tasks-default.base
@@ -1,71 +1,54 @@
-# All Tasks
-
filters:
and:
- file.hasTag("type/task")
- file.inFolder("templates") != true
-
formulas:
- priorityWeight: 'if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))'
- daysUntilDue: 'if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)'
- dueIn: 'if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))'
- daysUntilScheduled: 'if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)'
- daysSinceCreated: '((number(now()) - number(file.ctime)) / 86400000).floor()'
- daysSinceModified: '((number(now()) - number(file.mtime)) / 86400000).floor()'
- isOverdue: '(due.isEmpty() == false) && date(due) < today() && status != "done"'
- isDueToday: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isDueThisWeek: '(due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")'
- isScheduledToday: '(scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")'
- isRecurring: 'recurrence && !recurrence.isEmpty()'
- hasTimeEstimate: 'timeEstimate && timeEstimate > 0'
- timeRemaining: 'if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)'
- efficiencyRatio: 'if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)'
- timeTrackedThisWeek: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- timeTrackedToday: 'if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)'
- dueMonth: 'if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")'
- dueWeek: 'if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")'
- scheduledMonth: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")'
- scheduledWeek: 'if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")'
- dueDateCategory: 'if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))'
- timeEstimateCategory: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))'
- ageCategory: 'if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))'
- createdMonth: 'file.ctime.format("YYYY-MM")'
- modifiedMonth: 'file.mtime.format("YYYY-MM")'
- priorityCategory: 'if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))'
- projectCount: 'if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))'
- contextCount: 'if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))'
- trackingStatus: 'if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))'
- nextDate: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))'
- daysUntilNext: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))'
- hasDate: '(due.isEmpty() == false) || (scheduled.isEmpty() == false)'
- isToday: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))'
- isThisWeek: '((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))'
- nextDateCategory: 'if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))'
- nextDateMonth: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))'
- nextDateWeek: 'if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))'
- urgencyScore: 'if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))'
- timeTrackedFormatted: 'if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")'
- dueDateDisplay: 'if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))'
-
+ priorityWeight: if(priority=="none",0,if(priority=="low",1,if(priority=="normal",2,if(priority=="high",3,999))))
+ daysUntilDue: if((due.isEmpty() == false), ((number(date(due)) - number(today())) / 86400000).floor(), null)
+ dueIn: if(due.isEmpty(), "", if(formula.daysUntilDue == 0, "Today", if(formula.daysUntilDue == 1, "1 day", if(formula.daysUntilDue > 1, formula.daysUntilDue + " days", if(formula.daysUntilDue == -1, "1 day overdue", formula.daysUntilDue * -1 + " days overdue")))))
+ daysUntilScheduled: if((scheduled.isEmpty() == false), ((number(date(scheduled)) - number(today())) / 86400000).floor(), null)
+ daysSinceCreated: ((number(now()) - number(file.ctime)) / 86400000).floor()
+ daysSinceModified: ((number(now()) - number(file.mtime)) / 86400000).floor()
+ isOverdue: (due.isEmpty() == false) && date(due) < today() && status != "done"
+ isDueToday: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isDueThisWeek: (due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ isScheduledToday: (scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ isRecurring: recurrence && !recurrence.isEmpty()
+ hasTimeEstimate: timeEstimate && timeEstimate > 0
+ timeRemaining: if(timeEstimate && timeEstimate > 0, timeEstimate - if(timeEntries, list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0), 0), null)
+ efficiencyRatio: if(timeEstimate && timeEstimate > 0 && timeEntries, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / timeEstimate * 100).round(), null)
+ timeTrackedThisWeek: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime) >= today() - "7d").map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ timeTrackedToday: if(timeEntries, list(timeEntries).filter(value.endTime && date(value.startTime).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round(), 0)
+ dueMonth: if((due.isEmpty() == false), date(due).format("YYYY-MM"), "No due date")
+ dueWeek: if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), "No due date")
+ scheduledMonth: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "Not scheduled")
+ scheduledWeek: if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "Not scheduled")
+ dueDateCategory: if(due.isEmpty(), "No due date", if(date(due) < today(), "Overdue", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), "This week", "Later")))))
+ timeEstimateCategory: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(timeEstimate < 30, "Quick (<30m)", if(timeEstimate <= 120, "Medium (30m-2h)", "Long (>2h)")))
+ ageCategory: if(((number(now()) - number(file.ctime)) / 86400000) < 1, "Today", if(((number(now()) - number(file.ctime)) / 86400000) < 7, "This week", if(((number(now()) - number(file.ctime)) / 86400000) < 30, "This month", "Older")))
+ createdMonth: file.ctime.format("YYYY-MM")
+ modifiedMonth: file.mtime.format("YYYY-MM")
+ priorityCategory: if(priority=="none","None",if(priority=="low","Low",if(priority=="normal","Normal",if(priority=="high","High","No priority"))))
+ projectCount: if(!projects || list(projects).length == 0, "No projects", if(list(projects).length == 1, "Single project", "Multiple projects"))
+ contextCount: if(!contexts || list(contexts).length == 0, "No contexts", if(list(contexts).length == 1, "Single context", "Multiple contexts"))
+ trackingStatus: if(!timeEstimate || timeEstimate == 0 || timeEstimate == null, "No estimate", if(!timeEntries || list(timeEntries).length == 0, "Not started", if(formula.efficiencyRatio < 100, "Under estimate", "Over estimate")))
+ nextDate: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), due, scheduled), if((due.isEmpty() == false), due, scheduled))
+ daysUntilNext: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), min(formula.daysUntilDue, formula.daysUntilScheduled), if((due.isEmpty() == false), formula.daysUntilDue, formula.daysUntilScheduled))
+ hasDate: (due.isEmpty() == false) || (scheduled.isEmpty() == false)
+ isToday: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"))
+ isThisWeek: ((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD") && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"))
+ nextDateCategory: if(due.isEmpty() && scheduled.isEmpty(), "No date", if(((due.isEmpty() == false) && date(due) < today()) || ((scheduled.isEmpty() == false) && date(scheduled) < today()), "Overdue/Past", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")), "Today", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD")), "Tomorrow", if(((due.isEmpty() == false) && date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")) || ((scheduled.isEmpty() == false) && date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")), "This week", "Later")))))
+ nextDateMonth: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-MM"), date(scheduled).format("YYYY-MM")), if((due.isEmpty() == false), date(due).format("YYYY-MM"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-MM"), "No date")))
+ nextDateWeek: if((due.isEmpty() == false) && (scheduled.isEmpty() == false), if(date(due) < date(scheduled), date(due).format("YYYY-[W]WW"), date(scheduled).format("YYYY-[W]WW")), if((due.isEmpty() == false), date(due).format("YYYY-[W]WW"), if((scheduled.isEmpty() == false), date(scheduled).format("YYYY-[W]WW"), "No date")))
+ urgencyScore: if(due.isEmpty() && scheduled.isEmpty(), formula.priorityWeight, formula.priorityWeight + max(0, 10 - if(formula.daysUntilNext, formula.daysUntilNext, 0)) + (1 - ((number(date(formula.nextDate)) - number(date(date(formula.nextDate).format("YYYY-MM-DD")))) / 86400000)))
+ timeTrackedFormatted: if(timeEntries, if(list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) >= 60, (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) / 60).floor() + "h " + (list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0) % 60).round() + "m", list(timeEntries).filter(value.endTime).map((number(date(value.endTime)) - number(date(value.startTime))) / 60000).reduce(acc + value, 0).round() + "m"), "0m")
+ dueDateDisplay: if(due.isEmpty(), "", if(date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD"), "Today", if(date(due).format("YYYY-MM-DD") == (today() + "1 day").format("YYYY-MM-DD"), "Tomorrow", if(date(due).format("YYYY-MM-DD") == (today() - "1 day").format("YYYY-MM-DD"), "Yesterday", if(date(due) < today(), formula.daysUntilDue * -1 + "d ago", if(date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD"), date(due).format("ddd"), date(due).format("MMM D")))))))
views:
- type: tasknotesTaskList
- name: "Manual Order"
- order:
- - status
- - priority
- - blockedBy
- - file.name
- - recurrence
- - complete_instances
- - file.tasks
- sort:
- - column: tasknotes_manual_order
- direction: DESC
+ name: Manual Order
groupBy:
property: status
direction: ASC
- - type: tasknotesTaskList
- name: "All Tasks"
order:
- status
- priority
@@ -75,28 +58,35 @@ views:
- complete_instances
- file.tasks
sort:
- - column: due
+ - property: tasknotes_manual_order
+ direction: DESC
+ - type: tasknotesTaskList
+ name: All Tasks
+ order:
+ - status
+ - priority
+ - blockedBy
+ - file.name
+ - recurrence
+ - complete_instances
+ - file.tasks
+ sort:
+ - property: due
direction: ASC
- type: tasknotesTaskList
- name: "Not Blocked"
+ name: Not Blocked
filters:
and:
- # Incomplete tasks
- or:
- # Non-recurring task that's not in any completed status
- - and:
- - recurrence.isEmpty()
- - status != "done"
- # Recurring task where today is not in complete_instances
- - and:
- - recurrence.isEmpty() == false
- - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- # Not blocked by any incomplete tasks
+ - and:
+ - recurrence.isEmpty()
+ - status != "done"
+ - and:
+ - recurrence.isEmpty() == false
+ - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- or:
- # No blocking dependencies at all
- - blockedBy.isEmpty()
- # All blocking tasks are completed (filter returns only incomplete, then check if empty)
- - 'list(blockedBy).filter(file(if(value.isType("object"), value.uid, value)).properties.status != "done").isEmpty()'
+ - blockedBy.isEmpty()
+ - list(blockedBy).filter(file(if(value.isType("object"), value.uid, value)).properties.status != "done").isEmpty()
order:
- status
- priority
@@ -106,30 +96,26 @@ views:
- complete_instances
- file.tasks
sort:
- - column: formula.urgencyScore
+ - property: formula.urgencyScore
direction: DESC
- type: tasknotesTaskList
- name: "Today"
+ name: Today
filters:
and:
- # Incomplete tasks (handles both recurring and non-recurring)
- or:
- # Non-recurring task that's not in any completed status
- - and:
- - recurrence.isEmpty()
- - status != "done"
- # Recurring task where today is not in complete_instances
- - and:
- - recurrence.isEmpty() == false
- - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- # Due or scheduled today
+ - and:
+ - recurrence.isEmpty()
+ - status != "done"
+ - and:
+ - recurrence.isEmpty() == false
+ - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- or:
- - and:
- - due.isEmpty() == false
- - date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
- - and:
- - scheduled.isEmpty() == false
- - date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ - and:
+ - due.isEmpty() == false
+ - date(due).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
+ - and:
+ - scheduled.isEmpty() == false
+ - date(scheduled).format("YYYY-MM-DD") == today().format("YYYY-MM-DD")
order:
- status
- priority
@@ -139,30 +125,26 @@ views:
- complete_instances
- file.tasks
sort:
- - column: formula.urgencyScore
+ - property: formula.urgencyScore
direction: DESC
- type: tasknotesTaskList
- name: "Overdue"
+ name: Overdue
filters:
and:
- # Incomplete tasks
- or:
- # Non-recurring task that's not in any completed status
- - and:
- - recurrence.isEmpty()
- - status != "done"
- # Recurring task where today is not in complete_instances
- - and:
- - recurrence.isEmpty() == false
- - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- # Due or scheduled in the past
+ - and:
+ - recurrence.isEmpty()
+ - status != "done"
+ - and:
+ - recurrence.isEmpty() == false
+ - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- or:
- - and:
- - due.isEmpty() == false
- - date(due) < today()
- - and:
- - scheduled.isEmpty() == false
- - date(scheduled) < today()
+ - and:
+ - due.isEmpty() == false
+ - date(due) < today()
+ - and:
+ - scheduled.isEmpty() == false
+ - date(scheduled) < today()
order:
- status
- priority
@@ -172,32 +154,28 @@ views:
- complete_instances
- file.tasks
sort:
- - column: formula.urgencyScore
+ - property: formula.urgencyScore
direction: DESC
- type: tasknotesTaskList
- name: "This Week"
+ name: This Week
filters:
and:
- # Incomplete tasks
- or:
- # Non-recurring task that's not in any completed status
- - and:
- - recurrence.isEmpty()
- - status != "done"
- # Recurring task where today is not in complete_instances
- - and:
- - recurrence.isEmpty() == false
- - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- # Due or scheduled this week
+ - and:
+ - recurrence.isEmpty()
+ - status != "done"
+ - and:
+ - recurrence.isEmpty() == false
+ - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- or:
- - and:
- - due.isEmpty() == false
- - date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD")
- - date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
- - and:
- - scheduled.isEmpty() == false
- - date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD")
- - date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ - and:
+ - due.isEmpty() == false
+ - date(due).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD")
+ - date(due).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
+ - and:
+ - scheduled.isEmpty() == false
+ - date(scheduled).format("YYYY-MM-DD") >= today().format("YYYY-MM-DD")
+ - date(scheduled).format("YYYY-MM-DD") <= (today() + "7 days").format("YYYY-MM-DD")
order:
- status
- priority
@@ -207,23 +185,19 @@ views:
- complete_instances
- file.tasks
sort:
- - column: formula.urgencyScore
+ - property: formula.urgencyScore
direction: DESC
- type: tasknotesTaskList
- name: "Unscheduled"
+ name: Unscheduled
filters:
and:
- # Incomplete tasks
- or:
- # Non-recurring task that's not in any completed status
- - and:
- - recurrence.isEmpty()
- - status != "done"
- # Recurring task where today is not in complete_instances
- - and:
- - recurrence.isEmpty() == false
- - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- # No due date and no scheduled date
+ - and:
+ - recurrence.isEmpty()
+ - status != "done"
+ - and:
+ - recurrence.isEmpty() == false
+ - complete_instances.map(date(value).format("YYYY-MM-DD")).contains(today().format("YYYY-MM-DD")) != true
- date(due).isEmpty()
- date(scheduled).isEmpty()
order:
@@ -235,5 +209,5 @@ views:
- complete_instances
- file.tasks
sort:
- - column: status
+ - property: status
direction: ASC
diff --git a/timestamped/2026-06-05_09-20-40.md b/timestamped/2026-06-05_09-20-40.md
new file mode 100644
index 0000000..48c245a
--- /dev/null
+++ b/timestamped/2026-06-05_09-20-40.md
@@ -0,0 +1,42 @@
+---
+id: 2026-06-05T09:20:40-0400
+title: 2026-06-05 09:20:40
+tags: []
+daily: "[[2026-06-05]]"
+---
+# 2026-06-05 09:20:40
+
+## LiveCount Feedback
+
+### Which LiveCount features do you **like**?
+
+* Adding and deleting from existing runs immediately updating Accubid
+ is an excellent pattern.
+ I teach estimators to count the obvious symbols
+ then move on to the next assembly,
+ using Add to Run at the end to pick up what was missed.
+
+* The new Overlay manual alignment pattern is much better.
+
+### Which LiveCount features do you **not like**?
+
+* Reverse takeoffs "un-reverse" when adding or deleting from a run.
+
+* Overlay Auto-align is turned on by default,
+ requiring me to wait seconds which feel like an eternity for each one,
+ even when I know from the previous that it will not align correctly.
+
+* Overlay Auto-align appears to give equal preference to drawing titles
+ meaning it always results in a zero translation alignment.
+
+* Overlays turn off when the overlay menu is closed.
+
+### Which features do you miss and should be added?
+
+### Is there anything else you would like to add?
+
+* Gating LiveCount features behind Anywhere
+ (Auto-homerun)
+ but still mentioning them in the changelogs
+ is up-selly and confusing.
+
diff --git a/timestamped/2026-06-05_09-48-37.md b/timestamped/2026-06-05_09-48-37.md
new file mode 100644
index 0000000..b65fa4b
--- /dev/null
+++ b/timestamped/2026-06-05_09-48-37.md
@@ -0,0 +1,36 @@
+---
+id: 2026-06-05T09:48:37-0400
+title: 2026-06-05 09:48:37
+tags: []
+daily: "[[2026-06-05]]"
+---
+# 2026-06-05 09:48:37
+
+## Accubid Reverse Takeoff
+
+I have mixed feelings
+about using negative or "reverse" takeoffs
+in [[accubid|Accubid]].
+
+### Pros
+
+Pros as an alternative to simply changing existing counts.
+
+With more than one revision,
+it quickly becomes difficult to have confidence in count changes.
+
+### Cons
+
+This note specifically concerns using negative quantities
+to cancel out positive for breakdown purposes,
+which I suspect is the only practical purpose for them.
+Net negative quantities cause all kinds of problems.
+There is no link from the positive to the negative,
+so any change to the former must be repeated for the latter.
+
+With more than one revision,
+determining net takeoff quickly becomes unwieldy.
+
+LiveCount "un-reverses" reverse takeoffs
+when adding or deleting from an existing run,
+which is not intuitive or well known.
diff --git a/timestamped/2026-06-05_10-07-40.md b/timestamped/2026-06-05_10-07-40.md
new file mode 100644
index 0000000..625531d
--- /dev/null
+++ b/timestamped/2026-06-05_10-07-40.md
@@ -0,0 +1,20 @@
+---
+id: 2026-06-05T10:07:40-0400
+title: 2026-06-05 10:07:40
+tags: []
+daily: "[[2026-06-05]]"
+---
+# 2026-06-05 10:07:40
+
+In [[construction-estimating-software]]
+it would always make more sense
+to model count-based assemblies
+as individual line items
+rather than counts in a single run of that assembly type.
+This would allow per-instance breakdowns and substitution
+without need to delete from one to create another.
+
+Were it not for Accubid's poor performance
+with 1000+ takeoff jobs,
+our own workflow could benefit from this arrangement
+if LiveCount would better support it.
diff --git a/timestamped/ensure_dailies.py b/timestamped/ensure_dailies.py
deleted file mode 100644
index 2918c20..0000000
--- a/timestamped/ensure_dailies.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""
-This script ensures that every daily note linked in the timestamped notes exists.
-"""
-import frontmatter
-import io
-import glob
-from datetime import datetime
-import os
-
-timestamped_notes = glob.glob("timestamped/*.md")
-
-daily_links = set()
-for child in timestamped_notes:
- with io.open(child, 'r') as file:
- link = frontmatter.load(file).get('daily')
- daily_links.add(link)
-
-new_daily_names = set()
-for link in daily_links:
- base_name = link[2:-2]
- path = f"periodic/daily/{base_name}.md"
- if not os.path.exists(path):
- new_daily_names.add(base_name)
-
-print(new_daily_names)
-
-# for name in new_daily_names:
-# date = datetime.strptime(name, '%Y-%m-%d')
-
-# with io.open(f"periodic/daily/{name}.md", 'x', encoding='utf8') as f:
-# f.write(f"# {name}\n\n")
-
-# post = frontmatter.load(f)
-
-# post['id'] = name
-# post['aliases'] = []
-# post['title'] = name
-# post['tags'] = [
-# 'authorship/original',
-# 'destiny/permanent',
-# 'status/draft',
-# 'type/periodic/daily'
-# ]
-# post['dg-publish'] = True
-# post['date-created'] = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
-# post['weekly'] = f'"[[{date.strftime('%Y-[W]%W')}]]"'
-# post['monthly'] = f'"[[{date.strftime('%Y-%m')}]]"'
-# post['quarterly'] = f'"[[{date.strftime('%Y-[Q]%q')}]]"'
-# post['yearly'] = f'"[[{date.strftime('%Y')}]]"'
-
-# frontmatter.dump(post, f)