feat(calendar): P1 разворот повторений — CalendarRecurrence (RRULE-оккуренции на лету) + eventOccursOnDay RRULE-осознан +11 тестов; refresh detekt-baseline (v0.5.144-долг)

This commit is contained in:
b-mob-calendar
2026-07-13 07:36:19 +00:00
parent 1c1e9c89e2
commit e7d0a5a9ee
6 changed files with 442 additions and 94 deletions
+161 -81
View File
@@ -12,88 +12,124 @@
<ID>ArgumentListWrapping:CalendarComponents.kt$(12.dp)</ID>
<ID>ArgumentListWrapping:CalendarComponents.kt$(cal.accountName, style = MaterialTheme.typography.labelSmall, color = F7Colors.TextMuted)</ID>
<ID>ArgumentListWrapping:CalendarComponents.kt$(event.location, style = MaterialTheme.typography.labelSmall, color = F7Colors.TextMuted, maxLines = 1)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( "#0082C9", "#7CBC3D", "#E9322D", "#F1DB50", "#795AAB", "#E97D30", "#00C7B4", )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( attendee.displayName.ifBlank { attendee.email }, color = F7Colors.TextPrimary, fontSize = 14.sp, fontWeight = FontWeight.SemiBold, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( context, { _, hh, mm -&gt; onPick("%02d:%02d".format(hh, mm)) }, h, mi, true, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( context, { _, y, m, d -&gt; onPick(LocalDate.of(y, m + 1, d)) }, current.year, current.monthValue - 1, current.dayOfMonth, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( context, { _, y, m, d -&gt; rule = rule.copy(untilDate = LocalDate.of(y, m + 1, d)) }, until.year, until.monthValue - 1, until.dayOfMonth, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( draft.date.format(DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.forLanguageTag("ru"))), color = F7Colors.TextSecondary, fontSize = 13.sp, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( if (draft.attachments.isEmpty()) "Нет ни одного вложения" else "Вложений: ${draft.attachments.size}", color = EVENT_TEXT, fontSize = 14.sp, modifier = Modifier.weight(1f), )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( sharee.displayName + if (sharee.writable) " (редактирование)" else " (чтение)", color = F7Colors.TextPrimary, fontSize = 14.sp, modifier = Modifier.weight(1f), maxLines = 1, overflow = TextOverflow.Ellipsis, )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$( when (rule.endType) { RecurrenceRule.EndType.NEVER -&gt; "Никогда" RecurrenceRule.EndType.UNTIL -&gt; "До даты" RecurrenceRule.EndType.COUNT -&gt; "После N повторений" }, color = EVENT_TEXT, fontSize = 14.sp, modifier = Modifier.weight(1f), )</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("$count событ.", style = MaterialTheme.typography.labelSmall, color = F7Colors.TextSecondary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("${s.name} · ${s.email}", modifier = Modifier.clickable { onAddAttendee(s) }.padding(start = 8.dp), color = F7Colors.Primary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("/${path}", color = F7Colors.TextSecondary, fontSize = 13.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("ru")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Весь день")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Комната Talk")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Выберите беседу", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Выберите файл", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("До даты")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Загрузка…", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Занятость участников", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Или создать новую беседу", color = F7Colors.TextPrimary, fontSize = 14.sp, fontWeight = FontWeight.SemiBold)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Корзина пуста", color = F7Colors.TextSecondary, modifier = Modifier.padding(top = 12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Настройки календаря", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Нет доступных бесед", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Нет задач без срока", color = F7Colors.TextSecondary, modifier = Modifier.padding(top = 12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Никогда")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Отмена", color = F7Colors.TextSecondary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Папка пуста", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Повторять событие", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("После N повторений")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$("Удалить календарь и все его события?", color = F7Colors.TextPrimary, fontSize = 14.sp, fontWeight = FontWeight.SemiBold)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$('/')</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$('/', "")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(10.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(12.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(16.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(8.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.clickable { onDraftChange(draft.copy(calendarHref = cal.href)) }, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.clickable { onDraftChange(draft.copy(classification = cl)) }, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.clickable { onDraftChange(draft.copy(recurrence = preset, customRrule = "")) }, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.clickable { onDraftChange(draft.copy(status = st)) }, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(18.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(1f)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(2.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(24.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(28.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(3.dp, F7Colors.TextPrimary, CircleShape)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(32.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(CircleShape)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(F7Colors.Primary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(F7Colors.PrimaryLight)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Add, contentDescription = "Добавить вложение", tint = EVENT_PLACEHOLDER, modifier = Modifier.size(18.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Close, contentDescription = "Убрать доступ", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Close, contentDescription = "Удалить напоминание", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Close, contentDescription = "Удалить", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.InsertDriveFile, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.KeyboardArrowDown, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Link, contentDescription = null, tint = F7Colors.Primary, modifier = Modifier.size(18.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Icons.Default.Notifications, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.fillMaxWidth().clickable { onDraftChange(draft.copy(mode = mode)) }, verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.fillMaxWidth().heightIn(max = 520.dp).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(8.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.padding(16.dp).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(10.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(addTalkRoom = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(allDay = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(calendarHref = cal.href)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(categories = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(checked = draft.addTalkRoom, onCheckedChange = { onDraftChange(draft.copy(addTalkRoom = it)) })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(checked = draft.allDay, onCheckedChange = { onDraftChange(draft.copy(allDay = it)) })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(classification = cl)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(description = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(addTalkRoom = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(allDay = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(calendarHref = cal.href))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(categories = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(classification = cl))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(description = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.padding(horizontal = 16.dp, vertical = 14.dp), verticalArrangement = Arrangement.spacedBy(12.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.size(24.dp).clip(CircleShape).background(F7Colors.Primary), contentAlignment = Alignment.Center)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.size(32.dp).clip(CircleShape).background(F7Colors.PrimaryLight), contentAlignment = Alignment.Center)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(Modifier.weight(1f).verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(2.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(allDay = !draft.allDay)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(att.fileName.ifBlank { att.url.substringAfterLast('/') }, color = F7Colors.TextPrimary, fontSize = 13.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(calendarName, color = EVENT_TEXT, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(allDay = !draft.allDay))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(endDate = picked.coerceAtLeast(draft.date).takeIf { it != draft.date }))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(endTime = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(mode = mode))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(name = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(recurrence = preset))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(recurrence = preset, customRrule = ""))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(reminderMinutes = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(recurrence = RecurrencePreset.NONE, customRrule = rule.toRrule()))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(reminders = draft.reminders - min))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(startTime = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(status = st))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(subscriptionUrl = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.copy(title = it))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.date)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.endTime)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(draft.startTime)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(endDate = picked.coerceAtLeast(draft.date).takeIf { it != draft.date })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(endTime = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(entry.name, color = F7Colors.TextPrimary, fontSize = 15.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(freqLabel(rule.freq, rule.interval), color = EVENT_TEXT, fontSize = 14.sp, modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(horizontal = 16.dp, vertical = 14.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(icon = Icons.Default.Schedule, modifier = Modifier.weight(1f), onClick = { pickTime(draft.endTime) { onDraftChange(draft.copy(endTime = it)) } })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(icon = Icons.Default.Schedule, modifier = Modifier.weight(1f), onClick = { pickTime(draft.startTime) { onDraftChange(draft.copy(startTime = it)) } })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(if (month == YearMonth.from(selectedDay)) F7Colors.PrimaryLight else F7Colors.Surface)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(if (state.deleting) "Удаление…" else "Удалить", color = F7Colors.Error)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(if (selected) Modifier.border(3.dp, F7Colors.TextPrimary, CircleShape) else Modifier)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(java.time.format.TextStyle.FULL_STANDALONE, java.util.Locale.forLanguageTag("ru"))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(max = 520.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(label, color = EVENT_TEXT, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(min)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(mode = mode)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(month.month.getDisplayName(java.time.format.TextStyle.FULL_STANDALONE, java.util.Locale.forLanguageTag("ru")), style = MaterialTheme.typography.labelLarge, fontWeight = FontWeight.SemiBold)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(name = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(onClick = onDelete, enabled = !state.deleting)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(recurrence = preset)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(recurrence = preset, customRrule = "")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(onClick = { confirmDelete = false })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(onClick = { onDraftChange(draft.copy(reminders = draft.reminders - min)) }, modifier = Modifier.size(24.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(onClick = { onNavigate(path.substringBeforeLast('/', "")) }, modifier = Modifier.size(28.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(path.substringBeforeLast('/', ""))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(recurrence = RecurrencePreset.NONE, customRrule = rule.toRrule())</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(rememberScrollState())</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(reminderMinutes = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(s)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(s.address.ifBlank { s.name }, modifier = Modifier.clickable { onApplyLocation(s) }.padding(start = 8.dp), color = F7Colors.Primary)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(selected = draft.calendarHref == cal.href, onClick = { onDraftChange(draft.copy(calendarHref = cal.href)) })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(selected = draft.classification == cl, onClick = { onDraftChange(draft.copy(classification = cl)) })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(selected = draft.recurrence == preset, onClick = { onDraftChange(draft.copy(recurrence = preset)) })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(start = 8.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(reminderLabelFor(min), color = F7Colors.TextPrimary, fontSize = 13.sp, modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(reminders = draft.reminders - min)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(room.displayName, color = F7Colors.TextPrimary, fontSize = 15.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(rule.freq, rule.interval)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(startTime = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(status = st)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(subscriptionUrl = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(text = if (saving) "Сохранение…" else "Создать", onClick = onSave, enabled = !saving)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(text = if (state.saving) "Сохранение…" else "Сохранить", onClick = onSave, enabled = !state.saving)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(title = it)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(text = { Text("До даты") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.UNTIL, untilDate = rule.untilDate ?: LocalDate.now().plusMonths(1)); endMenu = false })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(text = { Text("Никогда") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.NEVER); endMenu = false })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(text = { Text("После N повторений") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.COUNT); endMenu = false })</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(top = 12.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.attendeeQuery, onValueChange = onSearchAttendees, label = "Поиск участника")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.categories, onValueChange = { onDraftChange(draft.copy(categories = it)) }, label = "Категории")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.description, onValueChange = { onDraftChange(draft.copy(description = it)) }, label = "Описание")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.endTime, onValueChange = { onDraftChange(draft.copy(endTime = it)) }, label = "Окончание")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.name, onValueChange = { onDraftChange(draft.copy(name = it)) }, label = "Название")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.reminderMinutes.toString(), onValueChange = { v -&gt; v.toIntOrNull()?.let { onDraftChange(draft.copy(reminderMinutes = it)) } }, label = "Напоминание (мин)")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.startTime, onValueChange = { onDraftChange(draft.copy(startTime = it)) }, label = "Начало")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.subscriptionUrl, onValueChange = { onDraftChange(draft.copy(subscriptionUrl = it)) }, label = "URL подписки (WebCal)")</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = draft.title, onValueChange = { onDraftChange(draft.copy(title = it)) }, label = "Название")</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$("MMM d", Locale.ENGLISH)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$("MMM d, yyyy", Locale.ENGLISH)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(value = name, onValueChange = { name = it }, placeholder = "Название календаря", modifier = Modifier.weight(1f))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(vertical = 12.dp)</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp))</ID>
<ID>ArgumentListWrapping:CalendarExtendedUi.kt$(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clickable { onDraftChange(draft.copy(allDay = !draft.allDay)) })</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$("d MMM yyyy", RU)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$("d MMM", RU)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$("dd.MM.yyyy HH:mm")</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(DateTimeFormatter.ofPattern("MMM d", Locale.ENGLISH))</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(DateTimeFormatter.ofPattern("MMM d, yyyy", Locale.ENGLISH))</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(DateTimeFormatter.ofPattern("d MMM yyyy", RU))</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(DateTimeFormatter.ofPattern("d MMM", RU))</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(ZoneId.systemDefault())</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(epoch)</ID>
@@ -102,35 +138,62 @@
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(st.visibleYear, 1, 1)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(st.visibleYear, 12, 31)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(start)</ID>
<ID>ArgumentListWrapping:CalendarViewModel.kt$CalendarViewModel$(talkRoomUrl = room.callUrl, addTalkRoom = false, location = it.location.ifBlank { room.callUrl })</ID>
<ID>ArgumentListWrapping:RecurrenceRule.kt$RecurrenceRule.Companion$( "MO" to "Пн", "TU" to "Вт", "WE" to "Ср", "TH" to "Чт", "FR" to "Пт", "SA" to "Сб", "SU" to "Вс", )</ID>
<ID>ArgumentListWrapping:RecurrenceRule.kt$RecurrenceRule.Companion$("dd.MM.yyyy")</ID>
<ID>ArgumentListWrapping:RecurrenceRule.kt$RecurrenceRule.Companion$(DateTimeFormatter.ofPattern("dd.MM.yyyy"))</ID>
<ID>CyclomaticComplexMethod:CalendarExtendedUi.kt$@Composable fun CalendarFullEventEditorDialog( state: CalendarUiState, onDismiss: () -&gt; Unit, onDraftChange: (CalendarEventDraft) -&gt; Unit, onSave: () -&gt; Unit, onDelete: () -&gt; Unit, onSearchAttendees: (String) -&gt; Unit, onAddAttendee: (CalendarAttendeeSuggestion) -&gt; Unit, onRemoveAttendee: (String) -&gt; Unit, onSearchLocations: (String) -&gt; Unit, onApplyLocation: (CalendarLocationSuggestion) -&gt; Unit, onOpenTalkPicker: () -&gt; Unit = {}, onPickDeviceAttachment: () -&gt; Unit = {}, onPickFilesAttachment: () -&gt; Unit = {}, onRemoveAttachment: (String) -&gt; Unit = {}, onOpenFreeBusy: () -&gt; Unit = {}, )</ID>
<ID>CyclomaticComplexMethod:CalendarScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun CalendarScreen( session: AuthSession, modifier: Modifier = Modifier, focusEventUid: String? = null, settingsRequest: Int = 0, sidebarOpen: Boolean = false, onSidebarOpenChange: (Boolean) -&gt; Unit = {}, onFocusEventConsumed: () -&gt; Unit = {}, onUnauthorized: () -&gt; Unit = {}, )</ID>
<ID>CyclomaticComplexMethod:CalendarSyncEngine.kt$CalendarSyncEngine$fun run( session: AuthSession, deviceCalendarId: Long, ): CalendarSyncResult</ID>
<ID>ForEachOnRange:CalendarComponents.kt$0..23</ID>
<ID>ForEachOnRange:CalendarComponents.kt$0..24</ID>
<ID>ImportOrdering:CalendarComponents.kt$import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.DatePicker import androidx.compose.material3.DatePickerDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberDatePickerState import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.offset import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.sp import java.time.LocalTime import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.designsystem.F7Colors import ru.forbion.f7cloud.core.designsystem.F7ListCard import ru.forbion.f7cloud.core.designsystem.F7OutlinedField import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton import ru.forbion.f7cloud.core.designsystem.F7TextButton import java.time.Instant import java.time.LocalDate import java.time.YearMonth import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Locale</ID>
<ID>ImportOrdering:CalendarRepository.kt$import okhttp3.OkHttpClient import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.auth.OcsUserResolver import ru.forbion.f7cloud.core.network.CalendarAlarmData import ru.forbion.f7cloud.core.network.CalendarAttendeeData import ru.forbion.f7cloud.core.network.CalendarEventData import ru.forbion.f7cloud.core.network.CalendarIcs import ru.forbion.f7cloud.core.network.CalDavClient import ru.forbion.f7cloud.core.network.DavCalendar import ru.forbion.f7cloud.core.network.DavEvent import ru.forbion.f7cloud.core.network.DavTask import ru.forbion.f7cloud.core.network.DavTrashEvent import ru.forbion.f7cloud.core.network.NetworkFactory import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime import java.time.YearMonth import java.time.ZoneId import java.time.ZoneOffset</ID>
<ID>ImportOrdering:CalendarComponents.kt$import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.offset import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.sp import java.time.LocalTime import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.designsystem.F7Colors import ru.forbion.f7cloud.core.designsystem.F7ListCard import ru.forbion.f7cloud.core.designsystem.F7OutlinedField import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton import ru.forbion.f7cloud.core.designsystem.F7TextButton import java.time.Instant import java.time.LocalDate import java.time.YearMonth import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Locale</ID>
<ID>ImportOrdering:CalendarExtendedUi.kt$import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.AttachFile import androidx.compose.material.icons.filled.Autorenew import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.DateRange import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Folder import androidx.compose.material.icons.filled.InsertDriveFile import androidx.compose.material.icons.filled.Upload import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.filled.Link import androidx.compose.material.icons.filled.LocalOffer import androidx.compose.material.icons.filled.Notes import androidx.compose.material.icons.filled.Notifications import androidx.compose.material.icons.filled.Place import androidx.compose.material.icons.filled.Public import androidx.compose.material.icons.filled.Schedule import androidx.compose.material.icons.filled.Visibility import androidx.compose.material3.AlertDialog import androidx.compose.material3.Checkbox import androidx.compose.material3.CheckboxDefaults import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.RadioButton import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import ru.forbion.f7cloud.core.designsystem.F7Colors import ru.forbion.f7cloud.core.designsystem.F7OutlinedField import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton import ru.forbion.f7cloud.core.designsystem.F7TextButton import java.time.LocalDate import java.time.YearMonth import java.time.format.DateTimeFormatter import java.util.Locale</ID>
<ID>ImportOrdering:CalendarRepository.kt$import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.RequestBody.Companion.toRequestBody import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.auth.OcsUserResolver import ru.forbion.f7cloud.core.network.CalendarAlarmData import ru.forbion.f7cloud.core.network.CalendarAttachmentData import ru.forbion.f7cloud.core.network.CalendarAttendeeData import ru.forbion.f7cloud.core.network.CalendarEventData import ru.forbion.f7cloud.core.network.CalendarIcs import ru.forbion.f7cloud.core.network.CalDavClient import ru.forbion.f7cloud.core.network.DavCalendar import ru.forbion.f7cloud.core.network.DavClient import ru.forbion.f7cloud.core.network.DavEvent import ru.forbion.f7cloud.core.network.DavTask import ru.forbion.f7cloud.core.network.DavTrashEvent import ru.forbion.f7cloud.core.network.NetworkFactory import ru.forbion.f7cloud.core.network.davFileUrl import ru.forbion.f7cloud.core.network.davFolderUrl import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime import java.time.YearMonth import java.time.ZoneId import java.time.ZoneOffset</ID>
<ID>ImportOrdering:CalendarScreen.kt$import android.Manifest import android.content.pm.PackageManager import android.net.Uri import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Arrangement import androidx.compose.material3.DrawerValue import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalDrawerSheet import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.rememberDrawerState import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.snapshotFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.lifecycle.viewmodel.compose.viewModel import kotlinx.coroutines.delay import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.designsystem.F7Colors import ru.forbion.f7cloud.core.designsystem.F7ModuleScreen import ru.forbion.f7cloud.core.designsystem.F7OverlayDismissHandler import java.time.format.DateTimeFormatter import java.util.Locale</ID>
<ID>Indentation:CalendarScreen.kt$ </ID>
<ID>LargeClass:CalendarViewModel.kt$CalendarViewModel : ViewModel</ID>
<ID>LongMethod:CalendarComponents.kt$@Composable fun CalendarDayTimeline( session: AuthSession, day: LocalDate, events: List&lt;CalendarEventItem&gt;, viewMode: CalendarViewMode, onViewMode: (CalendarViewMode) -&gt; Unit, onEventClick: (CalendarEventItem) -&gt; Unit, modifier: Modifier = Modifier, )</ID>
<ID>LongMethod:CalendarExtendedUi.kt$@Composable fun CalendarFullEventEditorDialog( state: CalendarUiState, onDismiss: () -&gt; Unit, onDraftChange: (CalendarEventDraft) -&gt; Unit, onSave: () -&gt; Unit, onDelete: () -&gt; Unit, onSearchAttendees: (String) -&gt; Unit, onAddAttendee: (CalendarAttendeeSuggestion) -&gt; Unit, onRemoveAttendee: (String) -&gt; Unit, onSearchLocations: (String) -&gt; Unit, onApplyLocation: (CalendarLocationSuggestion) -&gt; Unit, onOpenTalkPicker: () -&gt; Unit = {}, onPickDeviceAttachment: () -&gt; Unit = {}, onPickFilesAttachment: () -&gt; Unit = {}, onRemoveAttachment: (String) -&gt; Unit = {}, onOpenFreeBusy: () -&gt; Unit = {}, )</ID>
<ID>LongMethod:CalendarExtendedUi.kt$@Composable fun CalendarRepeatModal( initial: RecurrenceRule, onDismiss: () -&gt; Unit, onApply: (RecurrenceRule) -&gt; Unit, onClear: () -&gt; Unit, )</ID>
<ID>LongMethod:CalendarScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun CalendarScreen( session: AuthSession, modifier: Modifier = Modifier, focusEventUid: String? = null, settingsRequest: Int = 0, sidebarOpen: Boolean = false, onSidebarOpenChange: (Boolean) -&gt; Unit = {}, onFocusEventConsumed: () -&gt; Unit = {}, onUnauthorized: () -&gt; Unit = {}, )</ID>
<ID>LongMethod:CalendarSyncEngine.kt$CalendarSyncEngine$fun run( session: AuthSession, deviceCalendarId: Long, ): CalendarSyncResult</ID>
<ID>LoopWithTooManyJumpStatements:CalendarApiClient.kt$CalendarApiClient$for</ID>
<ID>LoopWithTooManyJumpStatements:CalendarSyncEngine.kt$CalendarSyncEngine$for</ID>
<ID>MaxLineLength:CalendarApiClient.kt$CalendarApiClient$val url = "${session.serverUrl.trimEnd('/')}/index.php/apps/calendar/v1/autocompletion/location?search=${java.net.URLEncoder.encode(query.trim(), Charsets.UTF_8.name())}"</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Column</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$F7OutlinedField(value = draft.categories, onValueChange = { onDraftChange(draft.copy(categories = it)) }, label = "Категории")</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$F7OutlinedField(value = draft.description, onValueChange = { onDraftChange(draft.copy(description = it)) }, label = "Описание")</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$F7OutlinedField(value = draft.reminderMinutes.toString(), onValueChange = { v -&gt; v.toIntOrNull()?.let { onDraftChange(draft.copy(reminderMinutes = it)) } }, label = "Напоминание (мин)")</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$F7OutlinedField(value = draft.startTime, onValueChange = { onDraftChange(draft.copy(startTime = it)) }, label = "Начало")</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Box</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$DropdownMenuItem(text = { Text("До даты") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.UNTIL, untilDate = rule.untilDate ?: LocalDate.now().plusMonths(1)); endMenu = false })</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$DropdownMenuItem(text = { Text("Никогда") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.NEVER); endMenu = false })</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$DropdownMenuItem(text = { Text("После N повторений") }, onClick = { rule = rule.copy(endType = RecurrenceRule.EndType.COUNT); endMenu = false })</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$EventInput(value = name, onValueChange = { name = it }, placeholder = "Название календаря", modifier = Modifier.weight(1f))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$EventPill</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$F7OutlinedField(value = draft.subscriptionUrl, onValueChange = { onDraftChange(draft.copy(subscriptionUrl = it)) }, label = "URL подписки (WebCal)")</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$RadioButton(selected = draft.calendarHref == cal.href, onClick = { onDraftChange(draft.copy(calendarHref = cal.href)) })</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Add, contentDescription = "Добавить вложение", tint = EVENT_PLACEHOLDER, modifier = Modifier.size(18.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Close, contentDescription = "Убрать доступ", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Close, contentDescription = "Удалить напоминание", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Close, contentDescription = "Удалить", tint = F7Colors.TextSecondary, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.InsertDriveFile, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.KeyboardArrowDown, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Link, contentDescription = null, tint = F7Colors.Primary, modifier = Modifier.size(18.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Icon(Icons.Default.Notifications, contentDescription = null, tint = EVENT_PLACEHOLDER, modifier = Modifier.size(16.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$IconButton</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Row</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("${s.name} · ${s.email}", modifier = Modifier.clickable { onAddAttendee(s) }.padding(start = 8.dp), color = F7Colors.Primary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Комната Talk"); Switch(checked = draft.addTalkRoom, onCheckedChange = { onDraftChange(draft.copy(addTalkRoom = it)) })</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Выберите беседу", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Выберите файл", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Занятость участников", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Настройки календаря", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Повторять событие", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = F7Colors.TextPrimary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text("Удалить календарь и все его события?", color = F7Colors.TextPrimary, fontSize = 14.sp, fontWeight = FontWeight.SemiBold)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(att.fileName.ifBlank { att.url.substringAfterLast('/') }, color = F7Colors.TextPrimary, fontSize = 13.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(calendarName, color = EVENT_TEXT, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(entry.name, color = F7Colors.TextPrimary, fontSize = 15.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(label, color = EVENT_TEXT, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(month.month.getDisplayName(java.time.format.TextStyle.FULL_STANDALONE, java.util.Locale.forLanguageTag("ru")), style = MaterialTheme.typography.labelLarge, fontWeight = FontWeight.SemiBold)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(s.address.ifBlank { s.name }, modifier = Modifier.clickable { onApplyLocation(s) }.padding(start = 8.dp), color = F7Colors.Primary)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$confirmButton = { F7PrimaryButton(text = if (state.saving) "Сохранение…" else "Сохранить", onClick = onSave, enabled = !state.saving) }</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$if (isEdit) TextButton(onClick = onDelete, enabled = !state.deleting) { Text(if (state.deleting) "Удаление…" else "Удалить", color = F7Colors.Error) }</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$"${start.format(DateTimeFormatter.ofPattern("MMM d", Locale.ENGLISH))} ${end.format(DateTimeFormatter.ofPattern("MMM d, yyyy", Locale.ENGLISH))}"</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$Text(room.displayName, color = F7Colors.TextPrimary, fontSize = 15.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$state.filesPickerEntries.isEmpty() -&gt; Text("Папка пуста", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$state.filesPickerLoading -&gt; Text("Загрузка…", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$state.talkPickerLoading -&gt; Text("Загрузка…", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>MaxLineLength:CalendarExtendedUi.kt$state.talkRooms.isEmpty() -&gt; Text("Нет доступных бесед", color = F7Colors.TextSecondary, fontSize = 14.sp, modifier = Modifier.padding(vertical = 12.dp))</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$.</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$CalendarViewMode.DAY -&gt; st.copy(selectedDay = st.selectedDay.minusDays(1), visibleMonth = YearMonth.from(st.selectedDay.minusDays(1)))</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$CalendarViewMode.DAY -&gt; st.copy(selectedDay = st.selectedDay.plusDays(1), visibleMonth = YearMonth.from(st.selectedDay.plusDays(1)))</ID>
@@ -142,17 +205,27 @@
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$CalendarViewMode.WEEK -&gt; st.copy(selectedDay = st.selectedDay.plusWeeks(1), visibleMonth = YearMonth.from(st.selectedDay.plusWeeks(1)))</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$CalendarViewMode.YEAR -&gt; repository.loadRange(session, LocalDate.of(st.visibleYear, 1, 1), LocalDate.of(st.visibleYear, 12, 31), visibleCalendarHrefs)</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(deleting = false, createDialogOpen = false, eventDetail = null, focusedEventUid = null, snackMessage = "Удалено")</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(editCalendarBusy = false, editCalendarOpen = false, editCalendarTarget = null, snackMessage = "Календарь обновлён")</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(editCalendarBusy = false, editCalendarOpen = false, editCalendarTarget = null, snackMessage = "Календарь удалён")</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(selectedDay = day, visibleMonth = YearMonth.from(day), eventDetail = event, focusedEventUid = event.uid)</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(selectedDay = day, visibleMonth = YearMonth.from(day), visibleYear = day.year, datePickerOpen = false)</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$classification = EventClassification.entries.firstOrNull { it.icsValue == event.classification } ?: EventClassification.PUBLIC</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$private fun formatLastSync(epoch: Long)</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$return if (visible.isEmpty()) _state.value.events else _state.value.events.filter { it.calendarHref in visible || it.calendarHref.isBlank() }</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$snackMessage = if (showSnack) "Синхронизация завершена (${result.pushedToDevice + result.pushedToServer + result.updated + result.linked})" else _state.value.snackMessage</ID>
<ID>MaxLineLength:CalendarViewModel.kt$CalendarViewModel$updateEventDraft { it.copy(talkRoomUrl = room.callUrl, addTalkRoom = false, location = it.location.ifBlank { room.callUrl }) }</ID>
<ID>MaximumLineLength:CalendarApiClient.kt$CalendarApiClient$ </ID>
<ID>MaximumLineLength:CalendarComponents.kt$ </ID>
<ID>MaximumLineLength:CalendarExtendedUi.kt$ </ID>
<ID>MaximumLineLength:CalendarRepository.kt$CalendarRepository$ </ID>
<ID>MaximumLineLength:CalendarViewModel.kt$CalendarViewModel$ </ID>
<ID>MaximumLineLength:RecurrenceRule.kt$RecurrenceRule.Companion$ </ID>
<ID>MultiLineIfElse:CalendarExtendedUi.kt$draft.date.atStartOfDay(zone).toInstant().toEpochMilli()</ID>
<ID>MultiLineIfElse:CalendarExtendedUi.kt$draft.date.atTime( draft.startTime.substringBefore(':').toIntOrNull() ?: 10, draft.startTime.substringAfter(':').toIntOrNull() ?: 0, ).atZone(zone).toInstant().toEpochMilli()</ID>
<ID>MultiLineIfElse:CalendarExtendedUi.kt$endDay.atTime( draft.endTime.substringBefore(':').toIntOrNull() ?: 11, draft.endTime.substringAfter(':').toIntOrNull() ?: 0, ).atZone(zone).toInstant().toEpochMilli()</ID>
<ID>MultiLineIfElse:CalendarExtendedUi.kt$endDay.plusDays(1).atStartOfDay(zone).toInstant().toEpochMilli()</ID>
<ID>MultiLineIfElse:RecurrenceRule.kt$RecurrenceRule.Companion$""</ID>
<ID>NestedBlockDepth:CalendarApiClient.kt$CalendarApiClient$fun searchSharees(session: AuthSession, query: String): List&lt;CalendarShareeSuggestion&gt;</ID>
<ID>NoMultipleSpaces:CalendarSyncEngine.kt$CalendarSyncEngine.Companion$ </ID>
<ID>NoUnusedImports:CalendarApiClient.kt$ru.forbion.f7cloud.feature.calendar.CalendarApiClient.kt</ID>
<ID>NoUnusedImports:CalendarComponents.kt$ru.forbion.f7cloud.feature.calendar.CalendarComponents.kt</ID>
@@ -162,34 +235,41 @@
<ID>NoUnusedImports:CalendarSyncEngine.kt$ru.forbion.f7cloud.feature.calendar.CalendarSyncEngine.kt</ID>
<ID>NoUnusedImports:DeviceCalendarClient.kt$ru.forbion.f7cloud.feature.calendar.DeviceCalendarClient.kt</ID>
<ID>ParameterListWrapping:CalendarViewModel.kt$CalendarViewModel$(draft: CalendarCreateBookDraft)</ID>
<ID>StringTemplate:CalendarExtendedUi.kt$${path}</ID>
<ID>UnusedPrivateMember:CalendarComponents.kt$@Composable private fun CalendarIconButton( iconUrl: String, contentDescription: String?, onClick: () -&gt; Unit, )</ID>
<ID>UnusedPrivateMember:CalendarComponents.kt$@Composable private fun CalendarNavButton(text: String, onClick: () -&gt; Unit)</ID>
<ID>UnusedPrivateProperty:CalendarComponents.kt$private val toolbarDateFormatter = DateTimeFormatter.ofPattern("MMM d, yyyy", Locale.ENGLISH)</ID>
<ID>UnusedPrivateProperty:CalendarSyncEngine.kt$CalendarSyncEngine$val mappedDevIds2 = mappings.map { it.deviceEventId }.toSet()</ID>
<ID>UseCheckOrError:CalendarRepository.kt$CalendarRepository$throw IllegalStateException("Календари не найдены")</ID>
<ID>UseCheckOrError:CalendarRepository.kt$CalendarRepository$throw IllegalStateException("Не удалось загрузить события календаря: $lastError")</ID>
<ID>Wrapping:CalendarComponents.kt$;</ID>
<ID>Wrapping:CalendarExtendedUi.kt$;</ID>
<ID>Wrapping:CalendarExtendedUi.kt$F7PrimaryButton(text = if (saving) "Сохранение…" else "Создать", onClick = onSave, enabled = !saving)</ID>
<ID>Wrapping:CalendarExtendedUi.kt$F7PrimaryButton(text = if (state.saving) "Сохранение…" else "Сохранить", onClick = onSave, enabled = !state.saving)</ID>
<ID>Wrapping:CalendarExtendedUi.kt$Text(if (state.deleting) "Удаление…" else "Удалить", color = F7Colors.Error)</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onAddAttendee(s)</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onApplyLocation(s)</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(addTalkRoom = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(calendarHref = cal.href))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(categories = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(classification = cl))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(description = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$Text("До даты")</ID>
<ID>Wrapping:CalendarExtendedUi.kt$Text("Никогда")</ID>
<ID>Wrapping:CalendarExtendedUi.kt$Text("После N повторений")</ID>
<ID>Wrapping:CalendarExtendedUi.kt$att.url.substringAfterLast('/')</ID>
<ID>Wrapping:CalendarExtendedUi.kt$name = it</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(allDay = !draft.allDay))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(endTime = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(mode = mode))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(recurrence = preset, customRrule = ""))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(reminderMinutes = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(reminders = draft.reminders - min))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(startTime = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$onDraftChange(draft.copy(subscriptionUrl = it))</ID>
<ID>Wrapping:CalendarExtendedUi.kt$s.name</ID>
<ID>Wrapping:CalendarExtendedUi.kt$pickTime(draft.endTime) { onDraftChange(draft.copy(endTime = it)) }</ID>
<ID>Wrapping:CalendarExtendedUi.kt$pickTime(draft.startTime) { onDraftChange(draft.copy(startTime = it)) }</ID>
<ID>Wrapping:CalendarExtendedUi.kt$rule = rule.copy(endType = RecurrenceRule.EndType.COUNT); endMenu = false</ID>
<ID>Wrapping:CalendarExtendedUi.kt$rule = rule.copy(endType = RecurrenceRule.EndType.NEVER); endMenu = false</ID>
<ID>Wrapping:CalendarExtendedUi.kt$rule = rule.copy(endType = RecurrenceRule.EndType.UNTIL, untilDate = rule.untilDate ?: LocalDate.now().plusMonths(1)); endMenu = false</ID>
<ID>Wrapping:CalendarRepository.kt$CalendarRepository$;</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$;</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(attachmentUploading = false, snackMessage = "Ошибка загрузки: ${it.message}")</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(editCalendarBusy = false, snackMessage = "Не удалось обновить: ${it.message}")</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(editCalendarBusy = false, snackMessage = "Не удалось удалить: ${it.message}")</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$_state.value = _state.value.copy(loading = false, error = it.message, unauthorized = it is UnauthorizedException)</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$it.calendarHref in visible || it.calendarHref.isBlank()</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$it.copy(talkRoomUrl = room.callUrl, addTalkRoom = false, location = it.location.ifBlank { room.callUrl })</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$it.icsValue == event.classification</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel$room.callUrl</ID>
<ID>Wrapping:CalendarViewModel.kt$CalendarViewModel${ _state.value = _state.value.copy(createBookOpen = false, createBookDraft = CalendarCreateBookDraft()) }</ID>
</CurrentIssues>
</SmellBaseline>