Week view flexibility: configurable day count, layout, and a CalDAV task list
Build and push server image / build-and-push (push) Successful in 52s

- Day count (2-10, was fixed at 7) -- 5 days trims the weekend clutter
  without losing the grid format.
- Layout choice: days side by side (original behavior) or stacked
  vertically as full agenda-style sections (reuses _draw_agenda_day,
  same approach _build_today_tomorrow already used for a fixed 2 days).
- Optional task list (CalDAV VTODO collections only -- a plain ICS
  subscription doesn't meaningfully have one) that takes the space of
  one day slot instead of adding an extra one. Same owner-controls-
  their-own-data permission split as calendar sources: only the
  calendar's owner can point a frame's task list at it, but anyone
  linked to the frame can clear it.

Browse-offset paging now moves by N days (was hardcoded to weeks),
identical to the old behavior when days=7. Changing the day count
resets the browse offset, same reasoning as changing views already did.
This commit is contained in:
2026-07-23 07:58:13 -04:00
parent 01b9e9f1d0
commit ce8525bee8
10 changed files with 436 additions and 25 deletions
+45
View File
@@ -39,6 +39,15 @@
</select>
</label>
<p class="sub" style="margin-top: 4px;">Only affects the Week and Month views.</p>
<label>Days to show (Week view)
<input type="number" id="calendar_week_days" min="2" max="10" value="{{ frame.calendar_week_days }}">
</label>
<label>Week view layout
<select id="calendar_week_layout">
<option value="horizontal" {% if frame.calendar_week_layout == "horizontal" %}selected{% endif %}>Days side by side</option>
<option value="vertical" {% if frame.calendar_week_layout == "vertical" %}selected{% endif %}>Days stacked</option>
</select>
</label>
<div class="checkbox-row" id="calendar-inlay-row">
<input type="checkbox" id="calendar_photo_inlay" {% if frame.calendar_photo_inlay %}checked{% endif %}>
<label for="calendar_photo_inlay">Show a photo alongside the calendar</label>
@@ -131,6 +140,42 @@
<button type="button" class="btn-inline" id="weather-city-add">Add</button>
</div>
</section>
<section class="card" style="margin-top: 20px;">
<h2 class="card-title">Tasks</h2>
<p class="sub">Week view only -- takes the place of one day slot
instead of adding an extra one.</p>
<div class="checkbox-row" id="tasks-enabled-row">
<input type="checkbox" id="tasks_enabled" {% if frame.calendar_tasks_enabled %}checked{% endif %}>
<label for="tasks_enabled">Show a task list</label>
</div>
{% if tasks_source %}
<p class="sub" style="margin-top: 10px;">
Currently using <strong>{{ tasks_source.display_name }}</strong>'s
<strong>{{ tasks_source.label }}</strong> list.
<button type="button" class="btn-inline secondary" id="tasks-source-clear">Clear</button>
</p>
{% endif %}
{% if viewer_task_calendars %}
<p class="sub" style="margin-top: 10px;">Use one of your own CalDAV task lists:</p>
<ul class="calendar-user-list">
{% for c in viewer_task_calendars %}
<li class="checkbox-row" style="margin-top: 6px;">
<input type="radio" name="tasks-source-choice" class="tasks-source-choice" data-key="{{ c.key }}"
{% if tasks_source and tasks_source.user_id == user.id and frame.calendar_tasks_calendar_key == c.key %}checked{% endif %}>
<label style="margin: 0; font-weight: normal;">{{ c.label }}</label>
</li>
{% endfor %}
</ul>
{% else %}
<p class="sub" style="margin-top: 10px;">You don't have any CalDAV
task lists available -- set up a CalDAV account in
<a href="/settings">Settings</a> first (a plain ICS subscription
doesn't carry tasks).</p>
{% endif %}
</section>
</div>
<div class="side-col">