Web: caret/selection fix, reminder options & labels, group mute, rounded modal

- Stop the blinking text caret / selection on non-editable UI chrome
  (headings, buttons, icons, dropdowns): body is user-select:none, with text
  selection opted back in for inputs/textareas. Felt like an editable field.
- Reminder options trimmed to 5/15/30 min, 1 h, 1 day, 1 week (dropped 10 min,
  2 h, 2 days; added 1 week). Labels now read "5 Minuten vorher", "1 Tag
  vorher", "1 Woche vorher" instead of "vor 5 Min." / "vor 1 Tag(en)".
- Group calendars can now be muted (reminder bell) in the sidebar when owned.
- Event modal corners rounded (20px) to match the pill buttons.
- version v45 -> v46.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-06-09 20:32:01 +02:00
parent db43bad432
commit c684a424eb
4 changed files with 31 additions and 13 deletions

View File

@@ -44,6 +44,13 @@ body {
} }
input, select, textarea, button { font-family: inherit; font-size: inherit; color: inherit; } input, select, textarea, button { font-family: inherit; font-size: inherit; color: inherit; }
button { cursor: pointer; border: none; background: none; } button { cursor: pointer; border: none; background: none; }
/* Treat the app like native UI chrome: clicking a heading, button, icon or
dropdown must not place a blinking text caret or select the label. Real text
entry (inputs / textareas) opts selection back in. */
body { -webkit-user-select: none; user-select: none; }
input, textarea, [contenteditable="true"], .selectable {
-webkit-user-select: text; user-select: text;
}
a { color: var(--primary); text-decoration: none; } a { color: var(--primary); text-decoration: none; }
::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-track { background: transparent; }
@@ -936,7 +943,7 @@ a { color: var(--primary); text-decoration: none; }
.modal-card { .modal-card {
background: var(--bg-surface); background: var(--bg-surface);
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: var(--radius); border-radius: 20px;
width: 100%; width: 100%;
max-height: 90vh; overflow-y: auto; max-height: 90vh; overflow-y: auto;
box-shadow: var(--shadow-lg); box-shadow: var(--shadow-lg);

View File

@@ -713,10 +713,12 @@ function renderCalendarList() {
sourceLabel: `${t('shared_with_me')} · ${cal.shared_by || ''}`, remove: null }); sourceLabel: `${t('shared_with_me')} · ${cal.shared_by || ''}`, remove: null });
}); });
// Group calendars (owned by the creator or reached via membership) — shown so // Group calendars (owned by the creator or reached via membership) — shown so
// they can be toggled/recoloured; marked with the group emoji. // they can be toggled/recoloured. Owned group calendars can also be muted
// (reminders), which the server then syncs; member-reached ones can't (no PUT).
state.localCalendars.filter(c => c.group).forEach(cal => { state.localCalendars.filter(c => c.group).forEach(cal => {
entries.push({ key: `local:${cal.id}`, source: 'local', dataId: `data-cal-id="${cal.id}"`, entries.push({ key: `local:${cal.id}`, source: 'local', dataId: `data-cal-id="${cal.id}"`,
name: cal.name, color: cal.color, enabled: cal.enabled, name: cal.name, color: cal.color, enabled: cal.enabled,
reminders: cal.owned !== false, remindersEnabled: cal.reminders_enabled !== false,
sourceLabel: `${t('groups_title')} · ${cal.shared_by || ''}`, isGroupCal: true, remove: null }); sourceLabel: `${t('groups_title')} · ${cal.shared_by || ''}`, isGroupCal: true, remove: null });
}); });
state.icalSubscriptions.forEach(sub => { state.icalSubscriptions.forEach(sub => {
@@ -1718,13 +1720,14 @@ function resetColorPicker(color) {
} }
// ── Reminders (local events only) ───────────────────────── // ── Reminders (local events only) ─────────────────────────
const REMINDER_OPTIONS = [0, 5, 10, 15, 30, 60, 120, 1440, 2880]; const REMINDER_OPTIONS = [0, 5, 15, 30, 60, 1440, 10080];
function reminderLabel(min) { function reminderLabel(min) {
if (min <= 0) return t('reminder_at_start'); if (min <= 0) return t('reminder_at_start');
if (min < 60) return t('reminder_min', { n: min }); if (min < 60) return t('reminder_minutes', { n: min });
if (min < 1440) return t('reminder_hour', { n: min / 60 }); if (min < 1440) { const h = min / 60; return h === 1 ? t('reminder_hour_one') : t('reminder_hours', { n: h }); }
return t('reminder_day', { n: min / 1440 }); if (min < 10080) { const d = min / 1440; return d === 1 ? t('reminder_day_one') : t('reminder_days', { n: d }); }
const w = min / 10080; return w === 1 ? t('reminder_week_one') : t('reminder_weeks', { n: w });
} }
function setEventReminders(arr) { function setEventReminders(arr) {

View File

@@ -97,9 +97,13 @@ const translations = {
reminders: 'Benachrichtigungen', reminders: 'Benachrichtigungen',
reminder_add: 'Benachrichtigung hinzufügen', reminder_add: 'Benachrichtigung hinzufügen',
reminder_at_start: 'Zur Startzeit', reminder_at_start: 'Zur Startzeit',
reminder_min: 'vor {n} Min.', reminder_minutes: '{n} Minuten vorher',
reminder_hour: 'vor {n} Std.', reminder_hour_one: '1 Stunde vorher',
reminder_day: 'vor {n} Tag(en)', reminder_hours: '{n} Stunden vorher',
reminder_day_one: '1 Tag vorher',
reminder_days: '{n} Tage vorher',
reminder_week_one: '1 Woche vorher',
reminder_weeks: '{n} Wochen vorher',
calendar_reminders_on: 'Benachrichtigungen aktiviert', calendar_reminders_on: 'Benachrichtigungen aktiviert',
calendar_reminders_off: 'Benachrichtigungen deaktiviert', calendar_reminders_off: 'Benachrichtigungen deaktiviert',
share: 'Teilen', share: 'Teilen',
@@ -378,9 +382,13 @@ const translations = {
reminders: 'Reminders', reminders: 'Reminders',
reminder_add: 'Add reminder', reminder_add: 'Add reminder',
reminder_at_start: 'At start time', reminder_at_start: 'At start time',
reminder_min: '{n} min before', reminder_minutes: '{n} minutes before',
reminder_hour: '{n} h before', reminder_hour_one: '1 hour before',
reminder_day: '{n} day(s) before', reminder_hours: '{n} hours before',
reminder_day_one: '1 day before',
reminder_days: '{n} days before',
reminder_week_one: '1 week before',
reminder_weeks: '{n} weeks before',
calendar_reminders_on: 'Reminders enabled', calendar_reminders_on: 'Reminders enabled',
calendar_reminders_off: 'Reminders disabled', calendar_reminders_off: 'Reminders disabled',
share: 'Share', share: 'Share',

View File

@@ -1,2 +1,2 @@
// Increment APP_VERSION with every code change // Increment APP_VERSION with every code change
export const APP_VERSION = 'v45'; export const APP_VERSION = 'v46';