Fix mini-calendar to respect week_start_day config setting

This commit is contained in:
Bendt
2025-12-19 13:00:42 -05:00
parent 3629757e70
commit b75c069035

View File

@@ -16,15 +16,21 @@ from textual.reactive import reactive
from textual.strip import Strip from textual.strip import Strip
from textual.widget import Widget from textual.widget import Widget
from src.calendar import config
def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
def get_month_calendar(
year: int, month: int, week_start_day: int = 0
) -> list[list[Optional[date]]]:
"""Generate a calendar grid for a month. """Generate a calendar grid for a month.
Returns a list of weeks, where each week is a list of 7 dates (or None for empty cells). Returns a list of weeks, where each week is a list of 7 dates (or None for empty cells).
Week starts on Monday.
"""
import calendar
Args:
year: The year
month: The month (1-12)
week_start_day: Config format (0=Sunday, 1=Monday, ..., 6=Saturday)
"""
# Get first day of month and number of days # Get first day of month and number of days
first_day = date(year, month, 1) first_day = date(year, month, 1)
if month == 12: if month == 12:
@@ -32,11 +38,17 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
else: else:
last_day = date(year, month + 1, 1) - timedelta(days=1) last_day = date(year, month + 1, 1) - timedelta(days=1)
# Monday = 0, Sunday = 6 # Convert config week start to python weekday
first_weekday = first_day.weekday() # Config: 0=Sunday, 1=Monday, ..., 6=Saturday
# Python: 0=Monday, 1=Tuesday, ..., 6=Sunday
python_week_start = (week_start_day - 1) % 7
# Calculate which day of the week the first day falls on (relative to week start)
first_python_weekday = first_day.weekday() # 0=Monday, 6=Sunday
days_offset = (first_python_weekday - python_week_start) % 7
weeks: list[list[Optional[date]]] = [] weeks: list[list[Optional[date]]] = []
current_week: list[Optional[date]] = [None] * first_weekday current_week: list[Optional[date]] = [None] * days_offset
current = first_day current = first_day
while current <= last_day: while current <= last_day:
@@ -55,6 +67,22 @@ def get_month_calendar(year: int, month: int) -> list[list[Optional[date]]]:
return weeks return weeks
def get_day_names(week_start_day: int = 0) -> str:
"""Get day name headers based on week start day.
Args:
week_start_day: Config format (0=Sunday, 1=Monday, ..., 6=Saturday)
Returns:
String like "Su Mo Tu We Th Fr Sa" or "Mo Tu We Th Fr Sa Su"
"""
# Full list starting from Sunday (config day 0)
all_days = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
# Rotate to start from week_start_day
rotated = all_days[week_start_day:] + all_days[:week_start_day]
return " ".join(rotated)
class MonthCalendar(Widget): class MonthCalendar(Widget):
"""A compact month calendar widget for sidebars.""" """A compact month calendar widget for sidebars."""
@@ -122,7 +150,11 @@ class MonthCalendar(Widget):
@property @property
def _weeks(self) -> list[list[Optional[date]]]: def _weeks(self) -> list[list[Optional[date]]]:
"""Get the weeks for the current display month.""" """Get the weeks for the current display month."""
return get_month_calendar(self.display_month.year, self.display_month.month) return get_month_calendar(
self.display_month.year,
self.display_month.month,
config.week_start_day(),
)
def get_content_height(self, container, viewport, width: int) -> int: def get_content_height(self, container, viewport, width: int) -> int:
"""Calculate height: header + day names + weeks.""" """Calculate height: header + day names + weeks."""
@@ -152,8 +184,8 @@ class MonthCalendar(Widget):
return Strip([Segment(header, style)]) return Strip([Segment(header, style)])
def _render_day_names(self) -> Strip: def _render_day_names(self) -> Strip:
"""Render the day name headers (Mo Tu We ...).""" """Render the day name headers based on week start setting."""
day_names = "Mo Tu We Th Fr Sa Su" day_names = get_day_names(config.week_start_day())
# Pad to widget width # Pad to widget width
line = day_names[: self.size.width].ljust(self.size.width) line = day_names[: self.size.width].ljust(self.size.width)
style = Style(color="bright_black") style = Style(color="bright_black")