mirror of
https://github.com/formax68/memoChron.git
synced 2026-07-22 12:30:31 +00:00
good visuals
This commit is contained in:
parent
1f27aff545
commit
cb6d42e8cc
2 changed files with 107 additions and 126 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
107
styles.css
107
styles.css
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue