mirror of
https://github.com/playmean/obsidian-event-highlight-plugin.git
synced 2026-07-22 05:44:13 +00:00
feat: added optional text description for event
This commit is contained in:
parent
e6f00b51ae
commit
bb9ff01bba
2 changed files with 103 additions and 19 deletions
78
main.ts
78
main.ts
|
|
@ -1,4 +1,4 @@
|
||||||
import { Plugin, moment, setIcon, setTooltip } from 'obsidian';
|
import { MarkdownRenderer, Plugin, moment, setIcon, setTooltip } from 'obsidian';
|
||||||
import { SettingsTab } from 'settings-tab';
|
import { SettingsTab } from 'settings-tab';
|
||||||
|
|
||||||
interface PluginSettings {
|
interface PluginSettings {
|
||||||
|
|
@ -40,27 +40,33 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
|
|
||||||
this.addSettingTab(new SettingsTab(this.app, this));
|
this.addSettingTab(new SettingsTab(this.app, this));
|
||||||
|
|
||||||
this.registerMarkdownCodeBlockProcessor('event-highlight', (source, el, ctx) => {
|
this.registerMarkdownCodeBlockProcessor(
|
||||||
this.renderElement(el, source.trim());
|
'event-highlight',
|
||||||
|
async (source, el, ctx) => {
|
||||||
|
await this.renderElement(el, source.trim(), undefined, ctx.sourcePath);
|
||||||
|
|
||||||
el.addEventListener('click', () => {
|
el.addEventListener('click', async () => {
|
||||||
const { swapped } = this.loadState(el);
|
const { swapped } = this.loadState(el);
|
||||||
|
|
||||||
this.renderElement(el, source.trim(), {
|
await this.renderElement(
|
||||||
swapped: !swapped,
|
el,
|
||||||
|
source.trim(),
|
||||||
|
{ swapped: !swapped },
|
||||||
|
ctx.sourcePath,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
});
|
);
|
||||||
|
|
||||||
this.registerEvent(
|
this.registerEvent(
|
||||||
this.app.workspace.on('active-leaf-change', () => {
|
this.app.workspace.on('active-leaf-change', () => {
|
||||||
this.updateAllPage();
|
void this.updateAllPage();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.registerInterval(
|
this.registerInterval(
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.updateAllPage();
|
void this.updateAllPage();
|
||||||
}, 10_000),
|
}, 10_000),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -115,10 +121,17 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
return JSON.stringify(oldState) === JSON.stringify(newState);
|
return JSON.stringify(oldState) === JSON.stringify(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderElement(el: Element, source: string, overrideState?: Partial<State>) {
|
private async renderElement(
|
||||||
const parsedDate = moment(source, ['YYYY-MM-DD', 'DD.MM.YYYY'], true);
|
el: Element,
|
||||||
|
source: string,
|
||||||
|
overrideState?: Partial<State>,
|
||||||
|
sourcePath = '',
|
||||||
|
) {
|
||||||
|
const { dateSource, extraText } = this.parseSource(source);
|
||||||
|
|
||||||
|
const parsedDate = moment(dateSource, ['YYYY-MM-DD', 'DD.MM.YYYY'], true);
|
||||||
const parsedDateTime = moment(
|
const parsedDateTime = moment(
|
||||||
source,
|
dateSource,
|
||||||
['YYYY-MM-DD HH:mm', 'DD.MM.YYYY HH:mm'],
|
['YYYY-MM-DD HH:mm', 'DD.MM.YYYY HH:mm'],
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
@ -214,14 +227,27 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
|
|
||||||
el.empty();
|
el.empty();
|
||||||
|
|
||||||
const dateSpan = el.createEl('div', { cls: 'event-highlight-badge' });
|
const container = el.createEl('div', { cls: 'event-highlight-container' });
|
||||||
|
|
||||||
|
if (extraText) {
|
||||||
|
const textEl = container.createEl('div', { cls: 'event-highlight-text' });
|
||||||
|
|
||||||
|
await MarkdownRenderer.render(this.app, extraText, textEl, sourcePath, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateSpan = container.createEl('div', { cls: 'event-highlight-badge' });
|
||||||
const iconSpan = dateSpan.createEl('div', { cls: 'icon' });
|
const iconSpan = dateSpan.createEl('div', { cls: 'icon' });
|
||||||
|
|
||||||
|
if (extraText) {
|
||||||
|
dateSpan.classList.add('with-text');
|
||||||
|
}
|
||||||
|
|
||||||
dateSpan.createEl('div', { text });
|
dateSpan.createEl('div', { text });
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case isError:
|
case isError:
|
||||||
dateSpan.classList.add('error');
|
dateSpan.classList.add('error');
|
||||||
|
container.classList.add('error');
|
||||||
|
|
||||||
setIcon(iconSpan, 'ban');
|
setIcon(iconSpan, 'ban');
|
||||||
setTooltip(dateSpan, 'Invalid date');
|
setTooltip(dateSpan, 'Invalid date');
|
||||||
|
|
@ -229,6 +255,7 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
break;
|
break;
|
||||||
case isAfter:
|
case isAfter:
|
||||||
dateSpan.classList.add('after');
|
dateSpan.classList.add('after');
|
||||||
|
container.classList.add('after');
|
||||||
|
|
||||||
setIcon(iconSpan, 'calendar-check-2');
|
setIcon(iconSpan, 'calendar-check-2');
|
||||||
setTooltip(dateSpan, 'Past event');
|
setTooltip(dateSpan, 'Past event');
|
||||||
|
|
@ -236,6 +263,7 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
break;
|
break;
|
||||||
case isBefore:
|
case isBefore:
|
||||||
dateSpan.classList.add('before');
|
dateSpan.classList.add('before');
|
||||||
|
container.classList.add('before');
|
||||||
|
|
||||||
setIcon(iconSpan, 'calendar');
|
setIcon(iconSpan, 'calendar');
|
||||||
setTooltip(dateSpan, `Event soon (${workFormatted})`);
|
setTooltip(dateSpan, `Event soon (${workFormatted})`);
|
||||||
|
|
@ -243,6 +271,7 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
break;
|
break;
|
||||||
case isUpcoming:
|
case isUpcoming:
|
||||||
dateSpan.classList.add('upcoming');
|
dateSpan.classList.add('upcoming');
|
||||||
|
container.classList.add('upcoming');
|
||||||
|
|
||||||
setIcon(iconSpan, 'calendar-clock');
|
setIcon(iconSpan, 'calendar-clock');
|
||||||
setTooltip(dateSpan, `Upcoming event (${workFormatted})`);
|
setTooltip(dateSpan, `Upcoming event (${workFormatted})`);
|
||||||
|
|
@ -250,6 +279,7 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
break;
|
break;
|
||||||
case isActual:
|
case isActual:
|
||||||
dateSpan.classList.add('actual');
|
dateSpan.classList.add('actual');
|
||||||
|
container.classList.add('actual');
|
||||||
|
|
||||||
setIcon(iconSpan, 'clock');
|
setIcon(iconSpan, 'clock');
|
||||||
setTooltip(dateSpan, `Event started (${workFormatted})`);
|
setTooltip(dateSpan, `Event started (${workFormatted})`);
|
||||||
|
|
@ -258,15 +288,25 @@ export default class EventHighlightPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAllPage() {
|
private async updateAllPage() {
|
||||||
const elements = document.querySelectorAll(`[${this.attributeStateName}]`);
|
const elements = document.querySelectorAll(`[${this.attributeStateName}]`);
|
||||||
|
|
||||||
elements.forEach((el) => {
|
const sourcePath = this.app.workspace.getActiveFile()?.path ?? '';
|
||||||
|
|
||||||
|
for (const el of Array.from(elements)) {
|
||||||
const { source } = this.loadState(el);
|
const { source } = this.loadState(el);
|
||||||
|
|
||||||
if (!source) return;
|
if (!source) return;
|
||||||
|
|
||||||
this.renderElement(el, source);
|
await this.renderElement(el, source, undefined, sourcePath);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseSource(source: string) {
|
||||||
|
const lines = source.split(/\r?\n/);
|
||||||
|
const dateSource = (lines[0] || '').trim();
|
||||||
|
const extraText = lines.slice(1).join('\n').trim();
|
||||||
|
|
||||||
|
return { dateSource, extraText };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
styles.css
44
styles.css
|
|
@ -1,3 +1,21 @@
|
||||||
|
.event-highlight-container {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-highlight-text {
|
||||||
|
margin: 6px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
color: var(--text-normal);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge {
|
.event-highlight-badge {
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
|
|
||||||
|
|
@ -12,21 +30,39 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-badge.with-text {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge.after {
|
.event-highlight-badge.after {
|
||||||
background-color: var(--background-secondary-alt);
|
background-color: var(--background-secondary-alt);
|
||||||
color: var(--mono-rgb-255);
|
color: var(--mono-rgb-255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-container.after {
|
||||||
|
border-color: var(--background-secondary-alt);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge.before {
|
.event-highlight-badge.before {
|
||||||
background-color: rgba(var(--color-green-rgb), 0.2);
|
background-color: rgba(var(--color-green-rgb), 0.2);
|
||||||
color: var(--color-green);
|
color: var(--color-green);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-container.before {
|
||||||
|
border-color: rgba(var(--color-green-rgb), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge.upcoming {
|
.event-highlight-badge.upcoming {
|
||||||
background-color: rgba(var(--color-yellow-rgb), 0.2);
|
background-color: rgba(var(--color-yellow-rgb), 0.2);
|
||||||
color: var(--color-yellow);
|
color: var(--color-yellow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-container.upcoming {
|
||||||
|
border-color: rgba(var(--color-yellow-rgb), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge.actual {
|
.event-highlight-badge.actual {
|
||||||
background-color: rgba(var(--color-purple-rgb), 0.2);
|
background-color: rgba(var(--color-purple-rgb), 0.2);
|
||||||
color: var(--color-purple);
|
color: var(--color-purple);
|
||||||
|
|
@ -34,6 +70,10 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-container.actual {
|
||||||
|
border-color: rgba(var(--color-purple-rgb), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge.error {
|
.event-highlight-badge.error {
|
||||||
background-color: rgba(var(--color-red-rgb), 0.2);
|
background-color: rgba(var(--color-red-rgb), 0.2);
|
||||||
color: var(--color-red);
|
color: var(--color-red);
|
||||||
|
|
@ -41,6 +81,10 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-highlight-container.error {
|
||||||
|
border-color: rgba(var(--color-red-rgb), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.event-highlight-badge .icon {
|
.event-highlight-badge .icon {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue