From a4714f6fa82b67e06f108f1f15e4f9ed3a4b9fbe Mon Sep 17 00:00:00 2001 From: Olivier Legendre Date: Mon, 8 Jun 2026 12:32:21 -0400 Subject: [PATCH] Add period note commands with hotkeys and next/prev navigation - Add 5 'Go to' commands with default hotkeys: Ctrl+Shift+Alt+D/W/M/Q/Y for daily/weekly/monthly/quarterly/yearly - Add 10 navigation commands (next/prev) for each period type - Add detectPeriodType() and navigatePeriodNote() helpers - Bump version to 1.1.0 --- main.js | 18 ++++---- manifest.json | 2 +- package.json | 2 +- src/main.ts | 124 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 133 insertions(+), 13 deletions(-) diff --git a/main.js b/main.js index e447d46..83cb411 100644 --- a/main.js +++ b/main.js @@ -2,15 +2,15 @@ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD */ -var V=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var U=(f,d)=>{for(var t in d)V(f,t,{get:d[t],enumerable:!0})},K=(f,d,t,e)=>{if(d&&typeof d=="object"||typeof d=="function")for(let a of H(d))!_.call(f,a)&&a!==t&&V(f,a,{get:()=>d[a],enumerable:!(e=Q(d,a))||e.enumerable});return f};var X=f=>K(V({},"__esModule",{value:!0}),f);var ee={};U(ee,{default:()=>R});module.exports=X(ee);var b=require("obsidian");var j={calendar:{firstDayOfWeek:1,showNoteIndicators:!0},daily:{folder:"periodic/daily",templateFile:"Templates/Daily note",nameFormat:"YYYY-MM-DD",typeProperty:"daily-note"},weekly:{folder:"periodic/weekly",templateFile:"Templates/Weekly note",nameFormat:"GGGG-[W]WW",typeProperty:"weekly-note"},monthly:{folder:"periodic/monthly",templateFile:"Templates/Monthly note",nameFormat:"YYYY-MM",typeProperty:"monthly-note"},quarterly:{folder:"periodic/quarterly",templateFile:"Templates/Quarterly note",nameFormat:"YYYY-[Q]Q",typeProperty:"quarterly-note"},yearly:{folder:"periodic/yearly",templateFile:"Templates/Yearly note",nameFormat:"YYYY",typeProperty:"yearly-note"},recentFiles:{maxItems:50,updateOn:"file-open",omittedPaths:[],omittedTags:[]}};var u=require("obsidian"),W=class extends u.PluginSettingTab{constructor(d,t,e,a){super(d,t),this.plugin=t,this.settings=e,this.onSettingsChange=a}display(){let{containerEl:d}=this;d.empty(),new u.Setting(d).setHeading().setName("Calendar"),new u.Setting(d).setName("First day of week").setDesc("Which day the calendar week starts on.").addDropdown(a=>{a.addOption("0","Sunday").addOption("1","Monday").setValue(String(this.settings.calendar.firstDayOfWeek)).onChange(s=>{this.settings.calendar.firstDayOfWeek=parseInt(s,10),this.saveAndRefresh()})}),new u.Setting(d).setName("Show note indicators").setDesc("Show a dot on days that have existing notes.").addToggle(a=>{a.setValue(this.settings.calendar.showNoteIndicators).onChange(s=>{this.settings.calendar.showNoteIndicators=s,this.saveAndRefresh()})}),new u.Setting(d).setHeading().setName("Periodic Note Paths"),this.addPeriodNoteSettings("Daily",this.settings.daily),this.addPeriodNoteSettings("Weekly",this.settings.weekly),this.addPeriodNoteSettings("Monthly",this.settings.monthly),this.addPeriodNoteSettings("Quarterly",this.settings.quarterly),this.addPeriodNoteSettings("Yearly",this.settings.yearly),new u.Setting(d).setHeading().setName("Recent Files"),new u.Setting(d).setName("Max items").setDesc("Maximum number of recent files to track.").addText(a=>{a.inputEl.setAttr("type","number"),a.inputEl.setAttr("placeholder","50"),a.setValue(String(this.settings.recentFiles.maxItems)),a.inputEl.onblur=()=>{let s=parseInt(a.getValue(),10);!isNaN(s)&&s>0&&(this.settings.recentFiles.maxItems=s,this.saveAndRefresh())}}),new u.Setting(d).setName("Update on").setDesc("When to add a file to the recent list.").addDropdown(a=>{a.addOption("file-open","File opened").addOption("file-edit","File changed").setValue(this.settings.recentFiles.updateOn).onChange(s=>{this.settings.recentFiles.updateOn=s,this.saveAndRefresh()})});let t=new DocumentFragment;t.appendText("Regex patterns for paths to exclude. One per line."),new u.Setting(d).setName("Omitted paths").setDesc(t).addTextArea(a=>{a.inputEl.setAttr("rows",4),a.setPlaceholder(`^archives/ -\\.png$`),a.setValue(this.settings.recentFiles.omittedPaths.join(` -`)),a.inputEl.onblur=()=>{this.settings.recentFiles.omittedPaths=a.getValue().split(` -`).filter(s=>s.trim()),this.saveAndRefresh()}});let e=new DocumentFragment;e.appendText("Regex patterns for frontmatter tags to exclude. One per line."),new u.Setting(d).setName("Omitted tags").setDesc(e).addTextArea(a=>{a.inputEl.setAttr("rows",4),a.setPlaceholder(`ignore -archive`),a.setValue(this.settings.recentFiles.omittedTags.join(` -`)),a.inputEl.onblur=()=>{this.settings.recentFiles.omittedTags=a.getValue().split(` -`).filter(s=>s.trim()),this.saveAndRefresh()}})}addPeriodNoteSettings(d,t){new u.Setting(this.containerEl).setHeading().setName(d),new u.Setting(this.containerEl).setName("Folder").setDesc(`Folder path for ${d.toLowerCase()} notes.`).addText(e=>{e.setPlaceholder("periodic/daily"),e.setValue(t.folder),e.onChange(a=>{t.folder=a,this.saveAndRefresh()})}),new u.Setting(this.containerEl).setName("Name format").setDesc(`Date format for ${d.toLowerCase()} note filenames (moment.js format).`).addText(e=>{e.setPlaceholder("yyyy-MM-dd"),e.setValue(t.nameFormat),e.onChange(a=>{t.nameFormat=a,this.saveAndRefresh()})}),new u.Setting(this.containerEl).setName("Template file").setDesc("Path to the template file (without .md extension).").addText(e=>{e.setPlaceholder("Templates/Daily note"),e.setValue(t.templateFile),e.onChange(a=>{t.templateFile=a,this.saveAndRefresh()})}),new u.Setting(this.containerEl).setName("Type property").setDesc("Value for the 'type' frontmatter property.").addText(e=>{e.setPlaceholder("daily-note"),e.setValue(t.typeProperty),e.onChange(a=>{t.typeProperty=a,this.saveAndRefresh()})})}async saveAndRefresh(){await this.plugin.saveData(this.settings),this.onSettingsChange()}};var h=require("obsidian");var F=require("obsidian");function z(f,d,t){let e=(0,F.moment)({year:f,month:d,day:1}),a=(0,F.moment)(e).endOf("month"),s=(0,F.moment)(e).subtract((e.day()-t+7)%7,"days"),o=(0,F.moment)().startOf("day"),l=[],n=(0,F.moment)(s);for(;n.isBefore(a)||n.month()===d;){let i=[];for(let r=0;r<7;r++)i.push({date:(0,F.moment)(n),dayOfMonth:n.date(),isToday:n.isSame(o,"day"),isCurrentMonth:n.month()===d,isoWeekNumber:n.isoWeek()}),n.add(1,"day");if(l.push({weekNumber:i[0].isoWeekNumber,days:i}),l.length>=6)break}return l}var w="waypoint-view",A=class extends h.ItemView{constructor(t,e){super(t);this.redraw=()=>{this.contentEl.empty(),this.contentEl.addClass("waypoint-view"),this.renderFavorites(),this.renderRecentFiles(),this.renderCalendar()};this.currentDisplayMonth=(0,h.moment)().month();this.currentDisplayYear=(0,h.moment)().year();this.dragId=null;this.plugin=e}getViewType(){return w}getDisplayText(){return"Waypoint"}getIcon(){return"compass"}async onOpen(){this.redraw()}async onClose(){}renderCalendar(){let t=this.contentEl.createDiv({cls:"waypoint-section"});t.createDiv({cls:"waypoint-section-header",text:"Calendar"});let e=t.createDiv({cls:"waypoint-calendar"}),a=(0,h.moment)(),s=(0,h.moment)({year:this.currentDisplayYear,month:this.currentDisplayMonth,day:1}),o=e.createDiv({cls:"waypoint-calendar-top"}),l=o.createDiv({cls:"waypoint-calendar-breadcrumb"}),n=s.format("[Q]Q");l.createSpan({cls:"waypoint-clickable",text:n}).addEventListener("click",()=>{this.plugin.openPeriodNote("quarter",s)});let r=s.format("MMMM");l.createSpan({cls:"waypoint-clickable",text:r}).addEventListener("click",()=>{this.plugin.openPeriodNote("month",s)});let c=s.format("YYYY");l.createSpan({cls:"waypoint-clickable",text:c}).addEventListener("click",()=>{this.plugin.openPeriodNote("year",s)});let D=o.createDiv({cls:"waypoint-calendar-today-group"}),x=D.createEl("button",{cls:"waypoint-calendar-nav-btn"});(0,h.setIcon)(x,"chevron-left"),x.addEventListener("click",()=>this.navigateMonth(-1)),D.createEl("button",{cls:"waypoint-calendar-today-btn",text:"Today"}).addEventListener("click",()=>{this.currentDisplayMonth=(0,h.moment)().month(),this.currentDisplayYear=(0,h.moment)().year(),this.redraw()});let M=D.createEl("button",{cls:"waypoint-calendar-nav-btn"});(0,h.setIcon)(M,"chevron-right"),M.addEventListener("click",()=>this.navigateMonth(1));let E=e.createEl("table"),I=E.createEl("thead").createEl("tr");I.createEl("th",{text:""});let g=["sun","mon","tue","wed","thu","fri","sat"],Y=this.plugin.settings.calendar.firstDayOfWeek;for(let y=0;y<7;y++){let S=(Y+y)%7;I.createEl("th",{text:g[S]})}let v=E.createEl("tbody"),T=z(this.currentDisplayYear,this.currentDisplayMonth,this.plugin.settings.calendar.firstDayOfWeek);for(let y of T){let S=v.createEl("tr"),N=S.createEl("td",{cls:"waypoint-weeknum"});N.setText(String(y.weekNumber)),N.addEventListener("click",()=>{let k=y.days[0].date;this.plugin.openPeriodNote("week",k)});for(let k of y.days){let C=S.createEl("td",{cls:"waypoint-day"});if(C.setText(String(k.dayOfMonth)),k.isCurrentMonth||C.addClass("other-month"),k.isToday&&C.addClass("today"),this.plugin.settings.calendar.showNoteIndicators){let O=k.date.format("YYYY-MM-DD");this.plugin.app.vault.getFiles().some(q=>q.extension==="md"&&q.basename===O)&&C.addClass("has-note")}C.addEventListener("click",()=>{this.plugin.openPeriodNote("day",k.date)})}}}navigateMonth(t){let e=(0,h.moment)({year:this.currentDisplayYear,month:this.currentDisplayMonth}).add(t,"month");this.currentDisplayMonth=e.month(),this.currentDisplayYear=e.year(),this.redraw()}renderRecentFiles(){let t=this.contentEl.createDiv({cls:"waypoint-section waypoint-recent-files"});if(t.createDiv({cls:"waypoint-section-header",text:"Recent Files"}),this.plugin.recentFiles.length===0){t.createDiv({cls:"nav-file",text:"No recent files"});return}let e=this.app.workspace.getActiveFile(),a=t.createDiv({cls:"nav-folder mod-root"}),s=a.createDiv({cls:"nav-folder-children"});for(let o of this.plugin.recentFiles){let l=s.createDiv({cls:"tree-item nav-file"}),n=l.createDiv({cls:"tree-item-self is-clickable nav-file-title"});n.createDiv({cls:"tree-item-inner nav-file-title-content"}).setText(o.basename);let r=n.createDiv({cls:"tree-item-spacer"}),p=n.createDiv({cls:"waypoint-recent-remove"});(0,h.setIcon)(p,"x"),p.addEventListener("click",c=>{c.stopPropagation(),this.plugin.recentFiles=this.plugin.recentFiles.filter(m=>m.path!==o.path),this.plugin.saveSettings(),this.redraw()}),(0,h.setTooltip)(l,o.path),e&&o.path===e.path&&n.addClass("is-active"),n.setAttr("draggable","true"),n.addEventListener("dragstart",c=>{let m=this.app.metadataCache.getFirstLinkpathDest(o.path,"");m&&(this.app.dragManager.dragFile(c,m),this.app.dragManager.onDragStart(c,this.app.dragManager.dragFile(c,m)))}),n.addEventListener("mouseover",c=>{this.app.workspace.trigger("hover-link",{event:c,source:w,hoverParent:a,targetEl:l,linktext:o.path})}),n.addEventListener("contextmenu",c=>{let m=new h.Menu;m.addItem(x=>x.setSection("action").setTitle("Open in new tab").setIcon("file-plus").onClick(()=>this.focusFile(o,"tab")));let D=this.app.vault.getAbstractFileByPath(o.path);D&&this.app.workspace.trigger("file-menu",m,D,"link-context-menu"),m.showAtPosition({x:c.clientX,y:c.clientY})}),n.addEventListener("click",c=>{let m=h.Keymap.isModEvent(c);this.focusFile(o,m)}),n.addEventListener("mousedown",c=>{c.button===1&&(c.preventDefault(),this.focusFile(o,"tab"))})}}focusFile(t,e){let a=this.app.vault.getFiles().find(s=>s.path===t.path);a?this.app.workspace.getLeaf(e).openFile(a):(new h.Notice("Cannot find file"),this.plugin.recentFiles=this.plugin.recentFiles.filter(s=>s.path!==t.path),this.plugin.saveSettings(),this.redraw())}renderFavorites(){let t=this.contentEl.createDiv({cls:"waypoint-section waypoint-favorites"}),e=t.createDiv({cls:"waypoint-section-header"});if(e.setText("Waypoint Bookmarks"),e.addEventListener("contextmenu",a=>{let s=new h.Menu;s.addItem(o=>{o.setTitle("Add current file").setIcon("file-plus").onClick(()=>{let l=this.app.workspace.getActiveFile();l&&this.plugin.addBookmark(l.path,l.basename,"file")})}),s.addItem(o=>{o.setTitle("New group").setIcon("folder-plus").onClick(()=>{this.plugin.addBookmark("","New Group","group","folder")})}),s.addItem(o=>{o.setTitle("Add separator").setIcon("minus").onClick(()=>{this.plugin.addBookmark("","","separator")})}),s.addItem(o=>{o.setTitle("Add spacer").setIcon("space").onClick(()=>{this.plugin.addBookmark("","","spacer")})}),s.showAtPosition({x:a.clientX,y:a.clientY})}),this.plugin.waypointData.bookmarks.length===0){t.createDiv({cls:"waypoint-bookmark-item",text:"No bookmarks"});return}this.renderBookmarkList(t,this.plugin.waypointData.bookmarks,0)}renderBookmarkList(t,e,a){for(let s=0;s{this.dragId=o.id,r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",o.id),i.addClass("waypoint-bm-dragging")}),i.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(r=>{r.removeClass("waypoint-bm-dragging"),r.removeClass("waypoint-bm-drop-line"),r.removeClass("waypoint-bm-drop-below")})}),i.addEventListener("dragenter",r=>{r.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(i,r)}),i.addEventListener("dragover",r=>{r.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(i,r)}),i.addEventListener("dragleave",()=>{i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")}),i.addEventListener("drop",r=>{var m;r.preventDefault(),this.dragId=null,i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below");let p=(m=r.dataTransfer)==null?void 0:m.getData("text/plain");if(!p||p===o.id)return;let c=i.__dropAbove;this.moveBookmarkToPosition(p,o.id,c)}),i.addEventListener("contextmenu",r=>{r.stopPropagation(),r.preventDefault(),this.showBookmarkContextMenu(r,o)});continue}if(o.type==="spacer"){let i=t.createDiv({cls:"waypoint-bookmark-item waypoint-bookmark-spacer"});i.setAttr("draggable","true"),i.setAttr("data-bm-id",o.id),i.style.paddingLeft=`${8+a*16}px`,i.style.cursor="grab",i.addEventListener("dragstart",r=>{this.dragId=o.id,r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",o.id),i.addClass("waypoint-bm-dragging")}),i.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(r=>{r.removeClass("waypoint-bm-dragging"),r.removeClass("waypoint-bm-drop-line"),r.removeClass("waypoint-bm-drop-below")})}),i.addEventListener("dragenter",r=>{r.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(i,r)}),i.addEventListener("dragover",r=>{r.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(i,r)}),i.addEventListener("dragleave",()=>{i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")}),i.addEventListener("drop",r=>{var m;r.preventDefault(),this.dragId=null,i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below");let p=(m=r.dataTransfer)==null?void 0:m.getData("text/plain");if(!p||p===o.id)return;let c=i.__dropAbove;this.moveBookmarkToPosition(p,o.id,c)}),i.addEventListener("contextmenu",r=>{r.stopPropagation(),r.preventDefault(),this.showBookmarkContextMenu(r,o)});continue}let l=o.type==="group",n=t.createDiv({cls:`waypoint-bookmark-item${l?" waypoint-bookmark-group":""}${o.collapsed?" collapsed":""}`});if(n.setAttr("draggable","true"),n.setAttr("data-bm-id",o.id),l||(n.style.paddingLeft=`${8+a*16}px`),n.addEventListener("dragstart",i=>{this.dragId=o.id,i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",o.id),n.addClass("waypoint-bm-dragging")}),n.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(i=>{i.removeClass("waypoint-bm-dragging"),i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")})}),n.addEventListener("dragenter",i=>{i.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(n,i)}),n.addEventListener("dragover",i=>{i.preventDefault(),!(!this.dragId||this.dragId===o.id)&&this.showDropIndicator(n,i)}),n.addEventListener("dragleave",()=>{n.removeClass("waypoint-bm-drop-line"),n.removeClass("waypoint-bm-drop-below")}),n.addEventListener("drop",i=>{var c;i.preventDefault(),this.dragId=null,n.removeClass("waypoint-bm-drop-line"),n.removeClass("waypoint-bm-drop-below");let r=(c=i.dataTransfer)==null?void 0:c.getData("text/plain");if(!r||r===o.id)return;let p=n.__dropAbove;this.moveBookmarkToPosition(r,o.id,p)}),l){let i=n.createDiv({cls:"waypoint-bm-chevron"});(0,h.setIcon)(i,"chevron-down");let r=n.createDiv({cls:"waypoint-bm-icon"});(0,h.setIcon)(r,o.icon||"folder");let p=n.createDiv({cls:"waypoint-bm-label",text:o.label});n.addEventListener("click",()=>{this.plugin.updateBookmark(o.id,{collapsed:!o.collapsed})});let c=t.createDiv({cls:`waypoint-bookmark-children${o.collapsed?" collapsed":""}`});o.children&&o.children.length>0&&this.renderBookmarkList(c,o.children,a+1)}else{let i=n.createDiv({cls:"waypoint-bm-icon"});(0,h.setIcon)(i,o.icon||"file");let r=n.createDiv({cls:"waypoint-bm-label",text:o.label});(0,h.setTooltip)(n,o.filePath),n.addEventListener("click",()=>{if(o.filePath){let p=this.app.vault.getFileByPath(o.filePath);p?this.app.workspace.getLeaf(!1).openFile(p):(new h.Notice("File not found"),this.plugin.removeBookmark(o.id))}})}n.addEventListener("contextmenu",i=>{i.stopPropagation(),i.preventDefault(),this.showBookmarkContextMenu(i,o)})}}showBookmarkContextMenu(t,e){let a=new h.Menu;e.type==="file"&&(a.addItem(n=>n.setTitle("Open in new tab").setIcon("file-plus").onClick(()=>{let i=this.app.vault.getFileByPath(e.filePath);i&&this.app.workspace.getLeaf("tab").openFile(i)})),a.addSeparator()),e.type!=="separator"&&e.type!=="spacer"&&(a.addItem(n=>n.setTitle("Rename").setIcon("pencil").onClick(()=>this.promptRename(e))),a.addItem(n=>n.setTitle("Change icon").setIcon("image").onClick(()=>this.promptIcon(e))));let s=this.collectGroups(this.plugin.waypointData.bookmarks),o=this.collectDescendantIds(e),l=s.filter(n=>!o.includes(n.id)&&n.id!==e.id);if((l.length>0||e.type==="file"||e.type==="group")&&e.type!=="separator"&&e.type!=="spacer"){if(a.addSeparator(),l.length>0)for(let n of l)a.addItem(i=>i.setTitle(` ${n.label}`).setIcon(n.icon||"folder").onClick(()=>{this.moveBookmarkToGroup(e.id,n.id)}));a.addItem(n=>n.setTitle(" (Root)").setIcon("layout").onClick(()=>{this.moveBookmarkToGroup(e.id,null)}))}e.type==="group"&&(a.addItem(n=>n.setTitle(e.collapsed?"Expand":"Collapse").setIcon(e.collapsed?"chevron-down":"chevron-up").onClick(()=>{this.plugin.updateBookmark(e.id,{collapsed:!e.collapsed})})),a.addSeparator(),a.addItem(n=>n.setTitle("Add bookmark here").setIcon("plus").onClick(()=>{let i=this.app.workspace.getActiveFile();if(!i){new h.Notice("No active file");return}let r={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"file",label:i.basename,filePath:i.path,icon:"file",children:[],collapsed:!1,indent:e.indent+1};e.children.push(r),this.plugin.saveWaypointData(),this.redraw()})),a.addItem(n=>n.setTitle("New sub-group").setIcon("folder-plus").onClick(()=>{let i={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"group",label:"New Group",filePath:"",icon:"folder",children:[],collapsed:!1,indent:e.indent+1};e.children.push(i),this.plugin.saveWaypointData(),this.redraw()}))),a.addSeparator(),a.addItem(n=>n.setTitle("Insert separator above").setIcon("separator-vertical").onClick(()=>this.insertAdjacent(e.id,"separator","above"))),a.addItem(n=>n.setTitle("Insert separator below").setIcon("separator-vertical").onClick(()=>this.insertAdjacent(e.id,"separator","below"))),a.addItem(n=>n.setTitle("Insert spacer above").setIcon("space").onClick(()=>this.insertAdjacent(e.id,"spacer","above"))),a.addItem(n=>n.setTitle("Insert spacer below").setIcon("space").onClick(()=>this.insertAdjacent(e.id,"spacer","below"))),a.addSeparator(),a.addItem(n=>n.setTitle("Remove").setIcon("trash").onClick(()=>{this.plugin.removeBookmark(e.id)})),a.showAtPosition({x:t.clientX,y:t.clientY})}insertAdjacent(t,e,a){let s={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e,label:"",filePath:"",icon:"",children:[],collapsed:!1,indent:0},o=l=>{let n=l.findIndex(i=>i.id===t);if(n>=0){let i=a==="above"?n:n+1;return l.splice(i,0,s),!0}for(let i of l)if(i.children&&o(i.children))return!0;return!1};o(this.plugin.waypointData.bookmarks),this.plugin.saveWaypointData(),this.redraw()}collectGroups(t){let e=[];for(let a of t)a.type==="group"&&(e.push(a),e.push(...this.collectGroups(a.children)));return e}collectDescendantIds(t){let e=[];for(let a of t.children)e.push(a.id),e.push(...this.collectDescendantIds(a));return e}showDropIndicator(t,e){let a=t.parentElement;a&&a.querySelectorAll(".waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(n=>{n.removeClass("waypoint-bm-drop-line"),n.removeClass("waypoint-bm-drop-below")});let s=t.getBoundingClientRect(),o=s.top+s.height/2,l=e.clientY{let l=o.findIndex(n=>n.id===t);if(l>=0){let[n]=o.splice(l,1);return n}for(let n of o){let i=a(n.children);if(i)return i}return null},s=a(this.plugin.waypointData.bookmarks);if(s){if(e){let o=n=>{for(let i of n){if(i.id===e)return i;let r=o(i.children);if(r)return r}return null},l=o(this.plugin.waypointData.bookmarks);l&&(s.indent=l.indent+1,l.children.push(s))}else s.indent=0,this.plugin.waypointData.bookmarks.push(s);this.plugin.saveWaypointData(),this.redraw()}}moveBookmarkToPosition(t,e,a){let s=i=>{let r=i.findIndex(p=>p.id===t);if(r>=0){let[p]=i.splice(r,1);return{item:p,parent:i}}for(let p of i)if(p.children){let c=s(p.children);if(c.item)return c}return{item:null,parent:[]}},{item:o}=s(this.plugin.waypointData.bookmarks);if(!o)return;let l=i=>{let r=i.findIndex(p=>p.id===e);if(r>=0)return{parent:i,idx:r};for(let p of i)if(p.children){let c=l(p.children);if(c)return c}return null},n=l(this.plugin.waypointData.bookmarks);if(!n)o.indent=0,this.plugin.waypointData.bookmarks.push(o);else{let i=a?n.idx:n.idx+1;n.parent.splice(i,0,o)}this.plugin.saveWaypointData(),this.redraw()}promptRename(t){new $(this.app,t.label,e=>{e&&e.trim()&&this.plugin.updateBookmark(t.id,{label:e.trim()})}).open()}promptIcon(t){new G(this.app,t.icon,e=>{e&&this.plugin.updateBookmark(t.id,{icon:e})}).open()}},$=class extends h.Modal{constructor(d,t,e){super(d),this.currentValue=t,this.onSubmit=e}onOpen(){this.titleEl.setText("Rename bookmark");let d=this.contentEl.createEl("input",{type:"text",value:this.currentValue});d.style.width="100%",d.style.marginBottom="12px",d.focus(),d.select();let t=this.contentEl.createDiv({cls:"modal-button-container"}),e=t.createEl("button",{text:"Cancel",cls:"mod-cta"});e.style.marginRight="8px",e.addEventListener("click",()=>this.close()),t.createEl("button",{text:"Save",cls:"mod-cta"}).addEventListener("click",()=>{this.onSubmit(d.value),this.close()}),d.addEventListener("keydown",s=>{s.key==="Enter"&&(this.onSubmit(d.value),this.close())})}onClose(){this.contentEl.empty()}},G=class extends h.Modal{constructor(t,e,a){super(t);this.allIcons=[];this.loaded=!1;this.selected=e,this.onSubmit=a}async onOpen(){let t=this.contentEl;t.style.display="flex",t.style.flexDirection="column",t.style.gap="10px",this.titleEl.setText("Change icon");let e=t.createDiv({cls:"waypoint-icon-preview"});e.style.display="flex",e.style.alignItems="center",e.style.gap="10px",e.style.padding="12px 16px",e.style.borderRadius="8px",e.style.background="var(--background-secondary)",e.style.minHeight="48px";let a=e.createSpan();a.style.display="flex",this.selected&&(0,h.setIcon)(a,this.selected);let s=e.createSpan();s.style.fontWeight="var(--font-medium)",s.style.fontSize="var(--font-ui-medium)",s.setText(this.selected||"No icon");let o=t.createEl("input",{type:"text",placeholder:"Type to search (e.g. arrow, chart, home)..."});Object.assign(o.style,{width:"100%",boxSizing:"border-box",padding:"8px 10px",borderRadius:"6px",border:"1px solid var(--background-modifier-border)",background:"var(--background-primary)",color:"var(--text-normal)",fontSize:"var(--font-ui-medium)"}),o.focus();let l=t.createDiv({cls:"waypoint-icon-grid"});l.style.display="grid",l.style.gridTemplateColumns="repeat(auto-fill, minmax(52px, 1fr))",l.style.gap="4px",l.style.maxHeight="320px",l.style.overflowY="auto",l.style.padding="2px 0";let n=t.createDiv();n.style.display="flex",n.style.justifyContent="space-between",n.style.alignItems="center",n.style.fontSize="var(--font-ui-smaller)",n.style.color="var(--text-muted)",n.style.padding="0 4px";let i=n.createSpan();i.setText("Loading\u2026");let r=n.createSpan();r.style.cursor="var(--cursor)",r.style.color="var(--text-accent)",r.setText("No icon"),r.addEventListener("click",()=>{this.onSubmit(""),this.close()}),this.loadIcons().then(()=>{this.loaded=!0,i.setText(this.allIcons.length+" icons"),c(o.value)});let p=null,c=P=>{if(l.empty(),!this.loaded){l.createDiv({text:"Loading\u2026"});return}let M=P.toLowerCase().trim(),E=M?this.allIcons.filter(function(v){return v.includes(M)}).slice(0,80):this.allIcons.slice(0,80);if(E.length===0){let v=l.createDiv();v.style.gridColumn="1 / -1",v.style.textAlign="center",v.style.color="var(--text-muted)",v.style.padding="20px",v.setText('No icons match "'+P+'"');return}for(var B=0;Bnew A(e,this)),this.addSettingTab(new W(this.app,this,this.settings,()=>this.redrawAll())),this.addCommand({id:"waypoint-open-view",name:"Open Waypoint sidebar",callback:async()=>{let e=this.app.workspace.getLeavesOfType(w);if(e.length>0)await this.app.workspace.revealLeaf(e[0]);else{let a=this.app.workspace.getLeftLeaf(!1);a&&(await a.setViewState({type:w}),await this.app.workspace.revealLeaf(a))}}}),this.addCommand({id:"waypoint-add-bookmark",name:"Add current file as Waypoint bookmark",callback:async()=>{let e=this.app.workspace.getActiveFile();if(!e){new b.Notice("No active file");return}this.addBookmark(e.path,e.basename,"file"),new b.Notice(`Bookmarked: ${e.basename}`)}}),this.addCommand({id:"waypoint-go-to-today",name:"Go to today's daily note",callback:async()=>{await this.openPeriodNote("day",(0,b.moment)())}}),this.registerEvent(this.app.workspace.on("file-open",e=>{e&&this.onFileOpen(e)})),this.registerEvent(this.app.vault.on("create",()=>this.onVaultChange())),this.registerEvent(this.app.vault.on("delete",()=>this.onVaultChange())),this.registerEvent(this.app.vault.on("rename",(e,a)=>this.onRename(e,a))),this.app.workspace.onLayoutReady(()=>{if(this.app.workspace.getLeavesOfType(w).length===0){let a=this.app.workspace.getLeftLeaf(!1);a&&a.setViewState({type:w})}});let t=new Date().toDateString();this.registerInterval(window.setInterval(()=>{let e=new Date().toDateString();e!==t&&(t=e,this.redrawAll())},6e5))}async onunload(){this.app.workspace.detachLeavesOfType(w)}async loadSettings(){let t=await this.loadData(),e=(t==null?void 0:t.settings)||{};this.settings=Object.assign({},j,e)}async saveSettings(){let t=await this.loadData()||{};t.settings=this.settings,await this.saveData(t)}async loadWaypointData(){let t=await this.loadData(),e=(t==null?void 0:t.waypointData)||{};this.waypointData=Object.assign({},Z,e)}async saveWaypointData(){let t=await this.loadData()||{};t.waypointData=this.waypointData,await this.saveData(t)}onFileOpen(t){this.settings.recentFiles.updateOn!=="file-edit"&&this.addToRecentFiles(t)}addToRecentFiles(t){this.recentFiles=this.recentFiles.filter(e=>e.path!==t.path),this.recentFiles.unshift({path:t.path,basename:t.basename}),this.recentFiles.length>this.settings.recentFiles.maxItems&&(this.recentFiles=this.recentFiles.slice(0,this.settings.recentFiles.maxItems)),this.broadcastRedraw()}onRename(t,e){let a=this.recentFiles.find(s=>s.path===e);a&&(a.path=t.path,a.basename=t.basename||t.name.replace(/\.[^/.]+$/,""),this.broadcastRedraw()),this.updateBookmarkPath(e,t.path)}onVaultChange(){this.broadcastRedraw()}addBookmark(t,e,a="file",s="file"){let l={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:a,label:e,filePath:a==="file"?t:"",icon:s,children:[],collapsed:!1,indent:0};return this.waypointData.bookmarks.push(l),this.saveWaypointData(),this.broadcastRedraw(),l}removeBookmark(t){let e=a=>{let s=a.findIndex(o=>o.id===t);if(s>=0)return a.splice(s,1),!0;for(let o of a)if(o.children&&e(o.children))return!0;return!1};e(this.waypointData.bookmarks),this.saveWaypointData(),this.broadcastRedraw()}updateBookmark(t,e){let a=o=>{for(let l of o){if(l.id===t)return l;if(l.children){let n=a(l.children);if(n)return n}}return null},s=a(this.waypointData.bookmarks);s&&(Object.assign(s,e),this.saveWaypointData(),this.broadcastRedraw())}updateBookmarkPath(t,e){let a=s=>{for(let o of s)o.filePath===t&&(o.filePath=e),o.children&&a(o.children)};a(this.waypointData.bookmarks)}async openPeriodNote(t,e){let s={day:{settings:this.settings.daily,label:"Daily"},week:{settings:this.settings.weekly,label:"Weekly"},month:{settings:this.settings.monthly,label:"Monthly"},quarter:{settings:this.settings.quarterly,label:"Quarterly"},year:{settings:this.settings.yearly,label:"Yearly"}}[t];if(!s)return;let{settings:o}=s,l=e.format(o.nameFormat)+".md",n=o.folder?`${o.folder}/${l}`:l,i=this.app.vault.getFileByPath(n);if(!i){try{let r=o.templateFile+".md",p=this.app.vault.getFileByPath(r);if(p){let c=await this.app.vault.read(p);i=await this.app.vault.create(n,c)}else{let c=`--- -type: ${o.typeProperty} +var $=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var U=(f,d)=>{for(var t in d)$(f,t,{get:d[t],enumerable:!0})},K=(f,d,t,e)=>{if(d&&typeof d=="object"||typeof d=="function")for(let n of H(d))!_.call(f,n)&&n!==t&&$(f,n,{get:()=>d[n],enumerable:!(e=z(d,n))||e.enumerable});return f};var X=f=>K($({},"__esModule",{value:!0}),f);var ee={};U(ee,{default:()=>R});module.exports=X(ee);var u=require("obsidian");var j={calendar:{firstDayOfWeek:1,showNoteIndicators:!0},daily:{folder:"periodic/daily",templateFile:"Templates/Daily note",nameFormat:"YYYY-MM-DD",typeProperty:"daily-note"},weekly:{folder:"periodic/weekly",templateFile:"Templates/Weekly note",nameFormat:"GGGG-[W]WW",typeProperty:"weekly-note"},monthly:{folder:"periodic/monthly",templateFile:"Templates/Monthly note",nameFormat:"YYYY-MM",typeProperty:"monthly-note"},quarterly:{folder:"periodic/quarterly",templateFile:"Templates/Quarterly note",nameFormat:"YYYY-[Q]Q",typeProperty:"quarterly-note"},yearly:{folder:"periodic/yearly",templateFile:"Templates/Yearly note",nameFormat:"YYYY",typeProperty:"yearly-note"},recentFiles:{maxItems:50,updateOn:"file-open",omittedPaths:[],omittedTags:[]}};var g=require("obsidian"),W=class extends g.PluginSettingTab{constructor(d,t,e,n){super(d,t),this.plugin=t,this.settings=e,this.onSettingsChange=n}display(){let{containerEl:d}=this;d.empty(),new g.Setting(d).setHeading().setName("Calendar"),new g.Setting(d).setName("First day of week").setDesc("Which day the calendar week starts on.").addDropdown(n=>{n.addOption("0","Sunday").addOption("1","Monday").setValue(String(this.settings.calendar.firstDayOfWeek)).onChange(r=>{this.settings.calendar.firstDayOfWeek=parseInt(r,10),this.saveAndRefresh()})}),new g.Setting(d).setName("Show note indicators").setDesc("Show a dot on days that have existing notes.").addToggle(n=>{n.setValue(this.settings.calendar.showNoteIndicators).onChange(r=>{this.settings.calendar.showNoteIndicators=r,this.saveAndRefresh()})}),new g.Setting(d).setHeading().setName("Periodic Note Paths"),this.addPeriodNoteSettings("Daily",this.settings.daily),this.addPeriodNoteSettings("Weekly",this.settings.weekly),this.addPeriodNoteSettings("Monthly",this.settings.monthly),this.addPeriodNoteSettings("Quarterly",this.settings.quarterly),this.addPeriodNoteSettings("Yearly",this.settings.yearly),new g.Setting(d).setHeading().setName("Recent Files"),new g.Setting(d).setName("Max items").setDesc("Maximum number of recent files to track.").addText(n=>{n.inputEl.setAttr("type","number"),n.inputEl.setAttr("placeholder","50"),n.setValue(String(this.settings.recentFiles.maxItems)),n.inputEl.onblur=()=>{let r=parseInt(n.getValue(),10);!isNaN(r)&&r>0&&(this.settings.recentFiles.maxItems=r,this.saveAndRefresh())}}),new g.Setting(d).setName("Update on").setDesc("When to add a file to the recent list.").addDropdown(n=>{n.addOption("file-open","File opened").addOption("file-edit","File changed").setValue(this.settings.recentFiles.updateOn).onChange(r=>{this.settings.recentFiles.updateOn=r,this.saveAndRefresh()})});let t=new DocumentFragment;t.appendText("Regex patterns for paths to exclude. One per line."),new g.Setting(d).setName("Omitted paths").setDesc(t).addTextArea(n=>{n.inputEl.setAttr("rows",4),n.setPlaceholder(`^archives/ +\\.png$`),n.setValue(this.settings.recentFiles.omittedPaths.join(` +`)),n.inputEl.onblur=()=>{this.settings.recentFiles.omittedPaths=n.getValue().split(` +`).filter(r=>r.trim()),this.saveAndRefresh()}});let e=new DocumentFragment;e.appendText("Regex patterns for frontmatter tags to exclude. One per line."),new g.Setting(d).setName("Omitted tags").setDesc(e).addTextArea(n=>{n.inputEl.setAttr("rows",4),n.setPlaceholder(`ignore +archive`),n.setValue(this.settings.recentFiles.omittedTags.join(` +`)),n.inputEl.onblur=()=>{this.settings.recentFiles.omittedTags=n.getValue().split(` +`).filter(r=>r.trim()),this.saveAndRefresh()}})}addPeriodNoteSettings(d,t){new g.Setting(this.containerEl).setHeading().setName(d),new g.Setting(this.containerEl).setName("Folder").setDesc(`Folder path for ${d.toLowerCase()} notes.`).addText(e=>{e.setPlaceholder("periodic/daily"),e.setValue(t.folder),e.onChange(n=>{t.folder=n,this.saveAndRefresh()})}),new g.Setting(this.containerEl).setName("Name format").setDesc(`Date format for ${d.toLowerCase()} note filenames (moment.js format).`).addText(e=>{e.setPlaceholder("yyyy-MM-dd"),e.setValue(t.nameFormat),e.onChange(n=>{t.nameFormat=n,this.saveAndRefresh()})}),new g.Setting(this.containerEl).setName("Template file").setDesc("Path to the template file (without .md extension).").addText(e=>{e.setPlaceholder("Templates/Daily note"),e.setValue(t.templateFile),e.onChange(n=>{t.templateFile=n,this.saveAndRefresh()})}),new g.Setting(this.containerEl).setName("Type property").setDesc("Value for the 'type' frontmatter property.").addText(e=>{e.setPlaceholder("daily-note"),e.setValue(t.typeProperty),e.onChange(n=>{t.typeProperty=n,this.saveAndRefresh()})})}async saveAndRefresh(){await this.plugin.saveData(this.settings),this.onSettingsChange()}};var h=require("obsidian");var T=require("obsidian");function Q(f,d,t){let e=(0,T.moment)({year:f,month:d,day:1}),n=(0,T.moment)(e).endOf("month"),r=(0,T.moment)(e).subtract((e.day()-t+7)%7,"days"),a=(0,T.moment)().startOf("day"),s=[],o=(0,T.moment)(r);for(;o.isBefore(n)||o.month()===d;){let i=[];for(let l=0;l<7;l++)i.push({date:(0,T.moment)(o),dayOfMonth:o.date(),isToday:o.isSame(a,"day"),isCurrentMonth:o.month()===d,isoWeekNumber:o.isoWeek()}),o.add(1,"day");if(s.push({weekNumber:i[0].isoWeekNumber,days:i}),s.length>=6)break}return s}var b="waypoint-view",Y=class extends h.ItemView{constructor(t,e){super(t);this.redraw=()=>{this.contentEl.empty(),this.contentEl.addClass("waypoint-view"),this.renderFavorites(),this.renderRecentFiles(),this.renderCalendar()};this.currentDisplayMonth=(0,h.moment)().month();this.currentDisplayYear=(0,h.moment)().year();this.dragId=null;this.plugin=e}getViewType(){return b}getDisplayText(){return"Waypoint"}getIcon(){return"compass"}async onOpen(){this.redraw()}async onClose(){}renderCalendar(){let t=this.contentEl.createDiv({cls:"waypoint-section"});t.createDiv({cls:"waypoint-section-header",text:"Calendar"});let e=t.createDiv({cls:"waypoint-calendar"}),n=(0,h.moment)(),r=(0,h.moment)({year:this.currentDisplayYear,month:this.currentDisplayMonth,day:1}),a=e.createDiv({cls:"waypoint-calendar-top"}),s=a.createDiv({cls:"waypoint-calendar-breadcrumb"}),o=r.format("[Q]Q");s.createSpan({cls:"waypoint-clickable",text:o}).addEventListener("click",()=>{this.plugin.openPeriodNote("quarter",r)});let l=r.format("MMMM");s.createSpan({cls:"waypoint-clickable",text:l}).addEventListener("click",()=>{this.plugin.openPeriodNote("month",r)});let c=r.format("YYYY");s.createSpan({cls:"waypoint-clickable",text:c}).addEventListener("click",()=>{this.plugin.openPeriodNote("year",r)});let D=a.createDiv({cls:"waypoint-calendar-today-group"}),I=D.createEl("button",{cls:"waypoint-calendar-nav-btn"});(0,h.setIcon)(I,"chevron-left"),I.addEventListener("click",()=>this.navigateMonth(-1)),D.createEl("button",{cls:"waypoint-calendar-today-btn",text:"Today"}).addEventListener("click",()=>{this.currentDisplayMonth=(0,h.moment)().month(),this.currentDisplayYear=(0,h.moment)().year(),this.redraw()});let M=D.createEl("button",{cls:"waypoint-calendar-nav-btn"});(0,h.setIcon)(M,"chevron-right"),M.addEventListener("click",()=>this.navigateMonth(1));let E=e.createEl("table"),x=E.createEl("thead").createEl("tr");x.createEl("th",{text:""});let y=["sun","mon","tue","wed","thu","fri","sat"],N=this.plugin.settings.calendar.firstDayOfWeek;for(let v=0;v<7;v++){let S=(N+v)%7;x.createEl("th",{text:y[S]})}let w=E.createEl("tbody"),C=Q(this.currentDisplayYear,this.currentDisplayMonth,this.plugin.settings.calendar.firstDayOfWeek);for(let v of C){let S=w.createEl("tr"),B=S.createEl("td",{cls:"waypoint-weeknum"});B.setText(String(v.weekNumber)),B.addEventListener("click",()=>{let k=v.days[0].date;this.plugin.openPeriodNote("week",k)});for(let k of v.days){let P=S.createEl("td",{cls:"waypoint-day"});if(P.setText(String(k.dayOfMonth)),k.isCurrentMonth||P.addClass("other-month"),k.isToday&&P.addClass("today"),this.plugin.settings.calendar.showNoteIndicators){let O=k.date.format("YYYY-MM-DD");this.plugin.app.vault.getFiles().some(V=>V.extension==="md"&&V.basename===O)&&P.addClass("has-note")}P.addEventListener("click",()=>{this.plugin.openPeriodNote("day",k.date)})}}}navigateMonth(t){let e=(0,h.moment)({year:this.currentDisplayYear,month:this.currentDisplayMonth}).add(t,"month");this.currentDisplayMonth=e.month(),this.currentDisplayYear=e.year(),this.redraw()}renderRecentFiles(){let t=this.contentEl.createDiv({cls:"waypoint-section waypoint-recent-files"});if(t.createDiv({cls:"waypoint-section-header",text:"Recent Files"}),this.plugin.recentFiles.length===0){t.createDiv({cls:"nav-file",text:"No recent files"});return}let e=this.app.workspace.getActiveFile(),n=t.createDiv({cls:"nav-folder mod-root"}),r=n.createDiv({cls:"nav-folder-children"});for(let a of this.plugin.recentFiles){let s=r.createDiv({cls:"tree-item nav-file"}),o=s.createDiv({cls:"tree-item-self is-clickable nav-file-title"});o.createDiv({cls:"tree-item-inner nav-file-title-content"}).setText(a.basename);let l=o.createDiv({cls:"tree-item-spacer"}),p=o.createDiv({cls:"waypoint-recent-remove"});(0,h.setIcon)(p,"x"),p.addEventListener("click",c=>{c.stopPropagation(),this.plugin.recentFiles=this.plugin.recentFiles.filter(m=>m.path!==a.path),this.plugin.saveSettings(),this.redraw()}),(0,h.setTooltip)(s,a.path),e&&a.path===e.path&&o.addClass("is-active"),o.setAttr("draggable","true"),o.addEventListener("dragstart",c=>{let m=this.app.metadataCache.getFirstLinkpathDest(a.path,"");m&&(this.app.dragManager.dragFile(c,m),this.app.dragManager.onDragStart(c,this.app.dragManager.dragFile(c,m)))}),o.addEventListener("mouseover",c=>{this.app.workspace.trigger("hover-link",{event:c,source:b,hoverParent:n,targetEl:s,linktext:a.path})}),o.addEventListener("contextmenu",c=>{let m=new h.Menu;m.addItem(I=>I.setSection("action").setTitle("Open in new tab").setIcon("file-plus").onClick(()=>this.focusFile(a,"tab")));let D=this.app.vault.getAbstractFileByPath(a.path);D&&this.app.workspace.trigger("file-menu",m,D,"link-context-menu"),m.showAtPosition({x:c.clientX,y:c.clientY})}),o.addEventListener("click",c=>{let m=h.Keymap.isModEvent(c);this.focusFile(a,m)}),o.addEventListener("mousedown",c=>{c.button===1&&(c.preventDefault(),this.focusFile(a,"tab"))})}}focusFile(t,e){let n=this.app.vault.getFiles().find(r=>r.path===t.path);n?this.app.workspace.getLeaf(e).openFile(n):(new h.Notice("Cannot find file"),this.plugin.recentFiles=this.plugin.recentFiles.filter(r=>r.path!==t.path),this.plugin.saveSettings(),this.redraw())}renderFavorites(){let t=this.contentEl.createDiv({cls:"waypoint-section waypoint-favorites"}),e=t.createDiv({cls:"waypoint-section-header"});if(e.setText("Waypoint Bookmarks"),e.addEventListener("contextmenu",n=>{let r=new h.Menu;r.addItem(a=>{a.setTitle("Add current file").setIcon("file-plus").onClick(()=>{let s=this.app.workspace.getActiveFile();s&&this.plugin.addBookmark(s.path,s.basename,"file")})}),r.addItem(a=>{a.setTitle("New group").setIcon("folder-plus").onClick(()=>{this.plugin.addBookmark("","New Group","group","folder")})}),r.addItem(a=>{a.setTitle("Add separator").setIcon("minus").onClick(()=>{this.plugin.addBookmark("","","separator")})}),r.addItem(a=>{a.setTitle("Add spacer").setIcon("space").onClick(()=>{this.plugin.addBookmark("","","spacer")})}),r.showAtPosition({x:n.clientX,y:n.clientY})}),this.plugin.waypointData.bookmarks.length===0){t.createDiv({cls:"waypoint-bookmark-item",text:"No bookmarks"});return}this.renderBookmarkList(t,this.plugin.waypointData.bookmarks,0)}renderBookmarkList(t,e,n){for(let r=0;r{this.dragId=a.id,l.dataTransfer.effectAllowed="move",l.dataTransfer.setData("text/plain",a.id),i.addClass("waypoint-bm-dragging")}),i.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(l=>{l.removeClass("waypoint-bm-dragging"),l.removeClass("waypoint-bm-drop-line"),l.removeClass("waypoint-bm-drop-below")})}),i.addEventListener("dragenter",l=>{l.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(i,l)}),i.addEventListener("dragover",l=>{l.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(i,l)}),i.addEventListener("dragleave",()=>{i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")}),i.addEventListener("drop",l=>{var m;l.preventDefault(),this.dragId=null,i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below");let p=(m=l.dataTransfer)==null?void 0:m.getData("text/plain");if(!p||p===a.id)return;let c=i.__dropAbove;this.moveBookmarkToPosition(p,a.id,c)}),i.addEventListener("contextmenu",l=>{l.stopPropagation(),l.preventDefault(),this.showBookmarkContextMenu(l,a)});continue}if(a.type==="spacer"){let i=t.createDiv({cls:"waypoint-bookmark-item waypoint-bookmark-spacer"});i.setAttr("draggable","true"),i.setAttr("data-bm-id",a.id),i.style.paddingLeft=`${8+n*16}px`,i.style.cursor="grab",i.addEventListener("dragstart",l=>{this.dragId=a.id,l.dataTransfer.effectAllowed="move",l.dataTransfer.setData("text/plain",a.id),i.addClass("waypoint-bm-dragging")}),i.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(l=>{l.removeClass("waypoint-bm-dragging"),l.removeClass("waypoint-bm-drop-line"),l.removeClass("waypoint-bm-drop-below")})}),i.addEventListener("dragenter",l=>{l.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(i,l)}),i.addEventListener("dragover",l=>{l.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(i,l)}),i.addEventListener("dragleave",()=>{i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")}),i.addEventListener("drop",l=>{var m;l.preventDefault(),this.dragId=null,i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below");let p=(m=l.dataTransfer)==null?void 0:m.getData("text/plain");if(!p||p===a.id)return;let c=i.__dropAbove;this.moveBookmarkToPosition(p,a.id,c)}),i.addEventListener("contextmenu",l=>{l.stopPropagation(),l.preventDefault(),this.showBookmarkContextMenu(l,a)});continue}let s=a.type==="group",o=t.createDiv({cls:`waypoint-bookmark-item${s?" waypoint-bookmark-group":""}${a.collapsed?" collapsed":""}`});if(o.setAttr("draggable","true"),o.setAttr("data-bm-id",a.id),s||(o.style.paddingLeft=`${8+n*16}px`),o.addEventListener("dragstart",i=>{this.dragId=a.id,i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",a.id),o.addClass("waypoint-bm-dragging")}),o.addEventListener("dragend",()=>{this.dragId=null,t.querySelectorAll(".waypoint-bm-dragging, .waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(i=>{i.removeClass("waypoint-bm-dragging"),i.removeClass("waypoint-bm-drop-line"),i.removeClass("waypoint-bm-drop-below")})}),o.addEventListener("dragenter",i=>{i.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(o,i)}),o.addEventListener("dragover",i=>{i.preventDefault(),!(!this.dragId||this.dragId===a.id)&&this.showDropIndicator(o,i)}),o.addEventListener("dragleave",()=>{o.removeClass("waypoint-bm-drop-line"),o.removeClass("waypoint-bm-drop-below")}),o.addEventListener("drop",i=>{var c;i.preventDefault(),this.dragId=null,o.removeClass("waypoint-bm-drop-line"),o.removeClass("waypoint-bm-drop-below");let l=(c=i.dataTransfer)==null?void 0:c.getData("text/plain");if(!l||l===a.id)return;let p=o.__dropAbove;this.moveBookmarkToPosition(l,a.id,p)}),s){let i=o.createDiv({cls:"waypoint-bm-chevron"});(0,h.setIcon)(i,"chevron-down");let l=o.createDiv({cls:"waypoint-bm-icon"});(0,h.setIcon)(l,a.icon||"folder");let p=o.createDiv({cls:"waypoint-bm-label",text:a.label});o.addEventListener("click",()=>{this.plugin.updateBookmark(a.id,{collapsed:!a.collapsed})});let c=t.createDiv({cls:`waypoint-bookmark-children${a.collapsed?" collapsed":""}`});a.children&&a.children.length>0&&this.renderBookmarkList(c,a.children,n+1)}else{let i=o.createDiv({cls:"waypoint-bm-icon"});(0,h.setIcon)(i,a.icon||"file");let l=o.createDiv({cls:"waypoint-bm-label",text:a.label});(0,h.setTooltip)(o,a.filePath),o.addEventListener("click",()=>{if(a.filePath){let p=this.app.vault.getFileByPath(a.filePath);p?this.app.workspace.getLeaf(!1).openFile(p):(new h.Notice("File not found"),this.plugin.removeBookmark(a.id))}})}o.addEventListener("contextmenu",i=>{i.stopPropagation(),i.preventDefault(),this.showBookmarkContextMenu(i,a)})}}showBookmarkContextMenu(t,e){let n=new h.Menu;e.type==="file"&&(n.addItem(o=>o.setTitle("Open in new tab").setIcon("file-plus").onClick(()=>{let i=this.app.vault.getFileByPath(e.filePath);i&&this.app.workspace.getLeaf("tab").openFile(i)})),n.addSeparator()),e.type!=="separator"&&e.type!=="spacer"&&(n.addItem(o=>o.setTitle("Rename").setIcon("pencil").onClick(()=>this.promptRename(e))),n.addItem(o=>o.setTitle("Change icon").setIcon("image").onClick(()=>this.promptIcon(e))));let r=this.collectGroups(this.plugin.waypointData.bookmarks),a=this.collectDescendantIds(e),s=r.filter(o=>!a.includes(o.id)&&o.id!==e.id);if((s.length>0||e.type==="file"||e.type==="group")&&e.type!=="separator"&&e.type!=="spacer"){if(n.addSeparator(),s.length>0)for(let o of s)n.addItem(i=>i.setTitle(` ${o.label}`).setIcon(o.icon||"folder").onClick(()=>{this.moveBookmarkToGroup(e.id,o.id)}));n.addItem(o=>o.setTitle(" (Root)").setIcon("layout").onClick(()=>{this.moveBookmarkToGroup(e.id,null)}))}e.type==="group"&&(n.addItem(o=>o.setTitle(e.collapsed?"Expand":"Collapse").setIcon(e.collapsed?"chevron-down":"chevron-up").onClick(()=>{this.plugin.updateBookmark(e.id,{collapsed:!e.collapsed})})),n.addSeparator(),n.addItem(o=>o.setTitle("Add bookmark here").setIcon("plus").onClick(()=>{let i=this.app.workspace.getActiveFile();if(!i){new h.Notice("No active file");return}let l={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"file",label:i.basename,filePath:i.path,icon:"file",children:[],collapsed:!1,indent:e.indent+1};e.children.push(l),this.plugin.saveWaypointData(),this.redraw()})),n.addItem(o=>o.setTitle("New sub-group").setIcon("folder-plus").onClick(()=>{let i={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"group",label:"New Group",filePath:"",icon:"folder",children:[],collapsed:!1,indent:e.indent+1};e.children.push(i),this.plugin.saveWaypointData(),this.redraw()}))),n.addSeparator(),n.addItem(o=>o.setTitle("Insert separator above").setIcon("separator-vertical").onClick(()=>this.insertAdjacent(e.id,"separator","above"))),n.addItem(o=>o.setTitle("Insert separator below").setIcon("separator-vertical").onClick(()=>this.insertAdjacent(e.id,"separator","below"))),n.addItem(o=>o.setTitle("Insert spacer above").setIcon("space").onClick(()=>this.insertAdjacent(e.id,"spacer","above"))),n.addItem(o=>o.setTitle("Insert spacer below").setIcon("space").onClick(()=>this.insertAdjacent(e.id,"spacer","below"))),n.addSeparator(),n.addItem(o=>o.setTitle("Remove").setIcon("trash").onClick(()=>{this.plugin.removeBookmark(e.id)})),n.showAtPosition({x:t.clientX,y:t.clientY})}insertAdjacent(t,e,n){let r={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e,label:"",filePath:"",icon:"",children:[],collapsed:!1,indent:0},a=s=>{let o=s.findIndex(i=>i.id===t);if(o>=0){let i=n==="above"?o:o+1;return s.splice(i,0,r),!0}for(let i of s)if(i.children&&a(i.children))return!0;return!1};a(this.plugin.waypointData.bookmarks),this.plugin.saveWaypointData(),this.redraw()}collectGroups(t){let e=[];for(let n of t)n.type==="group"&&(e.push(n),e.push(...this.collectGroups(n.children)));return e}collectDescendantIds(t){let e=[];for(let n of t.children)e.push(n.id),e.push(...this.collectDescendantIds(n));return e}showDropIndicator(t,e){let n=t.parentElement;n&&n.querySelectorAll(".waypoint-bm-drop-line, .waypoint-bm-drop-below").forEach(o=>{o.removeClass("waypoint-bm-drop-line"),o.removeClass("waypoint-bm-drop-below")});let r=t.getBoundingClientRect(),a=r.top+r.height/2,s=e.clientY{let s=a.findIndex(o=>o.id===t);if(s>=0){let[o]=a.splice(s,1);return o}for(let o of a){let i=n(o.children);if(i)return i}return null},r=n(this.plugin.waypointData.bookmarks);if(r){if(e){let a=o=>{for(let i of o){if(i.id===e)return i;let l=a(i.children);if(l)return l}return null},s=a(this.plugin.waypointData.bookmarks);s&&(r.indent=s.indent+1,s.children.push(r))}else r.indent=0,this.plugin.waypointData.bookmarks.push(r);this.plugin.saveWaypointData(),this.redraw()}}moveBookmarkToPosition(t,e,n){let r=i=>{let l=i.findIndex(p=>p.id===t);if(l>=0){let[p]=i.splice(l,1);return{item:p,parent:i}}for(let p of i)if(p.children){let c=r(p.children);if(c.item)return c}return{item:null,parent:[]}},{item:a}=r(this.plugin.waypointData.bookmarks);if(!a)return;let s=i=>{let l=i.findIndex(p=>p.id===e);if(l>=0)return{parent:i,idx:l};for(let p of i)if(p.children){let c=s(p.children);if(c)return c}return null},o=s(this.plugin.waypointData.bookmarks);if(!o)a.indent=0,this.plugin.waypointData.bookmarks.push(a);else{let i=n?o.idx:o.idx+1;o.parent.splice(i,0,a)}this.plugin.saveWaypointData(),this.redraw()}promptRename(t){new q(this.app,t.label,e=>{e&&e.trim()&&this.plugin.updateBookmark(t.id,{label:e.trim()})}).open()}promptIcon(t){new G(this.app,t.icon,e=>{e&&this.plugin.updateBookmark(t.id,{icon:e})}).open()}},q=class extends h.Modal{constructor(d,t,e){super(d),this.currentValue=t,this.onSubmit=e}onOpen(){this.titleEl.setText("Rename bookmark");let d=this.contentEl.createEl("input",{type:"text",value:this.currentValue});d.style.width="100%",d.style.marginBottom="12px",d.focus(),d.select();let t=this.contentEl.createDiv({cls:"modal-button-container"}),e=t.createEl("button",{text:"Cancel",cls:"mod-cta"});e.style.marginRight="8px",e.addEventListener("click",()=>this.close()),t.createEl("button",{text:"Save",cls:"mod-cta"}).addEventListener("click",()=>{this.onSubmit(d.value),this.close()}),d.addEventListener("keydown",r=>{r.key==="Enter"&&(this.onSubmit(d.value),this.close())})}onClose(){this.contentEl.empty()}},G=class extends h.Modal{constructor(t,e,n){super(t);this.allIcons=[];this.loaded=!1;this.selected=e,this.onSubmit=n}async onOpen(){let t=this.contentEl;t.style.display="flex",t.style.flexDirection="column",t.style.gap="10px",this.titleEl.setText("Change icon");let e=t.createDiv({cls:"waypoint-icon-preview"});e.style.display="flex",e.style.alignItems="center",e.style.gap="10px",e.style.padding="12px 16px",e.style.borderRadius="8px",e.style.background="var(--background-secondary)",e.style.minHeight="48px";let n=e.createSpan();n.style.display="flex",this.selected&&(0,h.setIcon)(n,this.selected);let r=e.createSpan();r.style.fontWeight="var(--font-medium)",r.style.fontSize="var(--font-ui-medium)",r.setText(this.selected||"No icon");let a=t.createEl("input",{type:"text",placeholder:"Type to search (e.g. arrow, chart, home)..."});Object.assign(a.style,{width:"100%",boxSizing:"border-box",padding:"8px 10px",borderRadius:"6px",border:"1px solid var(--background-modifier-border)",background:"var(--background-primary)",color:"var(--text-normal)",fontSize:"var(--font-ui-medium)"}),a.focus();let s=t.createDiv({cls:"waypoint-icon-grid"});s.style.display="grid",s.style.gridTemplateColumns="repeat(auto-fill, minmax(52px, 1fr))",s.style.gap="4px",s.style.maxHeight="320px",s.style.overflowY="auto",s.style.padding="2px 0";let o=t.createDiv();o.style.display="flex",o.style.justifyContent="space-between",o.style.alignItems="center",o.style.fontSize="var(--font-ui-smaller)",o.style.color="var(--text-muted)",o.style.padding="0 4px";let i=o.createSpan();i.setText("Loading\u2026");let l=o.createSpan();l.style.cursor="var(--cursor)",l.style.color="var(--text-accent)",l.setText("No icon"),l.addEventListener("click",()=>{this.onSubmit(""),this.close()}),this.loadIcons().then(()=>{this.loaded=!0,i.setText(this.allIcons.length+" icons"),c(a.value)});let p=null,c=F=>{if(s.empty(),!this.loaded){s.createDiv({text:"Loading\u2026"});return}let M=F.toLowerCase().trim(),E=M?this.allIcons.filter(function(w){return w.includes(M)}).slice(0,80):this.allIcons.slice(0,80);if(E.length===0){let w=s.createDiv();w.style.gridColumn="1 / -1",w.style.textAlign="center",w.style.color="var(--text-muted)",w.style.padding="20px",w.setText('No icons match "'+F+'"');return}for(var A=0;Anew Y(a,this)),this.addSettingTab(new W(this.app,this,this.settings,()=>this.redrawAll())),this.addCommand({id:"waypoint-open-view",name:"Open Waypoint sidebar",callback:async()=>{let a=this.app.workspace.getLeavesOfType(b);if(a.length>0)await this.app.workspace.revealLeaf(a[0]);else{let s=this.app.workspace.getLeftLeaf(!1);s&&(await s.setViewState({type:b}),await this.app.workspace.revealLeaf(s))}}}),this.addCommand({id:"waypoint-add-bookmark",name:"Add current file as Waypoint bookmark",callback:async()=>{let a=this.app.workspace.getActiveFile();if(!a){new u.Notice("No active file");return}this.addBookmark(a.path,a.basename,"file"),new u.Notice(`Bookmarked: ${a.basename}`)}}),this.addCommand({id:"waypoint-go-to-daily",name:"Go to daily note",hotkeys:[{modifiers:["Mod","Shift","Alt"],key:"d"}],callback:async()=>{await this.openPeriodNote("day",(0,u.moment)())}}),this.addCommand({id:"waypoint-go-to-weekly",name:"Go to weekly note",hotkeys:[{modifiers:["Mod","Shift","Alt"],key:"w"}],callback:async()=>{await this.openPeriodNote("week",(0,u.moment)())}}),this.addCommand({id:"waypoint-go-to-monthly",name:"Go to monthly note",hotkeys:[{modifiers:["Mod","Shift","Alt"],key:"m"}],callback:async()=>{await this.openPeriodNote("month",(0,u.moment)())}}),this.addCommand({id:"waypoint-go-to-quarterly",name:"Go to quarterly note",hotkeys:[{modifiers:["Mod","Shift","Alt"],key:"q"}],callback:async()=>{await this.openPeriodNote("quarter",(0,u.moment)())}}),this.addCommand({id:"waypoint-go-to-yearly",name:"Go to yearly note",hotkeys:[{modifiers:["Mod","Shift","Alt"],key:"y"}],callback:async()=>{await this.openPeriodNote("year",(0,u.moment)())}});let t=["next","prev"],e=["daily","weekly","monthly","quarterly","yearly"],n={next:"Next",prev:"Previous"};for(let a of e)for(let s of t){let o=`waypoint-go-to-${s}-${a}`,i=`${n[s]} ${a} note`;this.addCommand({id:o,name:i,callback:async()=>{await this.navigatePeriodNote(s)}})}this.registerEvent(this.app.workspace.on("file-open",a=>{a&&this.onFileOpen(a)})),this.registerEvent(this.app.vault.on("create",()=>this.onVaultChange())),this.registerEvent(this.app.vault.on("delete",()=>this.onVaultChange())),this.registerEvent(this.app.vault.on("rename",(a,s)=>this.onRename(a,s))),this.app.workspace.onLayoutReady(()=>{if(this.app.workspace.getLeavesOfType(b).length===0){let s=this.app.workspace.getLeftLeaf(!1);s&&s.setViewState({type:b})}});let r=new Date().toDateString();this.registerInterval(window.setInterval(()=>{let a=new Date().toDateString();a!==r&&(r=a,this.redrawAll())},6e5))}async onunload(){this.app.workspace.detachLeavesOfType(b)}async loadSettings(){let t=await this.loadData(),e=(t==null?void 0:t.settings)||{};this.settings=Object.assign({},j,e)}async saveSettings(){let t=await this.loadData()||{};t.settings=this.settings,await this.saveData(t)}async loadWaypointData(){let t=await this.loadData(),e=(t==null?void 0:t.waypointData)||{};this.waypointData=Object.assign({},Z,e)}async saveWaypointData(){let t=await this.loadData()||{};t.waypointData=this.waypointData,await this.saveData(t)}onFileOpen(t){this.settings.recentFiles.updateOn!=="file-edit"&&this.addToRecentFiles(t)}addToRecentFiles(t){this.recentFiles=this.recentFiles.filter(e=>e.path!==t.path),this.recentFiles.unshift({path:t.path,basename:t.basename}),this.recentFiles.length>this.settings.recentFiles.maxItems&&(this.recentFiles=this.recentFiles.slice(0,this.settings.recentFiles.maxItems)),this.broadcastRedraw()}onRename(t,e){let n=this.recentFiles.find(r=>r.path===e);n&&(n.path=t.path,n.basename=t.basename||t.name.replace(/\.[^/.]+$/,""),this.broadcastRedraw()),this.updateBookmarkPath(e,t.path)}onVaultChange(){this.broadcastRedraw()}addBookmark(t,e,n="file",r="file"){let s={id:`bm-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:n,label:e,filePath:n==="file"?t:"",icon:r,children:[],collapsed:!1,indent:0};return this.waypointData.bookmarks.push(s),this.saveWaypointData(),this.broadcastRedraw(),s}removeBookmark(t){let e=n=>{let r=n.findIndex(a=>a.id===t);if(r>=0)return n.splice(r,1),!0;for(let a of n)if(a.children&&e(a.children))return!0;return!1};e(this.waypointData.bookmarks),this.saveWaypointData(),this.broadcastRedraw()}updateBookmark(t,e){let n=a=>{for(let s of a){if(s.id===t)return s;if(s.children){let o=n(s.children);if(o)return o}}return null},r=n(this.waypointData.bookmarks);r&&(Object.assign(r,e),this.saveWaypointData(),this.broadcastRedraw())}updateBookmarkPath(t,e){let n=r=>{for(let a of r)a.filePath===t&&(a.filePath=e),a.children&&n(a.children)};n(this.waypointData.bookmarks)}async openPeriodNote(t,e){let r={day:{settings:this.settings.daily,label:"Daily"},week:{settings:this.settings.weekly,label:"Weekly"},month:{settings:this.settings.monthly,label:"Monthly"},quarter:{settings:this.settings.quarterly,label:"Quarterly"},year:{settings:this.settings.yearly,label:"Yearly"}}[t];if(!r)return;let{settings:a}=r,s=e.format(a.nameFormat)+".md",o=a.folder?`${a.folder}/${s}`:s,i=this.app.vault.getFileByPath(o);if(!i){try{let l=a.templateFile+".md",p=this.app.vault.getFileByPath(l);if(p){let c=await this.app.vault.read(p);i=await this.app.vault.create(o,c)}else{let c=`--- +type: ${a.typeProperty} date: ${e.format("YYYY-MM-DD")} --- -`;i=await this.app.vault.create(n,c)}}catch(r){new b.Notice(`Failed to create ${s.label.toLowerCase()} note: ${r.message}`);return}new b.Notice(`Created ${s.label.toLowerCase()} note: ${l}`)}i&&await this.app.workspace.getLeaf(!1).openFile(i)}redrawAll(){this.broadcastRedraw()}broadcastRedraw(){let t=this.app.workspace.getLeavesOfType(w);for(let e of t)e.view instanceof A&&e.view.redraw()}async getNotesForDate(t){return this.app.vault.getFiles().filter(e=>e.extension==="md"&&e.basename===t)}async hasNoteForDate(t){return this.app.vault.getFiles().some(e=>e.extension==="md"&&e.basename===t)}}; +`;i=await this.app.vault.create(o,c)}}catch(l){new u.Notice(`Failed to create ${r.label.toLowerCase()} note: ${l.message}`);return}new u.Notice(`Created ${r.label.toLowerCase()} note: ${s}`)}i&&await this.app.workspace.getLeaf(!1).openFile(i)}detectPeriodType(t){return/^\d{4}-\d{2}-\d{2}$/.test(t)?{period:"day",date:(0,u.moment)(t,"YYYY-MM-DD")}:/^\d{4}-W\d{2}$/.test(t)?{period:"week",date:(0,u.moment)(t,"GGGG-[W]WW")}:/^\d{4}-\d{2}$/.test(t)?{period:"month",date:(0,u.moment)(t,"YYYY-MM")}:/^\d{4}-Q[1-4]$/.test(t)?{period:"quarter",date:(0,u.moment)(t,"YYYY-[Q]Q")}:/^\d{4}$/.test(t)?{period:"year",date:(0,u.moment)(t,"YYYY")}:null}async navigatePeriodNote(t){let e=this.app.workspace.getActiveFile();if(!e){new u.Notice("No active file");return}let n=this.detectPeriodType(e.basename);if(!n){new u.Notice("Current file is not a periodic note (daily/weekly/monthly/quarterly/yearly)");return}let{period:r,date:a}=n;if(!a.isValid()){new u.Notice(`Could not parse date from filename: ${e.basename}`);return}let s=t==="next"?1:-1,o=r==="quarter"?a.clone().add(s*3,"months"):a.clone().add(s,`${r}s`);await this.openPeriodNote(r,o)}redrawAll(){this.broadcastRedraw()}broadcastRedraw(){let t=this.app.workspace.getLeavesOfType(b);for(let e of t)e.view instanceof Y&&e.view.redraw()}async getNotesForDate(t){return this.app.vault.getFiles().filter(e=>e.extension==="md"&&e.basename===t)}async hasNoteForDate(t){return this.app.vault.getFiles().some(e=>e.extension==="md"&&e.basename===t)}}; diff --git a/manifest.json b/manifest.json index 26891ec..f1dd908 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "waypoint", "name": "Waypoint", - "version": "1.0.0", + "version": "1.1.0", "minAppVersion": "0.16.3", "description": "Calendar, recent files, and custom bookmarks sidebar.", "author": "Olivier", diff --git a/package.json b/package.json index 2c66075..a3961ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waypoint", - "version": "1.0.0", + "version": "1.1.0", "description": "Calendar, recent files, and custom bookmarks sidebar.", "main": "main.js", "scripts": { diff --git a/src/main.ts b/src/main.ts index 0c8caa2..83228cd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -78,13 +78,70 @@ export default class WaypointPlugin extends Plugin { }); this.addCommand({ - id: 'waypoint-go-to-today', - name: 'Go to today\'s daily note', + id: 'waypoint-go-to-daily', + name: 'Go to daily note', + hotkeys: [{ modifiers: ['Mod', 'Shift', 'Alt'], key: 'd' }], callback: async () => { await this.openPeriodNote('day', moment()); }, }); + this.addCommand({ + id: 'waypoint-go-to-weekly', + name: 'Go to weekly note', + hotkeys: [{ modifiers: ['Mod', 'Shift', 'Alt'], key: 'w' }], + callback: async () => { + await this.openPeriodNote('week', moment()); + }, + }); + + this.addCommand({ + id: 'waypoint-go-to-monthly', + name: 'Go to monthly note', + hotkeys: [{ modifiers: ['Mod', 'Shift', 'Alt'], key: 'm' }], + callback: async () => { + await this.openPeriodNote('month', moment()); + }, + }); + + this.addCommand({ + id: 'waypoint-go-to-quarterly', + name: 'Go to quarterly note', + hotkeys: [{ modifiers: ['Mod', 'Shift', 'Alt'], key: 'q' }], + callback: async () => { + await this.openPeriodNote('quarter', moment()); + }, + }); + + this.addCommand({ + id: 'waypoint-go-to-yearly', + name: 'Go to yearly note', + hotkeys: [{ modifiers: ['Mod', 'Shift', 'Alt'], key: 'y' }], + callback: async () => { + await this.openPeriodNote('year', moment()); + }, + }); + + // ── Period navigation commands (no hotkeys) ── + + const directions = ['next', 'prev'] as const; + const periodLabels = ['daily', 'weekly', 'monthly', 'quarterly', 'yearly'] as const; + const directionLabels: Record = { next: 'Next', prev: 'Previous' }; + + for (const period of periodLabels) { + for (const dir of directions) { + const id = `waypoint-go-to-${dir}-${period}`; + const name = `${directionLabels[dir]} ${period} note`; + this.addCommand({ + id, + name, + callback: async () => { + await this.navigatePeriodNote(dir); + }, + }); + } + } + // ── Events ── this.registerEvent( @@ -319,6 +376,69 @@ export default class WaypointPlugin extends Plugin { } } + // ── Period note navigation (next/prev from current file) ── + + /** + * Detect the period type from a filename's basename. + * Returns the period key and the parsed moment, or null if not a period note. + */ + private detectPeriodType(basename: string): { period: 'day' | 'week' | 'month' | 'quarter' | 'year'; date: moment.Moment } | null { + // YYYY-MM-DD → daily + if (/^\d{4}-\d{2}-\d{2}$/.test(basename)) { + return { period: 'day', date: moment(basename, 'YYYY-MM-DD') }; + } + // GGGG-WWW → weekly (e.g. 2026-W24) + if (/^\d{4}-W\d{2}$/.test(basename)) { + return { period: 'week', date: moment(basename, 'GGGG-[W]WW') }; + } + // YYYY-MM → monthly + if (/^\d{4}-\d{2}$/.test(basename)) { + return { period: 'month', date: moment(basename, 'YYYY-MM') }; + } + // YYYY-Q# → quarterly + if (/^\d{4}-Q[1-4]$/.test(basename)) { + return { period: 'quarter', date: moment(basename, 'YYYY-[Q]Q') }; + } + // YYYY → yearly + if (/^\d{4}$/.test(basename)) { + return { period: 'year', date: moment(basename, 'YYYY') }; + } + return null; + } + + /** + * Navigate to the next or previous period note based on the currently active file. + */ + async navigatePeriodNote(direction: 'next' | 'prev'): Promise { + const file = this.app.workspace.getActiveFile(); + if (!file) { + new Notice('No active file'); + return; + } + + const detected = this.detectPeriodType(file.basename); + if (!detected) { + new Notice('Current file is not a periodic note (daily/weekly/monthly/quarterly/yearly)'); + return; + } + + const { period, date } = detected; + + if (!date.isValid()) { + new Notice(`Could not parse date from filename: ${file.basename}`); + return; + } + + const amount = direction === 'next' ? 1 : -1; + + // Map period to moment duration unit + const newDate = period === 'quarter' + ? date.clone().add(amount * 3, 'months') + : date.clone().add(amount, `${period}s` as moment.unitOfTime.DurationConstructor); + + await this.openPeriodNote(period, newDate); + } + // ── Redraw ── private redrawAll(): void {