Merge branch 'develop' into feature/user_location_state

This commit is contained in:
ganfra
2026-06-01 21:34:20 +02:00
committed by GitHub
162 changed files with 1692 additions and 1374 deletions
+1
View File
@@ -52,6 +52,7 @@ Uncomment this markdown table below and edit the last line `|||`:
<!-- Depending on the Pull Request content, it can be acceptable if some of the following checkboxes stay unchecked. -->
- [ ] I am aware of the [etiquette](https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#etiquette).
- This PR was made with the help of AI:
- [ ] Yes. In this case, please request a review by Copilot.
- [ ] No.
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Check membership
if: github.event.pull_request.user.login != 'renovate[bot]'
uses: tspascoal/get-user-teams-membership@818140d631d5f29f26b151afbe4179f87d9ceb5e # v4.0.1
uses: tspascoal/get-user-teams-membership@b2546c5affc730fd8e3d8483ae9ad3621938c2f9 # v4.0.2
id: teams
with:
username: ${{ github.event.pull_request.user.login }}
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
permissions:
issues: write
steps:
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
with:
only-labels: "X-Needs-Info"
days-before-issue-stale: 30
+8 -5
View File
@@ -44,11 +44,14 @@ PRs must meet these rules.
## Pull Request Guidelines
- Use sentence-style commit/PR messages (no conventional commits).
- Apply exactly **one** `PR-` label for changelog categorization.
- PR title = changelog entry — make it descriptive; no "Fixes #…" prefixes.
- Include screenshots or screen recordings for any UI changes.
- Keep PRs focused; split changes over 1000 lines.
- Sentence-style titles (no conventional commits).
- Exactly one `pr-` label (see `.github/release.yml`).
- Title = changelog entry — descriptive, no "Fixes #…".
- Leave description template for the developer. Redirect them to the [contributing etiquette](CONTRIBUTING.md#etiquette).
- Screenshots/videos for visual changes.
- 500 additions max — split large changes.
- Commits need a title and description; no tiny or massive commits.
- No history rewrites.
---
+23 -2
View File
@@ -6,7 +6,8 @@
* [I want to help translating Element](#i-want-to-help-translating-element)
* [I want to fix a bug](#i-want-to-fix-a-bug)
* [I want to add a new feature or enhancement](#i-want-to-add-a-new-feature-or-enhancement)
* [Developer onboarding](#developer-onboarding)
* [Etiquette](#etiquette)
* [Developer onboarding](#developer-onboarding)
* [Submitting the PRs](#submitting-the-prs)
* [Android Studio settings](#android-studio-settings)
* [Compilation](#compilation)
@@ -63,7 +64,27 @@ Once we know that you want to contribute and have confirmed that the new feature
Only once all of the above is met should you open a PR with your proposed changes.
## Developer onboarding
### Etiquette
* As stated above all significant changes should be communicated through an issue before opening a PR
* We are happy to receive contributions but features always require maintenance, so depending on the change we might not be willing to accept it
* We are also fine with AI led contributions within reasonable bounds
* You are completely responsible for the quality of the PR
* If the PR doesn't show minimal effort (code does not compile, code does not work as expected, etc.) on your part it will be closed
* Please write the description yourself, we don't have the bandwidth to read LLM essays. The code needs to speak for itself.
* We use git for version control and GitHub for reviews, so in order to make everybody's life easier please:
* Keep the existing pull request template
* Don't submit large PRs, especially if not previously talked about. Anything above 200 lines is large (excluding generated code e.g. tests, translations, mocks)
* Please don't open unfinished PRs and expect us to fill in the details
* If you would like our opinion/direction on unfinished code please link your branch or idea in the ticket
* Please limit the number of commits in a single PR. We are perfectly happy with splitting work across multiple sessions as long as they're logically independant and show promise of progress (ideally expressed through a ticket)
* Each and every commit should stand on its own, clearly explaining what it does and why
* Once a PR goes into review please don't rewrite the history unless agreed so with the reviewer.
* Tweaks and fixes following review can be directly committed (to be interactively rebased later) or as fixups
*The reviewer's response time will generally match yours. Switching contexts is very hard so please act accordingly. You are responsible for making the reviewers job enjoyable!*
### Developer onboarding
For a detailed overview of the project, see [Developer Onboarding](./docs/_developer_onboarding.md).
@@ -119,7 +119,6 @@ private fun RoomListModalBottomSheetContent(
leadingContent = ListItemContent.Icon(
iconSource = IconSource.Vector(CompoundIcons.MarkAsRead())
),
style = ListItemStyle.Primary,
)
} else {
ListItem(
@@ -133,7 +132,6 @@ private fun RoomListModalBottomSheetContent(
leadingContent = ListItemContent.Icon(
iconSource = IconSource.Vector(CompoundIcons.MarkAsUnread())
),
style = ListItemStyle.Primary,
)
}
val (textResId, icon) = if (contextMenu.isFavorite) {
@@ -159,7 +157,6 @@ private fun RoomListModalBottomSheetContent(
onClick = {
onFavoriteChange(!contextMenu.isFavorite)
},
style = ListItemStyle.Primary,
)
ListItem(
headlineContent = {
@@ -174,7 +171,6 @@ private fun RoomListModalBottomSheetContent(
CompoundIcons.Settings(),
)
),
style = ListItemStyle.Primary,
)
if (canReportRoom) {
ListItem(
@@ -211,7 +207,6 @@ private fun RoomListModalBottomSheetContent(
leadingContent = ListItemContent.Icon(
iconSource = IconSource.Vector(CompoundIcons.Delete())
),
style = ListItemStyle.Primary,
)
}
}
@@ -4,7 +4,7 @@
<string name="banner_battery_optimization_submit_android">"禁用优化"</string>
<string name="banner_battery_optimization_title_android">"通知未送达?"</string>
<string name="banner_new_sound_message">"通知提示音已升级:更清晰、更快速、干扰更少。"</string>
<string name="banner_new_sound_title">"我们已更新你的声音"</string>
<string name="banner_new_sound_title">"我们已更新提示音"</string>
<string name="banner_set_up_recovery_content">"你的聊天已被端到端加密自动备份。如果你无法访问所有设备,则需要使用恢复密钥并保留数字身份。"</string>
<string name="banner_set_up_recovery_submit">"获取恢复密钥"</string>
<string name="banner_set_up_recovery_title">"备份聊天"</string>
@@ -249,7 +249,7 @@ private fun ActionListViewContent(
leadingContent = ListItemContent.Icon(IconSource.Resource(action.icon)),
style = when {
action.destructive -> ListItemStyle.Destructive
else -> ListItemStyle.Primary
else -> ListItemStyle.Default
}
)
}
@@ -34,7 +34,6 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.ListItemStyle
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
import io.element.android.libraries.designsystem.theme.components.Text
@@ -106,25 +105,21 @@ private fun AttachmentSourcePickerMenu(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.PickAttachmentSource.PhotoFromCamera) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.TakePhoto())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_camera_photo)) },
style = ListItemStyle.Primary,
)
ListItem(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.PickAttachmentSource.VideoFromCamera) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.VideoCall())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_camera_video)) },
style = ListItemStyle.Primary,
)
ListItem(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.PickAttachmentSource.FromGallery) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Image())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_gallery)) },
style = ListItemStyle.Primary,
)
ListItem(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.PickAttachmentSource.FromFiles) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Attachment())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_files)) },
style = ListItemStyle.Primary,
)
if (state.canShareLocation) {
ListItem(
@@ -134,7 +129,6 @@ private fun AttachmentSourcePickerMenu(
},
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.LocationPin())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_location)) },
style = ListItemStyle.Primary,
)
}
ListItem(
@@ -144,14 +138,12 @@ private fun AttachmentSourcePickerMenu(
},
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Polls())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_poll)) },
style = ListItemStyle.Primary,
)
if (enableTextFormatting) {
ListItem(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.ToggleTextFormatting(enabled = true)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.TextFormatting())),
headlineContent = { Text(stringResource(R.string.screen_room_attachment_text_formatting)) },
style = ListItemStyle.Primary,
)
}
}
@@ -32,7 +32,11 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.aTimelineItemReadReceipts
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.receipt.ReadReceiptViewState
import io.element.android.features.messages.impl.timeline.components.receipt.TimelineItemReadReceiptView
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.RtcNotificationState
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
@@ -48,46 +52,63 @@ internal fun TimelineItemCallNotifyView(
timelineRoomInfo: TimelineRoomInfo,
event: TimelineItem.Event,
content: TimelineItemRtcNotificationContent,
renderReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
onLongClick: (TimelineItem.Event) -> Unit,
onReadReceiptsClick: (TimelineItem.Event) -> Unit,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.fillMaxWidth()
.border(1.dp, ElementTheme.colors.borderInteractiveSecondary, RoundedCornerShape(8.dp))
.combinedClickable(
enabled = true,
onClick = {},
onLongClick = { onLongClick(event) },
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
Column(modifier = modifier) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
.border(1.dp, ElementTheme.colors.borderInteractiveSecondary, RoundedCornerShape(8.dp))
.combinedClickable(
enabled = true,
onClick = {},
onLongClick = { onLongClick(event) },
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
)
.onKeyboardContextMenuAction { onLongClick(event) }
.padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier.size(20.sp.toDp()),
imageVector = getIcon(timelineRoomInfo, content),
contentDescription = null,
tint = ElementTheme.colors.iconSecondary,
)
.onKeyboardContextMenuAction { onLongClick(event) }
.padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier.size(20.sp.toDp()),
imageVector = getIcon(timelineRoomInfo, content),
contentDescription = null,
tint = ElementTheme.colors.iconSecondary,
)
Text(
modifier = Modifier.weight(1f),
text = stringResource(getTextRes(timelineRoomInfo, content)),
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
modifier = Modifier.weight(1f),
text = stringResource(getTextRes(timelineRoomInfo, content)),
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = event.sentTime,
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
Text(
text = event.sentTime,
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
TimelineItemReadReceiptView(
state = ReadReceiptViewState(
sendState = event.localSendState,
isLastOutgoingMessage = isLastOutgoingMessage,
receipts = event.readReceiptState.receipts,
),
renderReadReceipts = renderReadReceipts,
onReadReceiptsClick = { onReadReceiptsClick(event) },
modifier = Modifier.padding(top = 4.dp),
)
}
}
@@ -125,7 +146,10 @@ private fun getIcon(
@PreviewsDayNight
@Composable
internal fun TimelineItemCallNotifyViewPreview() = ElementPreview {
Column(modifier = Modifier.padding(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp)) {
val readReceiptState = aTimelineItemReadReceipts(
receipts = List(3) { aReadReceiptData(it) },
)
Column(modifier = Modifier.padding(bottom = 16.dp)) {
listOf(false, true).forEach { isDm ->
listOf(CallIntent.AUDIO, CallIntent.VIDEO).forEach { callIntent ->
listOf(
@@ -136,9 +160,18 @@ internal fun TimelineItemCallNotifyViewPreview() = ElementPreview {
val content = TimelineItemRtcNotificationContent(callIntent, state)
TimelineItemCallNotifyView(
timelineRoomInfo = aTimelineRoomInfo(isDm = isDm),
event = aTimelineItemEvent(content = content),
event = aTimelineItemEvent(
content = content,
readReceiptState = readReceiptState,
),
content = content,
// Render read receipts for the first item only
renderReadReceipts = !isDm &&
callIntent == CallIntent.AUDIO &&
state == RtcNotificationState.Started,
isLastOutgoingMessage = false,
onLongClick = {},
onReadReceiptsClick = {},
)
}
}
@@ -124,11 +124,13 @@ internal fun TimelineItemRow(
}
is TimelineItemRtcNotificationContent -> {
TimelineItemCallNotifyView(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp),
timelineRoomInfo = timelineRoomInfo,
event = timelineItem,
content = timelineItem.content,
renderReadReceipts = renderReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
onLongClick = onLongClick,
onReadReceiptsClick = onReadReceiptClick,
)
}
else -> {
@@ -16,6 +16,12 @@
<string name="emoji_picker_category_places">"Reisimine ja kohad"</string>
<string name="emoji_picker_category_recent">"Hiljutised emojid"</string>
<string name="emoji_picker_category_symbols">"Sümbolid"</string>
<string name="screen_image_edition_a11y_rotate_to_the_left">"Pööra pilti vasakule"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="one">"%1$d kraad"</item>
<item quantity="other">"%1$d kraadi"</item>
</plurals>
<string name="screen_image_edition_title">"Muuda fotot"</string>
<string name="screen_media_upload_preview_caption_warning">"Selgitused ja alapealkirjad ei pruugi olla nähtavad vanemate rakenduste kasutajatele."</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"Klõpsa üleslaaditava video kvaliteedi muutmiseks"</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"Faili üleslaadimine ei õnnestunud."</string>
@@ -26,6 +32,7 @@
<string name="screen_media_upload_preview_item_count">"Objekt %1$d/%2$d"</string>
<string name="screen_media_upload_preview_optimize_image_quality_title">"Optimeeri pildikvaliteeti"</string>
<string name="screen_media_upload_preview_processing">"Töötlen…"</string>
<string name="screen_media_upload_preview_title">"Lisa meediumi"</string>
<string name="screen_report_content_block_user">"Blokeeri kasutaja"</string>
<string name="screen_report_content_block_user_hint">"Vali see eelistus, kui sa soovid peita selle kasutaja kõik senised ja tulevased sõnumid"</string>
<string name="screen_report_content_explanation">"Teade selle sõnumi kohta edastatakse sinu koduserveri haldajale. Haldajal ei ole võimalik lugeda krüptitud sõnumite sisu."</string>
@@ -16,6 +16,10 @@
<string name="emoji_picker_category_places">"Matkustaminen ja paikat"</string>
<string name="emoji_picker_category_recent">"Viimeaikaiset emojit"</string>
<string name="emoji_picker_category_symbols">"Symbolit"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="one">"%1$d aste"</item>
<item quantity="other">"%1$d astetta"</item>
</plurals>
<string name="screen_media_upload_preview_caption_warning">"Kuvatekstit eivät välttämättä näy ihmisille, jotka käyttävät vanhempia sovelluksia."</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"Napauta muuttaaksesi videon lähetyslaatua"</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"Tiedostoa ei voitu lähettää."</string>
@@ -16,6 +16,10 @@
<string name="emoji_picker_category_places">"Voyages &amp; lieux"</string>
<string name="emoji_picker_category_recent">"Emojis récents"</string>
<string name="emoji_picker_category_symbols">"Symboles"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="one">"%1$d degré"</item>
<item quantity="other">"%1$d degrés"</item>
</plurals>
<string name="screen_media_upload_preview_caption_warning">"Les légendes peuvent ne pas être visibles pour les utilisateurs danciennes applications."</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"Cliquez pour modifier la qualité denvoi de la vidéo"</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"Le fichier na pas pu être envoyé."</string>
@@ -16,6 +16,11 @@
<string name="emoji_picker_category_places">"旅・場所"</string>
<string name="emoji_picker_category_recent">"最近使用"</string>
<string name="emoji_picker_category_symbols">"記号"</string>
<string name="screen_image_edition_a11y_rotate_to_the_left">"画像を左に回転"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="other">"%1$d°"</item>
</plurals>
<string name="screen_image_edition_title">"写真を編集"</string>
<string name="screen_media_upload_preview_caption_warning">"古いアプリケーションを使用しているユーザーはキャプションを見られない可能性があります。"</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"動画のアップロード画質を変更するにはタップしてください"</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"ファイルをアップロードに失敗しました。"</string>
@@ -16,6 +16,13 @@
<string name="emoji_picker_category_places">"Podróż i miejsca"</string>
<string name="emoji_picker_category_recent">"Ostatnie emoji"</string>
<string name="emoji_picker_category_symbols">"Symbole"</string>
<string name="screen_image_edition_a11y_rotate_to_the_left">"Obróć obraz w lewo"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="one">"%1$d stopień"</item>
<item quantity="few">"%1$d stopnie"</item>
<item quantity="many">"%1$d stopni"</item>
</plurals>
<string name="screen_image_edition_title">"Edytuj zdjęcie"</string>
<string name="screen_media_upload_preview_caption_warning">"Opis może być niedostępny dla osób korzystających ze starszej wersji aplikacji."</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"Dotknij, aby zmienić jakość przesyłania wideo."</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"Nie udało się przesłać pliku."</string>
@@ -16,6 +16,13 @@
<string name="emoji_picker_category_places">"Путешествия и места"</string>
<string name="emoji_picker_category_recent">"Недавние эмодзи"</string>
<string name="emoji_picker_category_symbols">"Символы"</string>
<string name="screen_image_edition_a11y_rotate_to_the_left">"Повернуть изображение влево."</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="one">"%1$d градус"</item>
<item quantity="few">"%1$d градуса"</item>
<item quantity="many">"%1$d градусов"</item>
</plurals>
<string name="screen_image_edition_title">"Редактировать фото"</string>
<string name="screen_media_upload_preview_caption_warning">"Подпись может быть не видна пользователям старых приложений."</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"Нажмите, чтобы изменить качество загружаемого видео."</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"Файл не может быть загружен."</string>
@@ -26,6 +33,7 @@
<string name="screen_media_upload_preview_item_count">"%1$d из %2$d"</string>
<string name="screen_media_upload_preview_optimize_image_quality_title">"Оптимизировать качество изображения"</string>
<string name="screen_media_upload_preview_processing">"Обработка…"</string>
<string name="screen_media_upload_preview_title">"Добавить медиа"</string>
<string name="screen_report_content_block_user">"Заблокировать пользователя"</string>
<string name="screen_report_content_block_user_hint">"Отметьте, хотите ли вы скрыть все текущие и будущие сообщения от этого пользователя"</string>
<string name="screen_report_content_explanation">"Это сообщение будет передано администратору вашего домашнего сервера. Они не смогут прочитать зашифрованные сообщения."</string>
@@ -16,6 +16,11 @@
<string name="emoji_picker_category_places">"文旅景点"</string>
<string name="emoji_picker_category_recent">"最近的 Emoji"</string>
<string name="emoji_picker_category_symbols">"符号"</string>
<string name="screen_image_edition_a11y_rotate_to_the_left">"向左旋转图像"</string>
<plurals name="screen_image_edition_a11y_rotation_state">
<item quantity="other">"%1$d 度"</item>
</plurals>
<string name="screen_image_edition_title">"编辑照片"</string>
<string name="screen_media_upload_preview_caption_warning">"使用旧版应用程序的用户可能无法看到字幕。"</string>
<string name="screen_media_upload_preview_change_video_quality_prompt">"点按以更改视频上传质量"</string>
<string name="screen_media_upload_preview_error_could_not_be_uploaded">"无法上传该文件。"</string>
@@ -286,7 +286,7 @@ private fun SoundsPreferenceCategory(state: NotificationSettingsState) {
type = RingtoneManager.TYPE_NOTIFICATION,
current = state.messageSound.sound,
defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI,
onSoundPicked = { sound -> state.eventSink(NotificationSettingsEvents.SetMessageSound(sound)) },
onSoundPick = { sound -> state.eventSink(NotificationSettingsEvents.SetMessageSound(sound)) },
)
// Skip the initial 0 emission so the picker doesn't auto-open on screen entry; only
// increments fired by LaunchMessageSoundPicker should launch it.
@@ -313,7 +313,7 @@ private fun SoundsPreferenceCategory(state: NotificationSettingsState) {
type = RingtoneManager.TYPE_RINGTONE,
current = state.callRingtone.sound,
defaultUri = Settings.System.DEFAULT_RINGTONE_URI,
onSoundPicked = { sound -> state.eventSink(NotificationSettingsEvents.SetCallRingtone(sound)) },
onSoundPick = { sound -> state.eventSink(NotificationSettingsEvents.SetCallRingtone(sound)) },
)
// Skip the initial 0 emission so the picker doesn't auto-open on screen entry; only
// increments fired by LaunchCallRingtonePicker should launch it.
@@ -441,7 +441,7 @@ private fun rememberSoundPickerOnClick(
type: Int,
current: NotificationSound,
defaultUri: Uri,
onSoundPicked: (NotificationSound) -> Unit,
onSoundPick: (NotificationSound) -> Unit,
): () -> Unit {
// Paparazzi previews don't provide a LocalActivityResultRegistryOwner, which
// rememberLauncherForActivityResult requires. Skip the launcher in inspection mode and
@@ -453,7 +453,7 @@ private fun rememberSoundPickerOnClick(
if (result.resultCode == Activity.RESULT_OK) {
val sound = result.data?.toPickedNotificationSound(defaultUri)
if (sound != null) {
onSoundPicked(sound)
onSoundPick(sound)
}
}
}
@@ -58,6 +58,7 @@
<string name="screen_labs_header_title">"Kas tahad katsetada?"</string>
<string name="screen_labs_title">"Katsed"</string>
<string name="screen_notification_settings_additional_settings_section_title">"Täiendavad seadistused"</string>
<string name="screen_notification_settings_call_ringtone_label">"Kõne helin"</string>
<string name="screen_notification_settings_calls_label">"Hääl- ja videokõned"</string>
<string name="screen_notification_settings_configuration_mismatch">"Eelistused ei sobi omavahel"</string>
<string name="screen_notification_settings_configuration_mismatch_description">"Et eelistusi oleks kergem leida, me oleme lihtsustanud teavituste seadistusi. Kuigi mõned varem valitud eelistused pole siin näha, siis nad kehtivad jätkuvalt.
@@ -76,10 +77,52 @@ Kui sa jätkad muutmist, siis võivad muutuda ka need peidetud eelistused."</str
<string name="screen_notification_settings_invite_for_me_label">"Kutsed"</string>
<string name="screen_notification_settings_mentions_only_disclaimer">"Sinu koduserver ei toeta seda funktsionaalsust krüptitud jututubades ja seega ei pruugi kõik teavitused sinuni jõuda."</string>
<string name="screen_notification_settings_mentions_section_title">"Mainimiste alusel"</string>
<string name="screen_notification_settings_message_sound_dialog_choose_other">"Vali muu helin…"</string>
<string name="screen_notification_settings_message_sound_dialog_current_subtitle">"Hetkel on kasutusel %1$s"</string>
<string name="screen_notification_settings_message_sound_dialog_title">"Sõnumi heli"</string>
<string name="screen_notification_settings_message_sound_label">"Sõnumi heli"</string>
<string name="screen_notification_settings_mode_all">"Kõik"</string>
<string name="screen_notification_settings_mode_mentions">"Mainimiste alusel"</string>
<string name="screen_notification_settings_notification_section_title">"Teavita mind"</string>
<string name="screen_notification_settings_room_mention_label">"Teavita mind @jututoa puhul"</string>
<string name="screen_notification_settings_sound_custom_fallback">"Kohandatud"</string>
<string name="screen_notification_settings_sound_custom_sound_button_title">"Sinu valitud helin…"</string>
<string name="screen_notification_settings_sound_delete_sound_error_title">"Viga faili kustutamisel"</string>
<string name="screen_notification_settings_sound_element_default">"Elementi vaikimisi väärtus"</string>
<string name="screen_notification_settings_sound_element_fade">"Elemendi hajumine"</string>
<string name="screen_notification_settings_sound_import_sound_error_title">"Viga faili importimisel"</string>
<string name="screen_notification_settings_sound_preview_sound_error_title">"Viga helina eelvaate esitamisel"</string>
<string name="screen_notification_settings_sound_section_title">"Helin"</string>
<string name="screen_notification_settings_sound_set_sound_error_dismiss_a11y">"Sulge helinavea viga"</string>
<string name="screen_notification_settings_sound_set_sound_error_title">"Viga helina seadistamisel"</string>
<string name="screen_notification_settings_sound_silent">"Vaikne"</string>
<string name="screen_notification_settings_sound_system_alert">"Hoiatus"</string>
<string name="screen_notification_settings_sound_system_anticipate">"Ootus"</string>
<string name="screen_notification_settings_sound_system_bell">"Kelluke"</string>
<string name="screen_notification_settings_sound_system_bloom">"Õitsemine"</string>
<string name="screen_notification_settings_sound_system_calypso">"Kalüpso"</string>
<string name="screen_notification_settings_sound_system_chime">"Kellamäng"</string>
<string name="screen_notification_settings_sound_system_choo_choo">"Tšuhh-tšuhh"</string>
<string name="screen_notification_settings_sound_system_default">"Süsteemi vaikimisi väärtus"</string>
<string name="screen_notification_settings_sound_system_descent">"Laskumine"</string>
<string name="screen_notification_settings_sound_system_electronic">"Elektrooniline"</string>
<string name="screen_notification_settings_sound_system_fanfare">"Tuututamine"</string>
<string name="screen_notification_settings_sound_system_glass">"Klaas"</string>
<string name="screen_notification_settings_sound_system_horn">"Pasun"</string>
<string name="screen_notification_settings_sound_system_ladder">"Redel"</string>
<string name="screen_notification_settings_sound_system_minuet">"Menuett"</string>
<string name="screen_notification_settings_sound_system_news_flash">"Uudisvälgatus"</string>
<string name="screen_notification_settings_sound_system_noir">"Sünge"</string>
<string name="screen_notification_settings_sound_system_sherwood_forest">"Sherwoodi mets"</string>
<string name="screen_notification_settings_sound_system_spell">"Loits"</string>
<string name="screen_notification_settings_sound_system_suspense">"Põnevus"</string>
<string name="screen_notification_settings_sound_system_swish">"Vihin-vuhin"</string>
<string name="screen_notification_settings_sound_system_telegraph">"Telegraaf"</string>
<string name="screen_notification_settings_sound_system_tiptoes">"Kikivarvul"</string>
<string name="screen_notification_settings_sound_system_tri_tone">"Kolmetooniline"</string>
<string name="screen_notification_settings_sound_system_tweet">"Säuts"</string>
<string name="screen_notification_settings_sound_system_typewriters">"Kirjutusmasinad"</string>
<string name="screen_notification_settings_sound_system_update">"Uuenda"</string>
<string name="screen_notification_settings_system_notifications_action_required">"Teavituste saamiseks palun muuda oma %1$s."</string>
<string name="screen_notification_settings_system_notifications_action_required_content_link">"süsteemi seadistusi"</string>
<string name="screen_notification_settings_system_notifications_turned_off">"Süsteemi teavitused on välja lülitatud"</string>
@@ -59,6 +59,7 @@
<string name="screen_labs_header_title">"Chcesz poeksperymentować?"</string>
<string name="screen_labs_title">"Laboratoria"</string>
<string name="screen_notification_settings_additional_settings_section_title">"Dodatkowe ustawienia"</string>
<string name="screen_notification_settings_call_ringtone_label">"Dzwonek połączenia"</string>
<string name="screen_notification_settings_calls_label">"Połączenia audio i wideo"</string>
<string name="screen_notification_settings_configuration_mismatch">"Niezgodność konfiguracji"</string>
<string name="screen_notification_settings_configuration_mismatch_description">"Uprościliśmy Ustawienia powiadomień, aby ułatwić nawigowanie między opcjami. Niektóre ustawienia, które wybrałeś mogły zniknąć, lecz są wciąż aktywne.
@@ -77,10 +78,15 @@ Niektóre ustawienia mogą ulec zmianie, jeśli kontynuujesz."</string>
<string name="screen_notification_settings_invite_for_me_label">"Zaproszenia"</string>
<string name="screen_notification_settings_mentions_only_disclaimer">"Twój serwer domowy nie wspiera tej opcji w pokojach szyfrowanych, możesz nie otrzymać powiadomień z niektórych pokoi."</string>
<string name="screen_notification_settings_mentions_section_title">"Wzmianki"</string>
<string name="screen_notification_settings_message_sound_dialog_choose_other">"Wybierz inny dźwięk…"</string>
<string name="screen_notification_settings_message_sound_dialog_current_subtitle">"Aktualnie używany %1$s"</string>
<string name="screen_notification_settings_message_sound_dialog_title">"Dźwięk wiadomości"</string>
<string name="screen_notification_settings_message_sound_label">"Dźwięk wiadomości"</string>
<string name="screen_notification_settings_mode_all">"Wszystkie"</string>
<string name="screen_notification_settings_mode_mentions">"Wzmianki"</string>
<string name="screen_notification_settings_notification_section_title">"Powiadamiaj mnie przez"</string>
<string name="screen_notification_settings_room_mention_label">"Powiadom mnie na @pokój"</string>
<string name="screen_notification_settings_sound_custom_fallback">"Własny"</string>
<string name="screen_notification_settings_sound_custom_sound_button_title">"Własny dźwięk…"</string>
<string name="screen_notification_settings_sound_delete_sound_error_title">"Błąd usuwania pliku"</string>
<string name="screen_notification_settings_sound_element_default">"Domyślny Element"</string>
@@ -88,7 +94,9 @@ Niektóre ustawienia mogą ulec zmianie, jeśli kontynuujesz."</string>
<string name="screen_notification_settings_sound_import_sound_error_title">"Błąd importowania pliku"</string>
<string name="screen_notification_settings_sound_preview_sound_error_title">"Wystąpił błąd podczas podglądania dźwięku powiadomień"</string>
<string name="screen_notification_settings_sound_section_title">"Dźwięk"</string>
<string name="screen_notification_settings_sound_set_sound_error_dismiss_a11y">"Pomiń dźwięk błędu"</string>
<string name="screen_notification_settings_sound_set_sound_error_title">"Nie udało się ustawić dźwięku powiadomień"</string>
<string name="screen_notification_settings_sound_silent">"Cichy"</string>
<string name="screen_notification_settings_sound_system_alert">"Alert"</string>
<string name="screen_notification_settings_sound_system_anticipate">"Oczekiwanie"</string>
<string name="screen_notification_settings_sound_system_bell">"Dzwonek"</string>
@@ -96,6 +104,7 @@ Niektóre ustawienia mogą ulec zmianie, jeśli kontynuujesz."</string>
<string name="screen_notification_settings_sound_system_calypso">"Kalipso"</string>
<string name="screen_notification_settings_sound_system_chime">"Gong"</string>
<string name="screen_notification_settings_sound_system_choo_choo">"Ciuchcia"</string>
<string name="screen_notification_settings_sound_system_default">"Ustawienie domyślne"</string>
<string name="screen_notification_settings_sound_system_descent">"Opadający"</string>
<string name="screen_notification_settings_sound_system_electronic">"Elektroniczna"</string>
<string name="screen_notification_settings_sound_system_fanfare">"Fanfary"</string>
@@ -81,6 +81,39 @@
<string name="screen_notification_settings_mode_mentions">"Упоминания"</string>
<string name="screen_notification_settings_notification_section_title">"Уведомлять меня"</string>
<string name="screen_notification_settings_room_mention_label">"Уведомлять меня при упоминании @room"</string>
<string name="screen_notification_settings_sound_custom_sound_button_title">"Пользовательский звук…"</string>
<string name="screen_notification_settings_sound_delete_sound_error_title">"Ошибка при удалении файла"</string>
<string name="screen_notification_settings_sound_element_default">"Element по умолчанию"</string>
<string name="screen_notification_settings_sound_import_sound_error_title">"Ошибка импорта файла"</string>
<string name="screen_notification_settings_sound_preview_sound_error_title">"Ошибка предварительного прослушиванием звука"</string>
<string name="screen_notification_settings_sound_section_title">"Звук"</string>
<string name="screen_notification_settings_sound_set_sound_error_title">"Проблема с настройкой звукового оповещения"</string>
<string name="screen_notification_settings_sound_system_alert">"Оповещение"</string>
<string name="screen_notification_settings_sound_system_anticipate">"Anticipate"</string>
<string name="screen_notification_settings_sound_system_bell">"Bell"</string>
<string name="screen_notification_settings_sound_system_bloom">"Bloom"</string>
<string name="screen_notification_settings_sound_system_calypso">"Calypso"</string>
<string name="screen_notification_settings_sound_system_chime">"Chime"</string>
<string name="screen_notification_settings_sound_system_choo_choo">"Choo Choo"</string>
<string name="screen_notification_settings_sound_system_descent">"Descent"</string>
<string name="screen_notification_settings_sound_system_electronic">"Electronic"</string>
<string name="screen_notification_settings_sound_system_fanfare">"Fanfare"</string>
<string name="screen_notification_settings_sound_system_glass">"Glass"</string>
<string name="screen_notification_settings_sound_system_horn">"Horn"</string>
<string name="screen_notification_settings_sound_system_ladder">"Ladder"</string>
<string name="screen_notification_settings_sound_system_minuet">"Minuet"</string>
<string name="screen_notification_settings_sound_system_news_flash">"News Flash"</string>
<string name="screen_notification_settings_sound_system_noir">"Noir"</string>
<string name="screen_notification_settings_sound_system_sherwood_forest">"Sherwood Forest"</string>
<string name="screen_notification_settings_sound_system_spell">"Spell"</string>
<string name="screen_notification_settings_sound_system_suspense">"Suspense"</string>
<string name="screen_notification_settings_sound_system_swish">"Swish"</string>
<string name="screen_notification_settings_sound_system_telegraph">"Telegraph"</string>
<string name="screen_notification_settings_sound_system_tiptoes">"Tiptoes"</string>
<string name="screen_notification_settings_sound_system_tri_tone">"Tri-tone"</string>
<string name="screen_notification_settings_sound_system_tweet">"Tweet"</string>
<string name="screen_notification_settings_sound_system_typewriters">"Typewriters"</string>
<string name="screen_notification_settings_sound_system_update">"Обновить"</string>
<string name="screen_notification_settings_system_notifications_action_required">"Чтобы получать уведомления, измените %1$s."</string>
<string name="screen_notification_settings_system_notifications_action_required_content_link">"системные настройки"</string>
<string name="screen_notification_settings_system_notifications_turned_off">"Системные уведомления выключены"</string>
@@ -57,6 +57,7 @@
<string name="screen_labs_header_title">"想尝试新功能?"</string>
<string name="screen_labs_title">"实验室"</string>
<string name="screen_notification_settings_additional_settings_section_title">"更多设置"</string>
<string name="screen_notification_settings_call_ringtone_label">"来电铃声"</string>
<string name="screen_notification_settings_calls_label">"音视频通话"</string>
<string name="screen_notification_settings_configuration_mismatch">"配置不匹配"</string>
<string name="screen_notification_settings_configuration_mismatch_description">"我们简化了通知设置,使选项更易于查找。你曾经选择的某些自定义设置未在此处显示,但它们仍然有效。
@@ -75,18 +76,25 @@
<string name="screen_notification_settings_invite_for_me_label">"邀请"</string>
<string name="screen_notification_settings_mentions_only_disclaimer">"主服务器不支持在加密房间中的此选项,因此在某些房间你可能无法收到通知。"</string>
<string name="screen_notification_settings_mentions_section_title">"提及"</string>
<string name="screen_notification_settings_message_sound_dialog_choose_other">"选择其它提示音…"</string>
<string name="screen_notification_settings_message_sound_dialog_current_subtitle">"当前正在使用 %1$s"</string>
<string name="screen_notification_settings_message_sound_dialog_title">"消息提示音"</string>
<string name="screen_notification_settings_message_sound_label">"消息提示音"</string>
<string name="screen_notification_settings_mode_all">"全部"</string>
<string name="screen_notification_settings_mode_mentions">"提及"</string>
<string name="screen_notification_settings_notification_section_title">"通知我以下类型"</string>
<string name="screen_notification_settings_room_mention_label">"提及所有成员(@room)时通知我"</string>
<string name="screen_notification_settings_sound_custom_sound_button_title">"自定义声音…"</string>
<string name="screen_notification_settings_sound_custom_fallback">"自定义"</string>
<string name="screen_notification_settings_sound_custom_sound_button_title">"自定义提示音…"</string>
<string name="screen_notification_settings_sound_delete_sound_error_title">"删除文件时出错"</string>
<string name="screen_notification_settings_sound_element_default">"Element 默认"</string>
<string name="screen_notification_settings_sound_element_fade">"Element 淡入"</string>
<string name="screen_notification_settings_sound_import_sound_error_title">"导入文件时出错"</string>
<string name="screen_notification_settings_sound_preview_sound_error_title">"预览提示音时出现问题"</string>
<string name="screen_notification_settings_sound_section_title">"音"</string>
<string name="screen_notification_settings_sound_section_title">"提示音"</string>
<string name="screen_notification_settings_sound_set_sound_error_dismiss_a11y">"忽略提示音错误"</string>
<string name="screen_notification_settings_sound_set_sound_error_title">"设置提示音时出现问题"</string>
<string name="screen_notification_settings_sound_silent">"静默"</string>
<string name="screen_notification_settings_sound_system_alert">"提醒声"</string>
<string name="screen_notification_settings_sound_system_anticipate">"悉心期盼"</string>
<string name="screen_notification_settings_sound_system_bell">"铃铛"</string>
@@ -94,6 +102,7 @@
<string name="screen_notification_settings_sound_system_calypso">"即兴曲调"</string>
<string name="screen_notification_settings_sound_system_chime">"风铃"</string>
<string name="screen_notification_settings_sound_system_choo_choo">"火车鸣笛"</string>
<string name="screen_notification_settings_sound_system_default">"系统默认"</string>
<string name="screen_notification_settings_sound_system_descent">"渐弱"</string>
<string name="screen_notification_settings_sound_system_electronic">"电子乐"</string>
<string name="screen_notification_settings_sound_system_fanfare">"嘹亮吹奏声"</string>
@@ -20,6 +20,7 @@ interface BugReporter {
* @param problemDescription the bug description
* @param canContact true if the user opt in to be contacted directly
* @param sendPushRules true to include the push rules
* @param ghIssueNumber it not null, the GitHub issue number to link the bug report to.
* @param listener the listener
*/
suspend fun sendBugReport(
@@ -29,6 +30,7 @@ interface BugReporter {
problemDescription: String,
canContact: Boolean = false,
sendPushRules: Boolean = false,
ghIssueNumber: Int? = null,
listener: BugReporterListener
)
@@ -18,4 +18,5 @@ sealed interface BugReportEvents {
data class SetCanContact(val canContact: Boolean) : BugReportEvents
data class SetSendScreenshot(val sendScreenshot: Boolean) : BugReportEvents
data class SetSendPushRules(val sendPushRules: Boolean) : BugReportEvents
data class SetGhIssueNumber(val ghIssueNumber: Int?) : BugReportEvents
}
@@ -113,6 +113,9 @@ class BugReportPresenter(
sendingProgress.floatValue = 0f
sendingAction.value = AsyncAction.Uninitialized
}
is BugReportEvents.SetGhIssueNumber -> updateFormState(formState) {
copy(ghIssueNumber = event.ghIssueNumber)
}
}
}
@@ -142,7 +145,8 @@ class BugReportPresenter(
problemDescription = formState.description,
canContact = formState.canContact,
sendPushRules = formState.sendPushRules,
listener = listener
ghIssueNumber = formState.ghIssueNumber,
listener = listener,
)
}
@@ -32,6 +32,7 @@ data class BugReportFormState(
val canContact: Boolean,
val sendScreenshot: Boolean,
val sendPushRules: Boolean,
val ghIssueNumber: Int?,
) : Parcelable {
companion object {
val Default = BugReportFormState(
@@ -40,6 +41,7 @@ data class BugReportFormState(
canContact = false,
sendScreenshot = false,
sendPushRules = false,
ghIssueNumber = null,
)
}
}
@@ -34,6 +34,7 @@ import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import coil3.request.CachePolicy
import coil3.request.ImageRequest
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.rageshake.impl.R
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.async.AsyncActionView
@@ -155,6 +156,48 @@ fun BugReportView(
title = stringResource(R.string.screen_bug_report_send_notification_settings_title),
subtitle = stringResource(R.string.screen_bug_report_send_notification_settings_description),
)
PreferenceRow {
var ghIssueNumberState by textFieldState(
stateValue = state.formState.ghIssueNumber?.toString() ?: ""
)
TextField(
value = ghIssueNumberState,
modifier = Modifier
.fillMaxWidth()
.onTabOrEnterKeyFocusNext(LocalFocusManager.current),
enabled = isFormEnabled,
label = stringResource(id = R.string.screen_bug_report_github_issue_label),
placeholder = "1234",
supportingText = stringResource(id = R.string.screen_bug_report_github_issue_description),
leadingIcon = {
Text(
text = "#",
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textSecondary,
)
},
onValueChange = {
if (it.isEmpty()) {
ghIssueNumberState = ""
eventSink(BugReportEvents.SetGhIssueNumber(null))
} else {
val number = it.toIntOrNull()?.takeIf { ghInt -> ghInt in 1..99_999 }
number?.let { ghIssueNumber ->
ghIssueNumberState = ghIssueNumber.toString()
eventSink(BugReportEvents.SetGhIssueNumber(ghIssueNumber))
}
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next,
),
keyboardActions = KeyboardActions(onNext = {
keyboardController?.hide()
}),
singleLine = true,
)
}
// Submit
PreferenceRow {
Button(
@@ -123,6 +123,7 @@ class DefaultBugReporter(
problemDescription: String,
canContact: Boolean,
sendPushRules: Boolean,
ghIssueNumber: Int?,
listener: BugReporterListener,
) {
val url = bugReporterUrlProvider.provide().first()
@@ -144,6 +145,9 @@ class DefaultBugReporter(
val crashCallStack = crashDataStore.crashInfo().first()
val bugDescription = buildString {
append(problemDescription)
ghIssueNumber?.let {
append("\n\nhttps://github.com/element-hq/element-x-android/issues/$it")
}
if (crashCallStack.isNotEmpty() && withCrashLogs) {
append("\n\n\n\n--------------------------------- crash call stack ---------------------------------\n")
append(crashCallStack)
@@ -8,6 +8,8 @@
<string name="screen_bug_report_editor_placeholder">"Palun kirjelda probleemi…"</string>
<string name="screen_bug_report_editor_supporting">"Kui vähegi võimalik, siis kirjuta inglise keeles."</string>
<string name="screen_bug_report_error_description_too_short">"Kirjeldus on liiga lühike. Palun jaga täpsemat teavet selle kohta, mis juhtus. Tänud juba ette!"</string>
<string name="screen_bug_report_github_issue_description">"Võid sisestada seotud GitHubi veateate numbri, kui see on olemas."</string>
<string name="screen_bug_report_github_issue_label">"Veateade GitHubis"</string>
<string name="screen_bug_report_include_crash_logs">"Saada krahhilogid"</string>
<string name="screen_bug_report_include_logs">"Luba logide saatmine"</string>
<string name="screen_bug_report_include_logs_error">"Sinu logid on väga mahukad ja neid ei saa siia lisada. Palun saada logid meile mõnel muul viisil."</string>
@@ -8,6 +8,7 @@
<string name="screen_bug_report_editor_placeholder">"描述问题…"</string>
<string name="screen_bug_report_editor_supporting">"请尽可能用英文描述。"</string>
<string name="screen_bug_report_error_description_too_short">"描述太短,请提供详细情况。谢谢!"</string>
<string name="screen_bug_report_github_issue_description">"你可以输入与之相关的 GitHub issue 编号(如果有)。"</string>
<string name="screen_bug_report_include_crash_logs">"发送崩溃日志"</string>
<string name="screen_bug_report_include_logs">"允许日志"</string>
<string name="screen_bug_report_include_logs_error">"日志文件过大,无法包含在本次报告中,请通过其它方式发送给我们。"</string>
@@ -8,6 +8,8 @@
<string name="screen_bug_report_editor_placeholder">"Describe the problem…"</string>
<string name="screen_bug_report_editor_supporting">"If possible, please write the description in English."</string>
<string name="screen_bug_report_error_description_too_short">"The description is too short, please provide more details about what happened. Thanks!"</string>
<string name="screen_bug_report_github_issue_description">"You can enter the number of an associated GitHub issue, if any."</string>
<string name="screen_bug_report_github_issue_label">"GitHub issue"</string>
<string name="screen_bug_report_include_crash_logs">"Send crash logs"</string>
<string name="screen_bug_report_include_logs">"Allow logs"</string>
<string name="screen_bug_report_include_logs_error">"Your logs are excessively large so cannot be included in this report, please send them to us another way."</string>
@@ -107,6 +107,18 @@ class BugReportPresenterTest {
}
}
@Test
fun `present - set GitHub issue number`() = runTest {
val presenter = createPresenter()
presenter.test {
val initialState = awaitItem()
initialState.eventSink.invoke(BugReportEvents.SetGhIssueNumber(1))
assertThat(awaitItem().formState).isEqualTo(BugReportFormState.Default.copy(ghIssueNumber = 1))
initialState.eventSink.invoke(BugReportEvents.SetGhIssueNumber(null))
assertThat(awaitItem().formState).isEqualTo(BugReportFormState.Default.copy(ghIssueNumber = null))
}
}
@Test
fun `present - reset all`() = runTest {
val presenter = createPresenter(
@@ -28,6 +28,7 @@ class FakeBugReporter(val mode: Mode = Mode.Success) : BugReporter {
problemDescription: String,
canContact: Boolean,
sendPushRules: Boolean,
ghIssueNumber: Int?,
listener: BugReporterListener,
) {
delay(100)
@@ -181,7 +181,6 @@ private fun ChangeOwnRoleBottomSheet(
ListItem(
headlineContent = { Text(stringResource(CommonStrings.action_cancel)) },
onClick = ::dismiss,
style = ListItemStyle.Primary,
)
}
}
@@ -278,7 +278,6 @@ private fun RoomMemberActionsBottomSheet(
when (val action = actionState.action) {
is ModerationAction.DisplayProfile -> {
ListItem(
style = ListItemStyle.Primary,
headlineContent = { Text(stringResource(R.string.screen_bottom_sheet_manage_room_member_member_user_info)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserProfile())),
onClick = {
@@ -84,7 +84,6 @@ private fun PreferenceBlockUser(
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Block())),
onClick = { if (!isLoading) eventSink(UserProfileEvents.UnblockUser(needsConfirmation = true)) },
trailingContent = if (isLoading) ListItemContent.Custom(loadingCurrentValue) else null,
style = ListItemStyle.Primary,
)
} else {
ListItem(
@@ -33,6 +33,11 @@ class DefaultConsoleMessageLogger : ConsoleMessageLogger {
else -> Log.DEBUG
}
// Avoid logging any messages that contain "password" to prevent leaking sensitive information
if (consoleMessage.message().contains("password=")) {
return
}
val message = buildString {
append(consoleMessage.sourceId())
append(":")
@@ -41,20 +46,6 @@ class DefaultConsoleMessageLogger : ConsoleMessageLogger {
append(consoleMessage.message())
}
// Avoid logging any messages that contain "password" to prevent leaking sensitive information
if (message.contains("password=")) {
return
}
Timber.tag(tag).log(
priority = priority,
message = buildString {
append(consoleMessage.sourceId())
append(":")
append(consoleMessage.lineNumber())
append(" ")
append(consoleMessage.message())
},
)
Timber.tag(tag).log(priority = priority, message = message)
}
}
@@ -18,10 +18,10 @@ class FilterEmptyDayPostProcessor {
* Filters out day separators from [items] for days that don't contain any events.
*/
fun process(items: List<MatrixTimelineItem>): List<MatrixTimelineItem> = buildList {
// The timeline is ordered by descending timestamp, so events that happened during a day appear before the day separator for that day.
// We can use this to determine if a day separator should be kept or not.
// The timeline is ordered by ascending timestamp, so events that happened during a day appear after the day separator for that day.
// We can use this to determine if a day separator should be kept or not by traversing the list in reverse.
var hasEvent = false
for (item in items) {
for (item in items.asReversed()) {
if (item is MatrixTimelineItem.Event) {
hasEvent = true
add(item)
@@ -35,4 +35,6 @@ class FilterEmptyDayPostProcessor {
}
}
}
// Then reverse the result to restore the original order, minus the empty day separators.
.asReversed()
}
@@ -32,36 +32,36 @@ class FilterEmptyDayPostProcessorTest {
@Test
fun `filterEmptyDaySeparators keeps day separator with events after it`() {
val items = listOf(
anEvent,
aDaySeparator(TODAY),
anEvent,
)
val result = FilterEmptyDayPostProcessor().process(items)
assertThat(result).hasSize(2)
assertThat(result[0]).isEqualTo(anEvent)
assertThat(result[1]).isEqualTo(aDaySeparator(TODAY))
assertThat(result[0]).isEqualTo(aDaySeparator(TODAY))
assertThat(result[1]).isEqualTo(anEvent)
}
@Test
fun `filterEmptyDaySeparators removes day separator with no events after it`() {
val items = listOf(
aDaySeparator(TODAY),
aDaySeparator(YESTERDAY),
aDaySeparator(TODAY),
)
val result = FilterEmptyDayPostProcessor().process(items)
assertThat(result).isEmpty()
}
@Test
fun `filterEmptyDaySeparators removes first day separator and keeps second when only second has events`() {
fun `filterEmptyDaySeparators removes second day separator and keeps first when only first has events`() {
val items = listOf(
aDaySeparator(TODAY),
anEvent,
aDaySeparator(YESTERDAY),
anEvent,
aDaySeparator(TODAY),
)
val result = FilterEmptyDayPostProcessor().process(items)
assertThat(result).hasSize(2)
assertThat(result[0]).isEqualTo(anEvent)
assertThat(result[1]).isEqualTo(aDaySeparator(YESTERDAY))
assertThat(result[0]).isEqualTo(aDaySeparator(YESTERDAY))
assertThat(result[1]).isEqualTo(anEvent)
}
@Test
@@ -78,15 +78,15 @@ class FilterEmptyDayPostProcessorTest {
@Test
fun `filterEmptyDaySeparators keeps all items when no day separators`() {
val items = listOf(
anEvent,
anEvent.copy(uniqueId = UniqueId("event2")),
anEvent,
)
val result = FilterEmptyDayPostProcessor().process(items)
assertThat(result).hasSize(2)
}
@Test
fun `filterEmptyDaySeparators removes day separator followed by non-event virtual item`() {
fun `filterEmptyDaySeparators removes day separator preceded by non-event virtual item`() {
val readMarker = MatrixTimelineItem.Virtual(
uniqueId = UniqueId("readMarker"),
virtual = VirtualTimelineItem.ReadMarker
@@ -107,12 +107,12 @@ class FilterEmptyDayPostProcessorTest {
virtual = VirtualTimelineItem.ReadMarker
)
val items = listOf(
anEvent,
readMarker,
aDaySeparator(TODAY),
readMarker,
anEvent,
)
val result = FilterEmptyDayPostProcessor().process(items)
assertThat(result).hasSize(3)
assertThat(result[2]).isEqualTo(aDaySeparator(TODAY))
assertThat(result[0]).isEqualTo(aDaySeparator(TODAY))
}
}
@@ -104,7 +104,7 @@ private fun AvatarActionBottomSheetContent(
leadingContent = ListItemContent.Icon(IconSource.Resource(action.iconResourceId)),
style = when {
action.destructive -> ListItemStyle.Destructive
else -> ListItemStyle.Primary
else -> ListItemStyle.Default
}
)
}
@@ -105,7 +105,6 @@ fun MediaDetailsBottomSheet(
ListItem(
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.VisibilityOn())),
headlineContent = { Text(stringResource(CommonStrings.action_view_in_timeline)) },
style = ListItemStyle.Primary,
onClick = {
onViewInTimeline(state.eventId)
}
@@ -113,7 +112,6 @@ fun MediaDetailsBottomSheet(
ListItem(
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.ShareAndroid())),
headlineContent = { Text(stringResource(CommonStrings.action_share)) },
style = ListItemStyle.Primary,
onClick = {
onShare(state.eventId)
}
@@ -121,7 +119,6 @@ fun MediaDetailsBottomSheet(
ListItem(
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Forward())),
headlineContent = { Text(stringResource(CommonStrings.action_forward)) },
style = ListItemStyle.Primary,
onClick = {
onForward(state.eventId)
}
@@ -129,7 +126,6 @@ fun MediaDetailsBottomSheet(
ListItem(
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Download())),
headlineContent = { Text(stringResource(CommonStrings.action_download)) },
style = ListItemStyle.Primary,
onClick = {
onDownload(state.eventId)
}
@@ -148,7 +144,6 @@ fun MediaDetailsBottomSheet(
ListItem(
leadingContent = icon,
headlineContent = { Text(wording) },
style = ListItemStyle.Primary,
onClick = {
onOpenWith(state.eventId)
}
@@ -18,6 +18,7 @@
<string name="a11y_info">"Teave"</string>
<string name="a11y_join_call">"Liitu kõnega"</string>
<string name="a11y_jump_to_bottom">"Mine lõppu"</string>
<string name="a11y_jump_to_unread">"Mine lugemata sõnumite juurde"</string>
<string name="a11y_move_the_map_to_my_location">"Nihuta kaart minu asukohta"</string>
<string name="a11y_notifications_mentions_only">"Ainult mainimised"</string>
<string name="a11y_notifications_muted">"Summutatud"</string>
@@ -98,6 +99,7 @@
<string name="action_decline_and_block">"Keeldu ja blokeeri"</string>
<string name="action_delete">"Kustuta"</string>
<string name="action_delete_account">"Kustuta kasutajakonto"</string>
<string name="action_delete_file">"Kustuta fail"</string>
<string name="action_delete_poll">"Kustuta küsitlus"</string>
<string name="action_deselect_all">"Eemalda kõik valikud"</string>
<string name="action_disable">"Lülita välja"</string>
@@ -303,6 +305,7 @@ Põhjus: %1$s."</string>
<string name="common_please_wait">"Palun oota…"</string>
<string name="common_poll_end_confirmation">"Kas oled kindel, et soovid selle küsitluse lõpetada?"</string>
<string name="common_poll_summary">"Küsitlus: %1$s"</string>
<string name="common_poll_summary_prefix">"Küsitlus"</string>
<string name="common_poll_total_votes">"Hääli kokku: %1$s"</string>
<string name="common_poll_undisclosed_text">"Tulemused on näha peale küsitluse lõppemist"</string>
<plurals name="common_poll_votes_count">
@@ -308,6 +308,7 @@ Powód: %1$s."</string>
<string name="common_please_wait">"Proszę czekać…"</string>
<string name="common_poll_end_confirmation">"Jesteś pewien, że chcesz zakończyć tę ankietę?"</string>
<string name="common_poll_summary">"Ankieta: %1$s"</string>
<string name="common_poll_summary_prefix">"Ankieta"</string>
<string name="common_poll_total_votes">"Łączna liczba głosów: %1$s"</string>
<string name="common_poll_undisclosed_text">"Wyniki zostaną wyświetlone po zakończeniu ankiety"</string>
<plurals name="common_poll_votes_count">
@@ -424,7 +425,7 @@ Powód: %1$s."</string>
<string name="common_video_quality_standard_description">"Balans między jakością a szybkością przesyłania"</string>
<string name="common_voice_message">"Wiadomość głosowa"</string>
<string name="common_waiting">"Oczekiwanie…"</string>
<string name="common_waiting_for_decryption_key">"Oczekiwanie na tę wiadomość"</string>
<string name="common_waiting_for_decryption_key">"Oczekiwanie wiadomości"</string>
<string name="common_waiting_live_location">"Czekam na lokalizację na żywo…"</string>
<string name="common_world_readable_history">"Każdy może zobaczyć historię"</string>
<string name="common_you">"Ty"</string>
@@ -10,6 +10,7 @@
<item quantity="few">"Введено %1$d цифры"</item>
<item quantity="many">"Введено %1$d цифр"</item>
</plurals>
<string name="a11y_duration">"Продолжительность: %1$s"</string>
<string name="a11y_edit_avatar">"Изменить аватар"</string>
<string name="a11y_edit_room_address_hint">"Полный адрес %1$s"</string>
<string name="a11y_encryption_details">"Сведения о шифровании"</string>
@@ -18,6 +19,7 @@
<string name="a11y_info">"Информация"</string>
<string name="a11y_join_call">"Присоединиться к звонку"</string>
<string name="a11y_jump_to_bottom">"Перейти вниз"</string>
<string name="a11y_jump_to_unread">"Перейти к непрочитанным"</string>
<string name="a11y_move_the_map_to_my_location">"Переместить карту к моему местоположению"</string>
<string name="a11y_notifications_mentions_only">"Только упоминания"</string>
<string name="a11y_notifications_muted">"Без звука"</string>
@@ -34,6 +36,7 @@
<string name="a11y_playback_speed">"Скорость воспроизведения"</string>
<string name="a11y_poll">"Опрос"</string>
<string name="a11y_poll_end">"Завершённый опрос"</string>
<string name="a11y_position">"Позиция: %1$s"</string>
<string name="a11y_qr_code">"QR-код"</string>
<string name="a11y_react_with">"Реагировать вместе с %1$s"</string>
<string name="a11y_react_with_other_emojis">"Реакция с помощью эмодзи"</string>
@@ -50,12 +53,15 @@
<string name="a11y_room_avatar">"Аватар комнаты"</string>
<string name="a11y_send_files">"Отправить файлы"</string>
<string name="a11y_sender_location">"Местоположение отправителя"</string>
<string name="a11y_sent_by_sender_at_date">"Отправлено пользователем %1$s в %2$s"</string>
<string name="a11y_session_verification_time_limited_action_required">"Требуется действие, на которое есть ограничение по времени, у вас есть одна минута для проверки"</string>
<string name="a11y_settings_with_required_action">"Настройки, требуется действие"</string>
<string name="a11y_show_password">"Показать пароль"</string>
<string name="a11y_start_call">"Начать звонок"</string>
<string name="a11y_start_video_call">"Начать видеозвонок"</string>
<string name="a11y_start_voice_call">"Начать голосовой вызов"</string>
<string name="a11y_thread_in_room">"Обсуждение в %1$s"</string>
<string name="a11y_threads_in_room">"Обсуждения в %1$s"</string>
<string name="a11y_tombstoned_room">"Брошенная комната"</string>
<string name="a11y_user_avatar">"Аватар пользователя"</string>
<string name="a11y_user_menu">"Меню пользователя"</string>
@@ -302,6 +308,7 @@
<string name="common_please_wait">"Подождите…"</string>
<string name="common_poll_end_confirmation">"Вы действительно хотите завершить данный опрос?"</string>
<string name="common_poll_summary">"Опрос: %1$s"</string>
<string name="common_poll_summary_prefix">"Опрос"</string>
<string name="common_poll_total_votes">"Всего голосов: %1$s"</string>
<string name="common_poll_undisclosed_text">"Результаты будут показаны после завершения опроса"</string>
<plurals name="common_poll_votes_count">
@@ -96,6 +96,7 @@
<string name="action_decline_and_block">"拒绝并屏蔽"</string>
<string name="action_delete">"删除"</string>
<string name="action_delete_account">"删除账户"</string>
<string name="action_delete_file">"删除文件"</string>
<string name="action_delete_poll">"删除投票"</string>
<string name="action_deselect_all">"取消全选"</string>
<string name="action_disable">"禁用"</string>
@@ -218,7 +219,7 @@
<string name="common_creating_room">"正在创建房间…"</string>
<string name="common_creating_space">"正在创建空间…"</string>
<string name="common_current_user_canceled_knock">"申请已取消"</string>
<string name="common_current_user_left_room">"离开房间"</string>
<string name="common_current_user_left_room">"离开房间"</string>
<string name="common_current_user_left_space">"离开空间"</string>
<string name="common_current_user_rejected_invite">"邀请已拒绝"</string>
<string name="common_decryption_error">"解密错误"</string>
@@ -299,6 +300,7 @@
<string name="common_please_wait">"请稍候…"</string>
<string name="common_poll_end_confirmation">"确定要结束这个投票吗?"</string>
<string name="common_poll_summary">"投票:%1$s"</string>
<string name="common_poll_summary_prefix">"投票"</string>
<string name="common_poll_total_votes">"总票数:%1$s"</string>
<string name="common_poll_undisclosed_text">"结果将在投票结束后显示"</string>
<plurals name="common_poll_votes_count">
@@ -99,6 +99,7 @@
<string name="action_decline_and_block">"Decline and block"</string>
<string name="action_delete">"Delete"</string>
<string name="action_delete_account">"Delete account"</string>
<string name="action_delete_file">"Delete file"</string>
<string name="action_delete_poll">"Delete Poll"</string>
<string name="action_deselect_all">"Deselect all"</string>
<string name="action_disable">"Disable"</string>
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c1ab182dfc2b45c80972722b1963a75c29175c1d09369fafb96c7b0ea04bf08a
size 21171
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fa435ee5d684b82c66c7207e0bcdc2d608a634e02d534530cccf8abd0f40f784
size 21292
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56f7a86707c00d1833ebbb26182ad9f9f010ed8f016713076232d4134c8bb6e7
size 329737
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6907cdde67cfb41246b9b86af19d0d46bf92914b21f9ab68d522f07dd83af153
size 284058
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6ec83baa6376355fcfa1e9a088faee47f5d7d87ed7608bcbe35e7438f9e0cdea
size 257324
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:17bd7ae449ad1fb92c75e09848bddf907d15cfcbbcb9554350893c7a6019add5
size 278513
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e692a9e204db51af62fa83af8c1c7dda4fdfe81077d3abced093f3f8dfdef2df
size 252607
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e881c0e26edfd9f4f2eb7325e307edcd4220aae42337ce8d238cd64c88722de4
size 312002
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c110f007c954fd01fad8d4e9810abae47bb89c330141c7c1d6412d3995943f4b
size 400985
oid sha256:14a4be90563169ef442341a03c8add67df6ad2385b23221f7a484b296d47cab9
size 405385
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:af9841032d9faebbee6f759259ef14b0d4cca3424ac110e1dfd1d3357768e436
size 399354
oid sha256:c15b4ac06b3327c95f4e40556e2c7cc0fdd0de6942dcc41a06545b03f3d7efb9
size 403700
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8fae17aad6ac7dfb2fd2fac83c2c1b6d9e0743fa9d3d1a874fe269284149ce29
size 62760
oid sha256:608236a6a1864f0036fb0d2bcd85d7269557dc3453876495585573471d08d2de
size 65085
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c110f007c954fd01fad8d4e9810abae47bb89c330141c7c1d6412d3995943f4b
size 400985
oid sha256:14a4be90563169ef442341a03c8add67df6ad2385b23221f7a484b296d47cab9
size 405385
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dbcda50596ea08167fda422fae89758bc46c719cd320103def3c90cea0a152ff
size 62616
oid sha256:116502f69435e6d7a5fe9fe9a2a604fcca36d1c6e1e09836595769cf8e8022d9
size 64937
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b1172f37d89f97ec0360402c013328ad65bfb62422d5b81a8d06e9d8dc3cbba
size 67739
oid sha256:eb69e3738018bd6138e1f04478b5f7b5758816b9516f871dc8643ea037ba1c65
size 71377
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:29d6a3980b5928907e5d5203ba4a5010feed5ca67107ef464933717664d72fb1
size 71937
oid sha256:130c46b4bd3589cc6a6e45a04f9793b742631daf21cbbf971f8e79a00f589ce8
size 329628
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:df744636336e3b7dcf4b8c20a3a9dcf70247ea0a5602c11665bb020925c94dd1
size 407934
oid sha256:6bea145d686c295829e91a0a19e4172155ddd03ae62730241ee55e3c759d5f88
size 75505
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ea59b97a710eab6b10192373c7058b301e0d2b4bfe07d16f952d69593b8b78d7
size 88581
oid sha256:7587dfe56eb8de6c4ed8117ad9bf1066cd53b5e89430be66a9b9f3ae357343fe
size 412192
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a1a324578ba710175ade8d54b2f99e8103b893d7a3e7d1353ddc2b2c0c3a285
size 91939
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:08984e24e297742f065201c4cea3d07eda34e4c80fbcb4689e539ac64f32f1db
size 53795
oid sha256:a2d68bc8db6190fbd5205fdaa386c250ae3a2014804a5372052d851a313a6ef1
size 47808
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:26f2620aa348febb2db9ebe379a964b76220819f7165fa7a5be5e2a38c2534a2
size 67183
oid sha256:cdde4c4250683a2cf63988a92dc03cbc64581794c9f25567ecca61675edea9dc
size 64428
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:168c2399ac6262c65e1026e3c79fe2c93dd6805ac73b9bc26adfaad8afeab724
size 53258
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:950b6b93b0b31d0bef28e6b7ff0759e1e6e3ee48fac8278035665247f1176e8b
size 51887
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7d53770762a7b2477787fb21acb17303b671d549b4eab5f54ccbf6d1c566aa50
size 53023
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:32abcd8e957508558dde739c881f2ce9efac648404c420aac44127d0b449d5c4
size 53000
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f6bf8bb2491b685153fb11542be0de2a95cdd00ab294cf0bf882e890f8f5f697
size 48682
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c4f67eb6df70b214682b9b337886cee1653c3804be2b3a6ed581247c22fc0d5f
size 44778
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c9ebab37f3d289cd684d616961b2f4b993a851a34bb8d41ce889443ce51c4c5f
size 53981
oid sha256:32abcd8e957508558dde739c881f2ce9efac648404c420aac44127d0b449d5c4
size 53000
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:058a2ef322426a6c996698c5c0df64f8d4cec5107b918101478a6f478897c3c1
size 46365
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d578725c9ef0c37be7115017fe1b7f7da41c02a54f932ee389d4683f2ec3f524
size 48465
oid sha256:78109755f9bb674e0b026f8696dcc5024e1aa07838d404954e17edcf8d752e80
size 47441
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e949b9fc728afe5da33073a5273aebe797a7c45a68fc6049e9292d0a256adad7
size 49632
oid sha256:288f3c3887439cfe8b4fea6ba7b5091c2342cf9e962ad2ddbbeea99243feddaf
size 48577
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e949b9fc728afe5da33073a5273aebe797a7c45a68fc6049e9292d0a256adad7
size 49632
oid sha256:288f3c3887439cfe8b4fea6ba7b5091c2342cf9e962ad2ddbbeea99243feddaf
size 48577
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c9ebab37f3d289cd684d616961b2f4b993a851a34bb8d41ce889443ce51c4c5f
size 53981
oid sha256:32abcd8e957508558dde739c881f2ce9efac648404c420aac44127d0b449d5c4
size 53000
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:23548dc4c9b3ede93580ce56989ff05d4317605aaa584744f73a5897d0cd6c51
size 46743
oid sha256:56fbcdd514a6fc964e0713ee18490f801bee4b5b91f1ebbf9471262af37830e1
size 45656
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a284cc8503c3cd6227afbd593d36e6f9a9eeadbd323b5cf66d77e3b5eeb6681
size 51713
oid sha256:a2bc82e2fa80c56ef65b462421c4b0204e6077547226b799c5a9a47367a1dfb2
size 50724
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c9ebab37f3d289cd684d616961b2f4b993a851a34bb8d41ce889443ce51c4c5f
size 53981
oid sha256:32abcd8e957508558dde739c881f2ce9efac648404c420aac44127d0b449d5c4
size 53000
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c9ebab37f3d289cd684d616961b2f4b993a851a34bb8d41ce889443ce51c4c5f
size 53981
oid sha256:32abcd8e957508558dde739c881f2ce9efac648404c420aac44127d0b449d5c4
size 53000
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f935cbeb516a345549877793ed1e0e5d82b0b1b81b65d54f028d8ee30a3eeb7c
size 50075
oid sha256:b3309c34f8127f41b85f915246d87b257befd909c6ea13151f018f2af838cee3
size 55553
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:54c0d5db8026616d766d1ceb94fbac1c3588be1ac3baa38e05ef4f665aa9419f
size 115721
oid sha256:4d11dbfc86f54a219d989672e5a5f2c729e1373706be22256aa913d3a2f67eb8
size 116355
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f8efca7b9be49bd84f809fac58de983e6126714914250ce4b0dcb96a56125bb7
size 46915
oid sha256:2a786030fface63e75009179d2473c5ec880cfb194ba43a85f2bbef3090a205b
size 52774
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f935cbeb516a345549877793ed1e0e5d82b0b1b81b65d54f028d8ee30a3eeb7c
size 50075
oid sha256:b3309c34f8127f41b85f915246d87b257befd909c6ea13151f018f2af838cee3
size 55553
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a3d7c97667774e00e618be65e63423d9d62c8b30dfe95cddad1d5dc62255e38c
size 39638
oid sha256:90360b93852bbcbcf694f892075401d9019f0b28f34abbe24f3546a9db62fd81
size 44307
+1083 -1067
View File
File diff suppressed because it is too large Load Diff
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c755a7dcfc2c9f48d449e570a3f1af1cde299fd90ddd4478e9a4c315cf03128
size 23810
oid sha256:aec4d2f2ec1b277afa895e47739b503d86b3104d315b6d20fce223324c57f51b
size 23960
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:efa5408c3af0fcd39659b8d30b21ace43be46d2876815ad592f802a7887b5eb9
size 23678
oid sha256:82f48053958a8bd72245365ee0cc4c1649c5c06dde6f66c95c23bf5009edd2f3
size 23879
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1fc512e71e168473e0e976be3e3e6cd24b455273257ad0adf970fc2641da43bb
size 25679
oid sha256:e50eaee3dc1512f76566d1170c2db8a07230d7c9f159c5f52c43ac9e810e2a72
size 25938
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:de71af50bba66a285b5ef44e1a4fe76ce6dc2e094c4c09ddf701deb9a5db898d
size 22025
oid sha256:3abd359bba25e19e231d723cc3de7dcf394c35a5948a935b2703d81940e00120
size 22391
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:88b3583d55c6855027f13a152a6fc414f6b9e11d65e5b5403463b84fafe38c3f
size 21891
oid sha256:4910c5904a53dacc578b32d0033e3fe64fa084602b62dff13930b68ee83e0cf5
size 22298
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e64367832735139b68269a8c679b9c6f2b929b906124a0ee93735cbdd9202d6d
size 23826
oid sha256:82ed1ed8042d4d6f9633144cc5f34567cfc09c6303e005a7157954917837054d
size 24160
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9e74b9b1819bf778ddb397a40113f71b2eb0ada0dcb26af85dab26bbc53ed079
size 54210
oid sha256:6833382305574e875ab2b5cbfa0ae441d06e405ae64f69a8b9de6e2f3da96922
size 54461
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a4e56509b4f10e97283d25432edd7be4b511987f0879acc3026ac16dab25b75c
size 54012
oid sha256:45d4703616e98579df79f9d23f1f0c954f937b75f7eeab1452675b8eaa3c0770
size 54266
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fe76cc652842cce967d975fae7a387f5cff118153b345bda452d5dbc618b22f8
size 52255
oid sha256:ea4983028fd8b8044df7d87125d49346bca92920217f14b7ce2aaac9dbe8af4b
size 52534
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f2d17c9021392f93fc022ce0ba4305f0739acaeab3ebfd51b7d3294ace365807
size 51156
oid sha256:86cd78d9ac357bfcbc017440b57e1d643255b6ffbe47e78c3df197405c185495
size 51522
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:286af36457c34621e10b91226b13c5a9fde77af6b63827d39a0a95697972d4ab
size 50896
oid sha256:ff899eb696998139c0b28b1596aa71fcb477cc534892bbfdeb81405412a6121b
size 51286

Some files were not shown because too many files have changed in this diff Show More