good visuals

This commit is contained in:
Michalis Efstratiadis 2026-01-28 17:19:12 +02:00
parent 1f27aff545
commit cb6d42e8cc
No known key found for this signature in database
2 changed files with 107 additions and 126 deletions

View file

@ -1,4 +1,4 @@
import { ItemView, WorkspaceLeaf, Notice, TFile, DropdownComponent } from "obsidian";
import { ItemView, WorkspaceLeaf, Notice, TFile, DropdownComponent, setIcon, Menu, MenuItem } from "obsidian";
import { CalendarEvent } from "../services/CalendarService";
import MemoChron from "../main";
import { MEMOCHRON_VIEW_TYPE } from "../utils/constants";
@ -164,7 +164,7 @@ export class CalendarView extends ItemView {
// Apply saved height
if (this.plugin.settings.calendarHeight) {
this.calendar.style.height = `${this.plugin.settings.calendarHeight}px`;
this.calendar.style.height = `${this.plugin.settings.calendarHeight} px`;
}
// Create resize handle
@ -190,57 +190,74 @@ export class CalendarView extends ItemView {
// Create navigation container
const nav = controls.createEl("div", { cls: "memochron-nav" });
// Add toggle button at the start of nav
const toggleBtn = nav.createEl("div", {
cls: "memochron-nav-link memochron-toggle-btn",
attr: { "aria-label": "Toggle calendar" }
});
this.updateToggleButtonIcon(toggleBtn);
toggleBtn.onclick = async () => {
await this.plugin.toggleCalendar();
this.updateToggleButtonIcon(toggleBtn);
};
nav.createEl("span", { cls: "memochron-title" });
new DropdownComponent(controls)
.addOption("month", "Month")
.addOption("1", "1 Week")
.addOption("2", "2 Weeks")
.addOption("3", "3 Weeks")
.addOption("4", "4 Weeks")
.addOption("5", "5 Weeks")
.setValue(String(this.viewMode))
.onChange(async (value) => {
this.viewMode = (value === 'month' ? 'month' : parseInt(value)) as CalendarViewMode;
await this.refreshEvents();
});
// View Options Button (Menu)
const viewOptionsBtn = controls.createEl("div", {
cls: "memochron-nav-link clickable-icon",
attr: { "aria-label": "View options" }
});
setIcon(viewOptionsBtn, "layout-grid");
viewOptionsBtn.onclick = (e: MouseEvent) => {
this.showViewMenu(e, viewOptionsBtn);
};
const navButtons = nav.createEl("div", { cls: "memochron-nav-buttons" });
this.createNavButton(navButtons, "<", () => this.navigate(-1));
this.createNavButton(navButtons, "Today", () => this.goToToday());
this.createNavButton(navButtons, ">", () => this.navigate(1));
this.createNavButton(navButtons, "chevron-left", () => this.navigate(-1), true);
this.createNavButton(navButtons, "Today", () => this.goToToday(), false);
this.createNavButton(navButtons, "chevron-right", () => this.navigate(1), true);
return controls;
}
private updateToggleButtonIcon(btn: HTMLElement) {
const isHidden = this.plugin.settings.hideCalendar;
btn.textContent = isHidden ? "Show" : "Hide";
// You could use icons here if preferred, e.g.:
// setIcon(btn, isHidden ? "eye" : "eye-off");
private showViewMenu(event: MouseEvent, target: HTMLElement) {
const menu = new Menu();
const addOption = (label: string, value: CalendarViewMode) => {
menu.addItem((item: MenuItem) => {
item
.setTitle(label)
.setChecked(this.viewMode === value)
.onClick(async () => {
if (this.viewMode !== value) {
this.viewMode = value;
await this.refreshEvents();
}
});
});
};
addOption("Month", "month");
menu.addSeparator();
addOption("1 Week", 1);
addOption("2 Weeks", 2);
addOption("3 Weeks", 3);
addOption("4 Weeks", 4);
addOption("5 Weeks", 5);
menu.showAtMouseEvent(event);
}
private createNavButton(
parent: HTMLElement,
text: string,
onClick: () => void
content: string,
onClick: () => void,
isIcon: boolean
) {
const button = parent.createEl("span", {
text,
cls: "memochron-nav-link",
const button = parent.createEl("div", {
cls: "memochron-nav-link clickable-icon", // clickable-icon gives standard Obsidian icon behavior
attr: { "aria-label": isIcon ? (content === "chevron-left" ? "Previous" : "Next") : content }
});
if (isIcon) {
setIcon(button, content);
} else {
button.setText(content);
button.addClass("text-button"); // Helper class for text buttons
}
button.onclick = onClick;
}
@ -740,10 +757,7 @@ export class CalendarView extends ItemView {
eventEl.createEl("div", {
cls: "memochron-event-time",
text: `${event.start.toLocaleTimeString(
[],
timeFormat
)} - ${event.end.toLocaleTimeString([], timeFormat)}`,
text: `${event.start.toLocaleTimeString([], timeFormat)} - ${event.end.toLocaleTimeString([], timeFormat)}`,
});
}
}
@ -831,46 +845,22 @@ export class CalendarView extends ItemView {
const controls = this.containerEl.querySelector(
".memochron-controls"
) as HTMLElement;
const navTitle = controls?.querySelector(".memochron-title") as HTMLElement;
const navButtons = controls?.querySelector(".memochron-nav-buttons") as HTMLElement;
const toggleBtn = controls?.querySelector(".memochron-toggle-btn") as HTMLElement;
if (this.plugin.settings.hideCalendar) {
this.calendar.style.display = "none";
if (this.resizeHandle) this.resizeHandle.style.display = "none";
// Hide nav elements but keep the toggle button visible
if (navTitle) navTitle.style.display = "none";
if (navButtons) navButtons.style.display = "none";
if (controls) {
controls.style.display = ""; // Ensure controls container is visible
controls.classList.add("calendar-hidden");
const dropdown = controls.querySelector("select");
if (dropdown) dropdown.style.display = "none";
controls.style.display = "none";
}
this.agenda.classList.add("agenda-only");
} else {
this.calendar.style.display = "";
if (this.resizeHandle) this.resizeHandle.style.display = "";
// Show nav elements
if (navTitle) navTitle.style.display = "";
if (navButtons) navButtons.style.display = "";
if (controls) {
controls.style.display = "";
controls.classList.remove("calendar-hidden");
const dropdown = controls.querySelector("select");
if (dropdown) dropdown.style.display = "";
}
this.agenda.classList.remove("agenda-only");
}
// Update the button text/state
if (toggleBtn) {
this.updateToggleButtonIcon(toggleBtn);
}
}
private setupDragAndDrop() {

View file

@ -22,13 +22,14 @@
overflow: hidden;
}
/* Controls */
/* Controls */
.memochron-controls {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--memochron-padding-sm);
padding: var(--memochron-padding-sm);
margin-bottom: var(--size-4-1);
padding: var(--size-4-1);
}
.memochron-nav {
@ -41,36 +42,44 @@
.memochron-nav-buttons {
display: flex;
align-items: center;
gap: var(--memochron-gap);
gap: var(--size-4-1);
}
/* Ghost button base */
.memochron-nav-link {
cursor: pointer;
color: var(--text-muted);
font-size: 0.9em;
padding: var(--memochron-padding-xs) var(--memochron-padding-sm);
border-radius: var(--radius-s);
transition:
color 0.1s ease,
background-color 0.1s ease;
transition: all 0.1s ease;
user-select: none;
display: inline-flex;
align-items: center;
justify-content: center;
background-color: transparent;
width: 28px;
/* Standard icon button size */
height: 28px;
}
/* Specifics for text buttons like "Today" */
.memochron-nav-link.text-button {
width: auto;
padding: 0 var(--size-4-2);
font-size: 0.85em;
font-weight: 500;
}
.memochron-nav-link:hover,
.memochron-nav-link:focus {
color: var(--text-normal);
background-color: var(--background-modifier-hover);
outline: 2px solid var(--interactive-accent);
outline-offset: 1px;
}
.memochron-title {
font-size: 0.9em;
font-size: 1em;
color: var(--text-normal);
font-weight: 500;
margin: 0 var(--memochron-padding-sm);
font-weight: 600;
margin: 0 var(--size-4-2);
}
/* Month View */
@ -89,28 +98,30 @@
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8em;
color: var(--text-muted);
background-color: var(--background-secondary);
border-radius: var(--radius-s);
font-size: 0.75em;
color: var(--text-faint);
background-color: transparent;
margin: 1px;
}
.memochron-weekday.week-number-header {
color: var(--text-faint);
font-size: 0.8em;
font-size: 0.75em;
}
.memochron-weekday {
padding: var(--memochron-padding-xs);
padding: var(--size-4-1);
text-align: center;
color: var(--text-muted);
font-size: 0.95em;
font-size: 0.8em;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 500;
}
.memochron-day {
min-height: 2rem;
padding: var(--memochron-padding-xs);
padding: var(--size-4-1);
position: relative;
cursor: pointer;
border-radius: var(--radius-s);
@ -118,14 +129,12 @@
flex-direction: column;
align-items: center;
background-color: transparent;
transition:
background-color 0.1s ease-in,
color 0.1s ease-in;
transition: background-color 0.1s ease-in;
}
.memochron-day:hover,
.memochron-day:focus {
background-color: var(--interactive-hover);
background-color: var(--background-modifier-hover);
outline: none;
}
@ -136,44 +145,41 @@
.memochron-day.selected {
background-color: var(--interactive-accent);
box-shadow: inset 0 0 0 1px var(--background-modifier-border);
}
/* Important: Always ensure text is visible on selected days */
.memochron-day.selected .memochron-day-header {
color: var(--text-on-accent) !important;
/* Use !important to override any theme styles */
font-weight: 600;
}
.memochron-day.selected .memochron-event-dot {
color: var(--text-on-accent);
}
.memochron-day.today {
border: 1px solid var(--interactive-accent);
opacity: 0.8;
/* Slight contrast on accent background */
}
.memochron-day.today .memochron-day-header {
color: var(--color-text-today);
color: var(--interactive-accent);
font-weight: 700;
}
.memochron-day-header {
font-size: 1em;
color: var(--text-muted);
font-size: 0.95em;
color: var(--text-normal);
transition: color 0.1s ease-in;
}
.memochron-day.has-events .memochron-day-header {
color: var(--color-text-day);
color: var(--text-normal);
}
.memochron-event-dot {
width: 6px;
height: 6px;
width: 4px;
height: 4px;
border-radius: 50%;
background-color: var(--interactive-accent);
margin-bottom: 2px;
background-color: var(--text-muted);
/* Default to muted if no color */
margin-bottom: 1px;
}
/* Colored dots container */
@ -192,10 +198,7 @@
margin-bottom: 0;
}
/* Daily note dot styling */
.memochron-event-dot.daily-note-dot {
/* Ensure it looks the same as others */
}
/* Daily note dot styling - inherits common dot styles */
/* Make daily note dot slightly larger when it's the only dot */
.memochron-event-dots-container:has(.daily-note-dot):not( :has(.memochron-event-dot:not(.daily-note-dot))) .daily-note-dot {
@ -318,8 +321,7 @@
}
.memochron-controls.calendar-hidden {
/* display: none; <-- We want to keep this visible for the toggle button */
display: flex;
display: none;
}
.memochron-agenda h3 {
@ -372,10 +374,7 @@
color: var(--text-muted);
}
/* Daily note entry styling */
.memochron-agenda-event.memochron-daily-note {
/* Keep the same background as regular events */
}
/* Color picker styles */
.memochron-color-button {
@ -1132,14 +1131,6 @@
margin: var(--size-4-3) 0;
}
/* Toggle Button */
.memochron-toggle-btn {
font-weight: 500;
min-width: 60px;
/* Prevent layout jump */
justify-content: center;
}
.memochron-controls.calendar-hidden .memochron-nav {
justify-content: flex-start;
/* Align left when alone */