Skip to content

Commit

Permalink
Merge pull request #17 from natefrisch01/natefrisch01/themes
Browse files Browse the repository at this point in the history
Text color is now chosen based on the --text-normal attribute of .the…
  • Loading branch information
natefrisch01 committed Jan 17, 2024
2 parents cd44cb6 + e7c4fe4 commit fa68cfb
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 23 deletions.
77 changes: 59 additions & 18 deletions linkManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,71 @@ import extractLinks from 'markdown-link-extractor';
export class LinkManager {
linksMap: Map<string, GltLink>;
api = getAPI();
currentTheme : string;
textColor : string;

constructor() {
this.linksMap = new Map<string, GltLink>();

// Detect changes to the theme.
this.detectThemeChange();
}

generateKey(sourceId: string, targetId: string): string {
return `${sourceId}-${targetId}`;
}

private detectThemeChange(): void {
let lastTheme = '';
let lastStyleSheetHref = '';
let debounceTimer: number;

const themeObserver = new MutationObserver(() => {
clearTimeout(debounceTimer);
debounceTimer = window.setTimeout(() => {
this.currentTheme = document.body.classList.contains('theme-dark') ? 'theme-dark' : 'theme-light';
const currentStyleSheetHref = document.querySelector('link[rel="stylesheet"][href*="theme"]')?.getAttribute('href');
if ((this.currentTheme && this.currentTheme !== lastTheme) || (currentStyleSheetHref !== lastStyleSheetHref)) {
console.log(`Theme has changed to: ${this.currentTheme}`);
this.textColor = this.getComputedColorFromClass(this.currentTheme, '--text-normal');
console.log(this.textColor);
lastTheme = this.currentTheme;
if (currentStyleSheetHref) {
lastStyleSheetHref = currentStyleSheetHref;
}
}
}, 100); // Debounce delay
});

themeObserver.observe(document.body, { attributes: true, attributeFilter: ['class'] });
themeObserver.observe(document.head, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'] });
}

private getComputedColorFromClass(className : string, cssVariable : string) : string {
// Create a temporary element
const tempElement = document.createElement('div');

// Apply the class to the temporary element
tempElement.classList.add(className);
document.body.appendChild(tempElement);

// Get the computed style of the temporary element
const style = getComputedStyle(tempElement);
const colorValue = style.getPropertyValue(cssVariable).trim();

// Remove the temporary element
document.body.removeChild(tempElement);

// Check if the color is in HSL format
if (colorValue.startsWith('hsl')) {
// Return a default color based on some condition, e.g., current theme
// This is a placeholder condition
return document.body.classList.contains('theme-dark') ? '#b3b3b3' : '#5c5c5c';
} else {
// If it's not HSL, return the color as-is
return colorValue;
}
}

addLink(renderer: ObsidianRenderer, obLink: ObsidianLink): void {
const key = this.generateKey(obLink.source.id, obLink.target.id);
Expand Down Expand Up @@ -101,6 +158,7 @@ export class LinkManager {
text.x = x;
text.y = y;
text.scale.set(1 / (3 * renderer.nodeScale));
text.style.fill = this.textColor;
}
}

Expand Down Expand Up @@ -129,7 +187,7 @@ export class LinkManager {
const textStyle: TextStyle = new TextStyle({
fontFamily: 'Arial',
fontSize: 36,
fill: this.determineTextColor()
fill: this.textColor
});
// Create new text node
const text: Text = new Text(linkString, textStyle);
Expand All @@ -149,22 +207,6 @@ export class LinkManager {
return links.length > 0 ? links[0] : '';
}

private determineTextColor(): string {
// Get the computed style of the document body
const style = getComputedStyle(document.body);

// This is a basic check. You might need to adjust the logic based on the themes you support.
// Here, we assume that dark themes have a background color with a low brightness value.
let textColor = '#FF0000';
if (style && style.backgroundColor && style.backgroundColor) {
// @ts-ignore
const isDarkTheme = style.backgroundColor.match(/\d+/g)?.map(Number).slice(0, 3).reduce((a, b) => a + b, 0) < 382.5;
isDarkTheme ? textColor = '#FFFFFF' : textColor = '#000000'; // White text for dark themes, black for light themes)
}

return textColor
}

// Method to determine the type of a value, now a class method
private determineDataviewLinkType(value: any): DataviewLinkType {
if (typeof value === 'object' && value !== null && 'path' in value) {
Expand Down Expand Up @@ -237,6 +279,5 @@ export class LinkManager {
// Apply scaling and panning to calculate the actual position.
return { x: linkX * scale + panX, y: linkY * scale + panY };
}


}
9 changes: 4 additions & 5 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Plugin, Notice} from 'obsidian';
import { getAPI } from 'obsidian-dataview';
import { ObsidianRenderer, ObsidianLink, LinkPair} from 'types';
import { ObsidianRenderer, ObsidianLink} from 'types';
import { LinkManager } from 'linkManager';


Expand Down Expand Up @@ -108,7 +108,7 @@ export default class GraphLinkTypesPlugin extends Plugin {
const renderer : ObsidianRenderer = this.currentRenderer;
// Remove existing text from the graph.
this.linkManager.destroyMap(renderer);

// Call the function to update positions in the next animation frame.
requestAnimationFrame(this.updatePositions.bind(this));
}
Expand All @@ -122,13 +122,11 @@ export default class GraphLinkTypesPlugin extends Plugin {
return;
}



const renderer: ObsidianRenderer = this.currentRenderer;

let updateMap = false;

if (this.animationFrameId && this.animationFrameId % 20 == 0) {
if (this.animationFrameId && this.animationFrameId % 10 == 0) {
updateMap = true;
// Update link manager with the current frame's links
this.linkManager.removeLinks(renderer, renderer.links);
Expand Down Expand Up @@ -159,5 +157,6 @@ export default class GraphLinkTypesPlugin extends Plugin {
&& typeof renderer.px.stage.removeChild === 'function'
&& Array.isArray(renderer.links);
}

}

0 comments on commit fa68cfb

Please sign in to comment.