From 338cc101f127e4841689c1f81227ee033e57ad28 Mon Sep 17 00:00:00 2001 From: shu Date: Sun, 26 Jul 2026 22:42:45 +0800 Subject: Add task board and organize local plugins --- tiddlers/journal-calendar-widget.tid | 333 ----------------------------------- 1 file changed, 333 deletions(-) delete mode 100644 tiddlers/journal-calendar-widget.tid (limited to 'tiddlers/journal-calendar-widget.tid') diff --git a/tiddlers/journal-calendar-widget.tid b/tiddlers/journal-calendar-widget.tid deleted file mode 100644 index cd54724..0000000 --- a/tiddlers/journal-calendar-widget.tid +++ /dev/null @@ -1,333 +0,0 @@ -title: $:/plugins/local/journal-calendar/widget.js -type: application/javascript -module-type: widget - -/*\ -title: $:/plugins/local/journal-calendar/widget.js -type: application/javascript -module-type: widget - -Renders journal tiddlers as monthly calendars. -\*/ -(function() { -"use strict"; - -var Widget = require("$:/core/modules/widgets/widget.js").widget, - VIEW_STATE_TITLE = "$:/state/journal-calendar/view", - MONTH_STATE_TITLE = "$:/state/journal-calendar/month"; - -var JournalCalendarWidget = function(parseTreeNode,options) { - this.initialise(parseTreeNode,options); -}; - -JournalCalendarWidget.prototype = new Widget(); -JournalCalendarWidget.prototype.constructor = JournalCalendarWidget; - -function pad(value) { - return value < 10 ? "0" + value : "" + value; -} - -function dateKey(year,month,day) { - return year + "-" + pad(month) + "-" + pad(day); -} - -function monthKey(year,month) { - return year + "-" + pad(month); -} - -function isValidMonth(value) { - var match = /^(\d{4})-(\d{2})$/.exec(value || ""); - return !!match && Number(match[2]) >= 1 && Number(match[2]) <= 12; -} - -function parseMonth(value) { - var parts = value.split("-"); - return { - year: Number(parts[0]), - month: Number(parts[1]) - }; -} - -JournalCalendarWidget.prototype.render = function(parent,nextSibling) { - this.parentDomNode = parent; - this.computeAttributes(); - this.execute(); - - var container = this.document.createElement("div"); - container.className = "tc-journal-calendar"; - parent.insertBefore(container,nextSibling); - this.domNodes.push(container); - this.containerNode = container; - - this.renderCalendar(); -}; - -JournalCalendarWidget.prototype.execute = function() { - this.tag = this.getAttribute("tag","日志"); - this.view = this.getAttribute("view","switchable"); - this.month = this.getAttribute("month",""); -}; - -JournalCalendarWidget.prototype.getJournalDate = function(tiddler) { - var titleMatch = /^(\d{4})年(\d{2})月(\d{2})日$/.exec(tiddler.fields.title), - date; - - if(titleMatch) { - date = new Date(Number(titleMatch[1]),Number(titleMatch[2]) - 1,Number(titleMatch[3])); - if(date.getFullYear() === Number(titleMatch[1]) && date.getMonth() === Number(titleMatch[2]) - 1 && date.getDate() === Number(titleMatch[3])) { - return date; - } - } - return null; -}; - -JournalCalendarWidget.prototype.getJournalData = function() { - var titles = this.wiki.getTiddlersWithTag(this.tag), - byDate = Object.create(null), - months = Object.create(null), - self = this; - - titles.forEach(function(title) { - var tiddler = self.wiki.getTiddler(title); - if(!tiddler || tiddler.fields["draft.of"]) { - return; - } - - var date = self.getJournalDate(tiddler); - if(!date) { - return; - } - - var day = dateKey(date.getFullYear(),date.getMonth() + 1,date.getDate()), - month = day.substring(0,7); - byDate[day] = { - title: title, - tags: (tiddler.fields.tags || []).filter(function(tag) { - return tag !== self.tag; - }) - }; - months[month] = true; - }); - - return { - byDate: byDate, - months: Object.keys(months).sort().reverse() - }; -}; - -JournalCalendarWidget.prototype.getCurrentMonth = function() { - if(isValidMonth(this.month)) { - return this.month; - } - - var stateMonth = this.wiki.getTiddlerText(MONTH_STATE_TITLE,""); - if(isValidMonth(stateMonth)) { - return stateMonth; - } - - var now = new Date(); - return monthKey(now.getFullYear(),now.getMonth() + 1); -}; - -JournalCalendarWidget.prototype.getCurrentView = function() { - if(this.view === "month" || this.view === "all") { - return this.view; - } - return this.wiki.getTiddlerText(VIEW_STATE_TITLE,"month") === "all" ? "all" : "month"; -}; - -JournalCalendarWidget.prototype.setState = function(title,value) { - this.wiki.addTiddler({ - title: title, - text: value - }); -}; - -JournalCalendarWidget.prototype.createButton = function(label,className,handler) { - var button = this.document.createElement("button"); - button.setAttribute("type","button"); - button.className = className; - button.textContent = label; - button.addEventListener("click",handler); - return button; -}; - -JournalCalendarWidget.prototype.renderViewSwitcher = function(currentView) { - if(this.view !== "switchable") { - return; - } - - var self = this, - controls = this.document.createElement("div"); - controls.className = "tc-journal-calendar-view-switcher"; - - controls.appendChild(this.createButton("单月视图","tc-btn-invisible tc-journal-calendar-switch" + (currentView === "month" ? " tc-selected" : ""),function() { - self.setState(VIEW_STATE_TITLE,"month"); - })); - controls.appendChild(this.createButton("全部月份","tc-btn-invisible tc-journal-calendar-switch" + (currentView === "all" ? " tc-selected" : ""),function() { - self.setState(VIEW_STATE_TITLE,"all"); - })); - this.containerNode.appendChild(controls); -}; - -JournalCalendarWidget.prototype.renderMonthControls = function(selectedMonth) { - if(isValidMonth(this.month)) { - return; - } - - var self = this, - selected = parseMonth(selectedMonth), - controls = this.document.createElement("div"); - controls.className = "tc-journal-calendar-month-controls"; - - function setOffset(offset) { - var date = new Date(selected.year,selected.month - 1 + offset,1); - self.setState(MONTH_STATE_TITLE,monthKey(date.getFullYear(),date.getMonth() + 1)); - } - - controls.appendChild(this.createButton("上个月","tc-btn-invisible tc-journal-calendar-nav",function() { - setOffset(-1); - })); - controls.appendChild(this.createButton("本月","tc-btn-invisible tc-journal-calendar-nav",function() { - var now = new Date(); - self.setState(MONTH_STATE_TITLE,monthKey(now.getFullYear(),now.getMonth() + 1)); - })); - controls.appendChild(this.createButton("下个月","tc-btn-invisible tc-journal-calendar-nav",function() { - setOffset(1); - })); - this.containerNode.appendChild(controls); -}; - -JournalCalendarWidget.prototype.navigateTo = function(title,node,event) { - var bounds = node.getBoundingClientRect(); - this.dispatchEvent({ - type: "tm-navigate", - navigateTo: title, - navigateFromTitle: this.getVariable("storyTiddler"), - navigateFromNode: this, - navigateFromClientRect: { - top: bounds.top, - left: bounds.left, - width: bounds.width, - right: bounds.right, - bottom: bounds.bottom, - height: bounds.height - }, - navigateSuppressNavigation: event.metaKey || event.ctrlKey || event.button === 1 - }); -}; - -JournalCalendarWidget.prototype.renderMonth = function(value,byDate) { - var self = this, - selected = parseMonth(value), - section = this.document.createElement("section"), - heading = this.document.createElement("h2"), - viewport = this.document.createElement("div"), - grid = this.document.createElement("div"), - weekdays = ["一","二","三","四","五","六","日"], - firstWeekday = (new Date(selected.year,selected.month - 1,1).getDay() + 6) % 7, - daysInMonth = new Date(selected.year,selected.month,0).getDate(), - today = new Date(), - index; - - section.className = "tc-journal-calendar-month"; - heading.className = "tc-journal-calendar-month-title"; - heading.textContent = selected.year + "年" + selected.month + "月"; - section.appendChild(heading); - viewport.className = "tc-journal-calendar-viewport"; - grid.className = "tc-journal-calendar-grid"; - - weekdays.forEach(function(weekday) { - var weekdayNode = self.document.createElement("div"); - weekdayNode.className = "tc-journal-calendar-weekday"; - weekdayNode.textContent = weekday; - grid.appendChild(weekdayNode); - }); - - for(index = 0; index < firstWeekday; index++) { - var blank = this.document.createElement("div"); - blank.className = "tc-journal-calendar-day tc-journal-calendar-day-empty"; - grid.appendChild(blank); - } - - for(var day = 1; day <= daysInMonth; day++) { - var key = dateKey(selected.year,selected.month,day), - journal = byDate[key], - dayNode = this.document.createElement("div"), - numberNode; - - dayNode.className = "tc-journal-calendar-day" + (journal ? " tc-journal-calendar-day-has-journal" : ""); - if(selected.year === today.getFullYear() && selected.month === today.getMonth() + 1 && day === today.getDate()) { - dayNode.className += " tc-journal-calendar-day-today"; - } - - if(journal) { - numberNode = this.createButton(day,"tc-btn-invisible tc-journal-calendar-day-number tc-journal-calendar-day-link",function(title) { - return function(event) { - self.navigateTo(title,event.currentTarget,event); - }; - }(journal.title)); - numberNode.title = "打开日志:" + journal.title; - numberNode.setAttribute("aria-label","打开日志:" + journal.title); - } else { - numberNode = this.document.createElement("div"); - numberNode.className = "tc-journal-calendar-day-number"; - numberNode.textContent = day; - } - dayNode.appendChild(numberNode); - - if(journal) { - journal.tags.forEach(function(tag) { - var tagButton = self.createButton(tag,"tc-btn-invisible tc-tag-label tc-journal-calendar-tag",function(event) { - self.navigateTo(tag,event.currentTarget,event); - }); - tagButton.title = "打开标签:" + tag; - tagButton.setAttribute("aria-label","打开标签:" + tag); - dayNode.appendChild(tagButton); - }); - } - grid.appendChild(dayNode); - } - - viewport.appendChild(grid); - section.appendChild(viewport); - this.containerNode.appendChild(section); -}; - -JournalCalendarWidget.prototype.renderCalendar = function() { - var data = this.getJournalData(), - currentView = this.getCurrentView(); - - this.renderViewSwitcher(currentView); - - if(currentView === "all") { - if(!data.months.length) { - var empty = this.document.createElement("div"); - empty.className = "tc-journal-calendar-empty"; - empty.textContent = "目前没有日志。"; - this.containerNode.appendChild(empty); - return; - } - data.months.forEach(function(month) { - this.renderMonth(month,data.byDate); - },this); - return; - } - - var selectedMonth = this.getCurrentMonth(); - this.renderMonthControls(selectedMonth); - this.renderMonth(selectedMonth,data.byDate); -}; - -JournalCalendarWidget.prototype.refresh = function(changedTiddlers) { - var changedAttributes = this.computeAttributes(); - if(Object.keys(changedAttributes).length || Object.keys(changedTiddlers).length) { - this.refreshSelf(); - return true; - } - return false; -}; - -exports["journal-calendar"] = JournalCalendarWidget; - -})(); -- cgit v1.2.3