Skip to content

Commit

Permalink
Fix issues with tag and date variations
Browse files Browse the repository at this point in the history
  • Loading branch information
mgmeyers committed Apr 18, 2024
1 parent c6360ca commit 9569e80
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 77 deletions.
8 changes: 6 additions & 2 deletions src/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ export class SettingsManager {
toggle.setValue(value as boolean);
} else if (globalValue !== undefined) {
toggle.setValue(globalValue as boolean);
} else {
toggle.setValue(true);
}

toggle.onChange((newValue) => {
Expand All @@ -524,7 +526,7 @@ export class SettingsManager {
.setTooltip(t('Reset to default'))
.onClick(() => {
const [, globalValue] = this.getSetting('hide-tags-display', local);
toggleComponent.setValue(!!globalValue);
toggleComponent.setValue((globalValue as boolean) ?? true);

this.applySettingsUpdate({
$unset: ['hide-tags-display'],
Expand Down Expand Up @@ -1072,6 +1074,8 @@ export class SettingsManager {
toggle.setValue(value as boolean);
} else if (globalValue !== undefined) {
toggle.setValue(globalValue as boolean);
} else {
toggle.setValue(true);
}

toggle.onChange((newValue) => {
Expand All @@ -1087,7 +1091,7 @@ export class SettingsManager {
.setTooltip(t('Reset to default'))
.onClick(() => {
const [, globalValue] = this.getSetting('hide-date-display', local);
toggleComponent.setValue(!!globalValue);
toggleComponent.setValue((globalValue as boolean) ?? true);

this.applySettingsUpdate({
$unset: ['hide-date-display'],
Expand Down
124 changes: 70 additions & 54 deletions src/components/Editor/dateWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
WidgetType,
} from '@codemirror/view';
import { moment } from 'obsidian';
import { useMemo } from 'preact/hooks';

import { StateManager } from '../../StateManager';
import { c } from '../helpers';
Expand Down Expand Up @@ -133,70 +134,85 @@ export const datePlugins: Extension[] = [
create('date', '\\[([^\\]]+)\\]\\([^)]+\\)'),
];

export function preprocess(
export function usePreprocessedStr(
stateManager: StateManager,
str: string,
getDateColor: (date: moment.Moment) => DateColorKey
) {
const dateTrigger = stateManager.getSetting('date-trigger');
const dateFormat = stateManager.getSetting('date-format');
const dateDisplayFormat = stateManager.getSetting('date-display-format');
const timeTrigger = stateManager.getSetting('time-trigger');
const timeFormat = stateManager.getSetting('time-format');
const useLinks = stateManager.getSetting('link-date-to-daily-note');

let dateColor: DateColorKey;
const getWrapperStyles = (baseClass: string) => {
let wrapperStyle = '';
if (dateColor) {
if (dateColor.backgroundColor) {
baseClass += ' has-background';
wrapperStyle = ` style="--date-color: ${dateColor.color}; --date-background-color: ${dateColor.backgroundColor};"`;
} else {
wrapperStyle = ` style="--date-color: ${dateColor.color};"`;
const dateTrigger = stateManager.useSetting('date-trigger');
const dateFormat = stateManager.useSetting('date-format');
const dateDisplayFormat = stateManager.useSetting('date-display-format');
const timeTrigger = stateManager.useSetting('time-trigger');
const timeFormat = stateManager.useSetting('time-format');
const useLinks = stateManager.useSetting('link-date-to-daily-note');
const tagColors = stateManager.getSetting('tag-colors');

return useMemo(() => {
let dateColor: DateColorKey;
const getWrapperStyles = (baseClass: string) => {
let wrapperStyle = '';
if (dateColor) {
if (dateColor.backgroundColor) {
baseClass += ' has-background';
wrapperStyle = ` style="--date-color: ${dateColor.color}; --date-background-color: ${dateColor.backgroundColor};"`;
} else {
wrapperStyle = ` style="--date-color: ${dateColor.color};"`;
}
}
}
return { wrapperClass: baseClass, wrapperStyle };
};

if (useLinks) {
str = str.replace(new RegExp(`${dateTrigger}\\[\\[([^\\]]+)\\]\\]`, 'g'), (match, content) => {
const parsed = moment(content, dateFormat);
if (!parsed.isValid()) return match;
const linkPath = app.metadataCache.getFirstLinkpathDest(content, stateManager.file.path);
if (!linkPath) return match;
if (!dateColor) dateColor = getDateColor(parsed);
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-date-wrapper'));
return `<span class="${wrapperClass}"${wrapperStyle}><a class="${c('preview-date')} internal-link" data-href="${linkPath.path}" href="${linkPath.path}" target="_blank" rel="noopener">${parsed.format(dateDisplayFormat)}</a></span>`;
});
str = str.replace(
new RegExp(`${dateTrigger}\\[([^\\]]+)\\]\\([^)]+\\)`, 'g'),
(match, content) => {
return { wrapperClass: baseClass, wrapperStyle };
};

if (useLinks) {
str = str.replace(
new RegExp(`${dateTrigger}\\[\\[([^\\]]+)\\]\\]`, 'g'),
(match, content) => {
console.log(match, content);
const parsed = moment(content, dateFormat);
if (!parsed.isValid()) return match;
const linkPath = app.metadataCache.getFirstLinkpathDest(content, stateManager.file.path);
if (!dateColor) dateColor = getDateColor(parsed);
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-date-wrapper'));
return `<span class="${wrapperClass} ${c('preview-date-link')}"${wrapperStyle}><a class="${c('preview-date')} internal-link" data-href="${linkPath?.path ?? content}" href="${linkPath?.path ?? content}" target="_blank" rel="noopener">${parsed.format(dateDisplayFormat)}</a></span>`;
}
);
str = str.replace(
new RegExp(`${dateTrigger}\\[([^\\]]+)\\]\\([^)]+\\)`, 'g'),
(match, content) => {
const parsed = moment(content, dateFormat);
if (!parsed.isValid()) return match;
const linkPath = app.metadataCache.getFirstLinkpathDest(content, stateManager.file.path);
if (!linkPath) return match;
if (!dateColor) dateColor = getDateColor(parsed);
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-date-wrapper'));
return `<span class="${wrapperClass} ${c('preview-date-link')}"${wrapperStyle}><a class="${c('preview-date')} internal-link" data-href="${linkPath.path}" href="${linkPath.path}" target="_blank" rel="noopener">${parsed.format(dateDisplayFormat)}</a></span>`;
}
);
} else {
str = str.replace(new RegExp(`${dateTrigger}{([^}]+)}`, 'g'), (match, content) => {
const parsed = moment(content, dateFormat);
if (!parsed.isValid()) return match;
const linkPath = app.metadataCache.getFirstLinkpathDest(content, stateManager.file.path);
if (!linkPath) return match;
if (!dateColor) dateColor = getDateColor(parsed);
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-date-wrapper'));
return `<span class="${wrapperClass}"${wrapperStyle}><a class="${c('preview-date')} internal-link" data-href="${linkPath.path}" href="${linkPath.path}" target="_blank" rel="noopener">${parsed.format(dateDisplayFormat)}</a></span>`;
}
);
} else {
str = str.replace(new RegExp(`${dateTrigger}{([^}]+)}`, 'g'), (match, content) => {
const parsed = moment(content, dateFormat);
return `<span class="${wrapperClass}"${wrapperStyle}><span class="${c('preview-date')} ${c('item-metadata-date')}">${parsed.format(dateDisplayFormat)}</span></span>`;
});
}

str = str.replace(new RegExp(`${timeTrigger}{([^}]+)}`, 'g'), (match, content) => {
const parsed = moment(content, timeFormat);
if (!parsed.isValid()) return match;
if (!dateColor) dateColor = getDateColor(parsed);
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-date-wrapper'));
return `<span class="${wrapperClass}"${wrapperStyle}><span class="${c('preview-date')} ${c('item-metadata-date')}">${parsed.format(dateDisplayFormat)}</span></span>`;
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-time-wrapper'));
return `<span class="${wrapperClass}"${wrapperStyle}><span class="${c('preview-time')} ${c('item-metadata-time')}">${parsed.format(timeFormat)}</span></span>`;
});
}

str = str.replace(new RegExp(`${timeTrigger}{([^}]+)}`, 'g'), (match, content) => {
const parsed = moment(content, timeFormat);
if (!parsed.isValid()) return match;
const { wrapperClass, wrapperStyle } = getWrapperStyles(c('preview-time-wrapper'));
return `<span class="${wrapperClass}"${wrapperStyle}><span class="${c('preview-time')} ${c('item-metadata-time')}">${parsed.format(timeFormat)}</span></span>`;
});

return str;
return str;
}, [
dateTrigger,
dateFormat,
dateDisplayFormat,
timeTrigger,
timeFormat,
useLinks,
str,
tagColors,
]);
}
2 changes: 1 addition & 1 deletion src/components/Item/ItemContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export function Tags({
style={
tagColor && {
'--tag-color': tagColor.color,
'--tag-background-color': tagColor.backgroundColor,
'--tag-background': tagColor.backgroundColor,
}
}
>
Expand Down
46 changes: 37 additions & 9 deletions src/components/MarkdownRenderer/MarkdownRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@
import classcat from 'classcat';
import Mark from 'mark.js';
import moment from 'moment';
import { MarkdownRenderer as ObsidianRenderer, TFile, getLinkpath } from 'obsidian';
import {
MarkdownPostProcessorContext,
MarkdownRenderer as ObsidianRenderer,
TFile,
getLinkpath,
} from 'obsidian';
import { appHasDailyNotesPluginLoaded, createDailyNote } from 'obsidian-daily-notes-interface';
import { CSSProperties, memo, useEffect, useRef } from 'preact/compat';
import { useCallback, useContext, useMemo } from 'preact/hooks';
import { useCallback, useContext } from 'preact/hooks';
import { KanbanView } from 'src/KanbanView';
import { DndManagerContext, EntityManagerContext } from 'src/dnd/components/context';
import { PromiseCapability } from 'src/helpers/util';
import KanbanPlugin from 'src/main';
import { frontmatterKey } from 'src/parsers/common';

import {
applyCheckboxIndexes,
getNormalizedPath,
renderMarkdown,
} from '../../helpers/renderMarkdown';
import { preprocess } from '../Editor/dateWidget';
import { usePreprocessedStr } from '../Editor/dateWidget';
import { KanbanContext } from '../context';
import { c, noop } from '../helpers';

Expand Down Expand Up @@ -379,6 +385,32 @@ export class MarkdownRenderer extends ObsidianRenderer {
}
}

export function postProcessor(plugin: KanbanPlugin) {
return (el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
const file = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath);
if (!file || !(file instanceof TFile)) return;

const stateManager = plugin.getStateManager(file);
if (!stateManager) return;

const tagColors = stateManager.getSetting('tag-colors');
if (!tagColors.length) return;

const tagAs = el.querySelectorAll<HTMLAnchorElement>('a.tag');
if (!tagAs.length) return;

tagAs.forEach((a) => {
const color = tagColors.find((c) => c.tagKey === a.getAttr('href'));
if (!color) return;

a.setCssProps({
'--tag-color': color.color,
'--tag-background': color.backgroundColor,
});
});
};
}

export const MarkdownPreviewRenderer = memo(function MarkdownPreviewRenderer({
entityId,
className,
Expand All @@ -393,11 +425,7 @@ export const MarkdownPreviewRenderer = memo(function MarkdownPreviewRenderer({

const entityManager = useContext(EntityManagerContext);
const dndManager = useContext(DndManagerContext);

const processed = useMemo(
() => preprocess(stateManager, markdownString, getDateColor),
[stateManager, markdownString]
);
const processed = usePreprocessedStr(stateManager, markdownString, getDateColor);

useEffect(() => {
const renderCapability = new PromiseCapability();
Expand Down Expand Up @@ -470,7 +498,7 @@ export const MarkdownPreviewRenderer = memo(function MarkdownPreviewRenderer({
preview.set(processed);
preview.renderer.onRendered(() => {
preview.showChildren();
if (!entityManager.isVisible) preview.hideChildren();
if (!entityManager?.isVisible) preview.hideChildren();
});
}, [processed]);

Expand Down
2 changes: 1 addition & 1 deletion src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ function useTableColumns(boardData: Board, stateManager: StateManager) {
}

return columns;
}, metadata);
}, [shouldShowRelativeDate, hideDateDisplay, hideTagsDisplay, ...metadata]);

const withFileMetadata = useMemo(() => {
const columns = [...withMetadata];
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { KanbanView, kanbanIcon, kanbanViewType } from './KanbanView';
import { KanbanSettings, KanbanSettingsTab } from './Settings';
import { StateManager } from './StateManager';
import { DateSuggest, TimeSuggest } from './components/Editor/suggest';
import { postProcessor } from './components/MarkdownRenderer/MarkdownRenderer';
import { getParentWindow } from './dnd/util/getWindow';
import { hasFrontmatterKey } from './helpers';
import { t } from './lang/helpers';
Expand Down Expand Up @@ -104,6 +105,7 @@ export default class KanbanPlugin extends Plugin {

this.registerEditorSuggest(new DateSuggest(this.app, this));
this.registerEditorSuggest(new TimeSuggest(this.app, this));
this.registerMarkdownPostProcessor(postProcessor(this));

this.registerEvent(
this.app.workspace.on('window-open', (_: any, win: Window) => {
Expand Down
2 changes: 1 addition & 1 deletion src/settings/TagColorSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function Item({ tagColorKey, deleteKey, updateKey, defaultColors }: ItemProps) {
className={`tag ${c('item-tag')}`}
style={{
'--tag-color': tagColorKey.color,
'--tag-background-color': tagColorKey.backgroundColor,
'--tag-background': tagColorKey.backgroundColor,
}}
>
{tagColorKey.tagKey || '#tag'}
Expand Down
21 changes: 12 additions & 9 deletions src/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ button.kanban-plugin__new-item-button {
.kanban-plugin__item-title {
width: 100%;
line-height: var(--line-height-tight);
overflow: hidden;
}

.kanban-plugin__meta-value,
Expand Down Expand Up @@ -864,7 +863,7 @@ button.kanban-plugin__new-item-button {

.kanban-plugin__item-tags .kanban-plugin__item-tag {
font-size: 12px;
background-color: var(--tag-background-color, hsla(var(--interactive-accent-hsl), 0.1));
background-color: var(--tag-background, hsla(var(--interactive-accent-hsl), 0.1));
color: var(--tag-color, var(--text-accent));
margin-block: 3px 0;
margin-inline: 0 3px;
Expand Down Expand Up @@ -1824,17 +1823,21 @@ body:not(.native-scrollbars) .kanban-plugin__scroll-container::-webkit-scrollbar
border-radius: var(--radius-s);
background-color: rgba(var(--mono-rgb-100), 0.05);

&:hover {
background-color: rgba(var(--mono-rgb-100), 0.1);
}

&.kanban-plugin__preview-date-link {
--link-decoration: none;
--link-unresolved-decoration-style: unset;
}

&.has-background {
background-color: var(--date-background-color, transparent);
}

> span {
> span,
> a {
padding-inline: var(--size-2-1);

@media (hover: hover) {
&:hover {
background-color: rgba(var(--mono-rgb-100), 0.1);
}
}
}
}

0 comments on commit 9569e80

Please sign in to comment.