From 313d3a732d2ef250c387e3160c9edb3be32c6666 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:16:43 +0300 Subject: [PATCH 1/4] multiplatform: images and fonts (#2656) * multiplatform: images and fonts * update desktop app name and comment --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- .../java/chat/simplex/app/MainActivity.kt | 4 +- .../java/chat/simplex/app/model/ChatModel.kt | 11 +- .../java/chat/simplex/app/model/SimpleXAPI.kt | 52 +++--- .../java/chat/simplex/app/ui/theme/Type.kt | 16 +- .../java/chat/simplex/app/views/SplashView.kt | 2 +- .../chat/simplex/app/views/WelcomeView.kt | 6 +- .../chat/simplex/app/views/call/CallView.kt | 20 +-- .../app/views/call/IncomingCallActivity.kt | 12 +- .../app/views/call/IncomingCallAlertView.kt | 12 +- .../simplex/app/views/chat/ChatInfoView.kt | 26 +-- .../app/views/chat/ChatItemInfoView.kt | 6 +- .../chat/simplex/app/views/chat/ChatView.kt | 18 +- .../simplex/app/views/chat/ComposeFileView.kt | 6 +- .../app/views/chat/ComposeImageView.kt | 6 +- .../simplex/app/views/chat/ComposeView.kt | 8 +- .../app/views/chat/ComposeVoiceView.kt | 6 +- .../simplex/app/views/chat/ContextItemView.kt | 6 +- .../simplex/app/views/chat/SendMsgView.kt | 19 +- .../simplex/app/views/chat/VerifyCodeView.kt | 12 +- .../views/chat/group/AddGroupMembersView.kt | 14 +- .../app/views/chat/group/GroupChatInfoView.kt | 22 +-- .../app/views/chat/group/GroupLinkView.kt | 8 +- .../views/chat/group/GroupMemberInfoView.kt | 10 +- .../views/chat/group/WelcomeMessageView.kt | 6 +- .../app/views/chat/item/CICallItemView.kt | 18 +- .../simplex/app/views/chat/item/CIFileView.kt | 20 +-- .../views/chat/item/CIGroupInvitationView.kt | 2 +- .../app/views/chat/item/CIImageView.kt | 16 +- .../app/views/chat/item/CIInvalidJSONView.kt | 4 +- .../simplex/app/views/chat/item/CIMetaView.kt | 10 +- .../app/views/chat/item/CIVideoView.kt | 20 +-- .../app/views/chat/item/CIVoiceView.kt | 9 +- .../app/views/chat/item/ChatItemView.kt | 24 +-- .../app/views/chat/item/FramedItemView.kt | 8 +- .../app/views/chatlist/ChatHelpView.kt | 4 +- .../app/views/chatlist/ChatListNavLinkView.kt | 31 ++-- .../app/views/chatlist/ChatListView.kt | 15 +- .../app/views/chatlist/ChatPreviewView.kt | 25 +-- .../views/chatlist/ContactConnectionView.kt | 6 +- .../app/views/chatlist/ShareListView.kt | 8 +- .../simplex/app/views/chatlist/UserPicker.kt | 12 +- .../app/views/database/ChatArchiveView.kt | 6 +- .../views/database/DatabaseEncryptionView.kt | 8 +- .../app/views/database/DatabaseView.kt | 18 +- .../app/views/helpers/ChatInfoImage.kt | 15 +- .../app/views/helpers/ChooseAttachmentView.kt | 10 +- .../app/views/helpers/CustomTimePicker.kt | 4 +- .../views/helpers/DefaultBasicTextField.kt | 9 +- .../app/views/helpers/DefaultTopAppBar.kt | 8 +- .../helpers/ExposedDropDownSettingRow.kt | 4 +- .../simplex/app/views/helpers/GetImageView.kt | 6 +- .../simplex/app/views/helpers/LinkPreviews.kt | 4 +- .../simplex/app/views/helpers/ModalView.kt | 2 +- .../app/views/helpers/SearchTextField.kt | 4 +- .../chat/simplex/app/views/helpers/Section.kt | 6 +- .../simplex/app/views/helpers/SimpleButton.kt | 7 +- .../app/views/localauth/PasscodeView.kt | 10 +- .../app/views/localauth/PasswordEntry.kt | 12 +- .../app/views/newchat/AddContactView.kt | 10 +- .../simplex/app/views/newchat/AddGroupView.kt | 4 +- .../app/views/newchat/ConnectViaLinkView.kt | 4 +- .../newchat/ContactConnectionInfoView.kt | 4 +- .../app/views/newchat/CreateLinkView.kt | 4 +- .../simplex/app/views/newchat/NewChatSheet.kt | 8 +- .../app/views/newchat/PasteToConnect.kt | 8 +- .../views/onboarding/CreateSimpleXAddress.kt | 10 +- .../app/views/onboarding/SimpleXInfo.kt | 14 +- .../app/views/onboarding/WhatsNewView.kt | 75 ++++---- .../usersettings/AdvancedNetworkSettings.kt | 11 +- .../app/views/usersettings/Appearance.kt | 20 +-- .../app/views/usersettings/DeveloperView.kt | 6 +- .../views/usersettings/NetworkAndServers.kt | 25 ++- .../app/views/usersettings/PrivacySettings.kt | 10 +- .../views/usersettings/ProtocolServerView.kt | 10 +- .../views/usersettings/ProtocolServersView.kt | 10 +- .../app/views/usersettings/RTCServers.kt | 4 +- .../app/views/usersettings/SettingsView.kt | 56 +++--- .../app/views/usersettings/UserAddressView.kt | 16 +- .../app/views/usersettings/UserProfileView.kt | 6 +- .../views/usersettings/UserProfilesView.kt | 16 +- .../res/drawable/ic_account_circle_filled.xml | 9 - .../android/src/main/res/drawable/ic_add.xml | 9 - .../src/main/res/drawable/ic_add_link.xml | 9 - .../src/main/res/drawable/ic_add_photo.xml | 9 - .../src/main/res/drawable/ic_add_reaction.xml | 9 - .../res/drawable/ic_add_reaction_filled.xml | 9 - .../main/res/drawable/ic_all_inclusive.xml | 9 - .../res/drawable/ic_arrow_back_ios_new.xml | 9 - .../main/res/drawable/ic_arrow_downward.xml | 9 - .../res/drawable/ic_arrow_forward_ios.xml | 9 - .../src/main/res/drawable/ic_arrow_upward.xml | 9 - .../src/main/res/drawable/ic_article.xml | 9 - .../drawable/ic_attach_file_filled_500.xml | 9 - .../src/main/res/drawable/ic_backspace.xml | 9 - .../src/main/res/drawable/ic_backup.xml | 9 - .../main/res/drawable/ic_battery_2_bar.xml | 9 - .../main/res/drawable/ic_battery_3_bar.xml | 9 - .../android/src/main/res/drawable/ic_bolt.xml | 9 - .../src/main/res/drawable/ic_bolt_filled.xml | 9 - .../src/main/res/drawable/ic_cable.xml | 9 - .../android/src/main/res/drawable/ic_call.xml | 9 - .../src/main/res/drawable/ic_call_500.xml | 9 - .../src/main/res/drawable/ic_call_end.xml | 9 - .../src/main/res/drawable/ic_call_filled.xml | 9 - .../main/res/drawable/ic_camera_enhance.xml | 9 - .../main/res/drawable/ic_cancel_filled.xml | 9 - .../android/src/main/res/drawable/ic_chat.xml | 9 - .../src/main/res/drawable/ic_check.xml | 9 - .../res/drawable/ic_check_circle_filled.xml | 9 - .../src/main/res/drawable/ic_check_fill.xml | 9 - .../main/res/drawable/ic_chevron_right.xml | 9 - .../src/main/res/drawable/ic_circle.xml | 9 - .../main/res/drawable/ic_circle_filled.xml | 9 - .../android/src/main/res/drawable/ic_code.xml | 9 - .../src/main/res/drawable/ic_content_copy.xml | 9 - .../main/res/drawable/ic_content_paste.xml | 9 - .../src/main/res/drawable/ic_database.xml | 9 - .../src/main/res/drawable/ic_delete.xml | 9 - .../main/res/drawable/ic_delete_forever.xml | 9 - .../res/drawable/ic_delete_forever_filled.xml | 9 - .../android/src/main/res/drawable/ic_dns.xml | 9 - .../res/drawable/ic_do_not_disturb_on.xml | 9 - .../src/main/res/drawable/ic_done_filled.xml | 9 - .../src/main/res/drawable/ic_download.xml | 9 - .../src/main/res/drawable/ic_draft.xml | 9 - .../src/main/res/drawable/ic_draft_filled.xml | 9 - .../res/drawable/ic_drive_folder_upload.xml | 9 - .../android/src/main/res/drawable/ic_edit.xml | 9 - .../src/main/res/drawable/ic_edit_filled.xml | 9 - .../src/main/res/drawable/ic_edit_note.xml | 9 - .../res/drawable/ic_electrical_services.xml | 9 - .../src/main/res/drawable/ic_error.xml | 9 - .../src/main/res/drawable/ic_error_filled.xml | 9 - .../src/main/res/drawable/ic_expand_less.xml | 9 - .../src/main/res/drawable/ic_expand_more.xml | 9 - .../src/main/res/drawable/ic_filter_list.xml | 4 - .../android/src/main/res/drawable/ic_flag.xml | 9 - .../ic_flip_camera_android_filled.xml | 9 - .../src/main/res/drawable/ic_github.xml | 22 --- .../src/main/res/drawable/ic_group.xml | 9 - .../android/src/main/res/drawable/ic_help.xml | 9 - .../src/main/res/drawable/ic_image.xml | 9 - .../android/src/main/res/drawable/ic_info.xml | 9 - .../src/main/res/drawable/ic_inventory_2.xml | 9 - .../src/main/res/drawable/ic_ios_share.xml | 9 - .../src/main/res/drawable/ic_keyboard.xml | 9 - .../res/drawable/ic_keyboard_arrow_down.xml | 9 - .../main/res/drawable/ic_keyboard_voice.xml | 9 - .../res/drawable/ic_keyboard_voice_filled.xml | 9 - .../res/drawable/ic_launcher_background.xml | 170 ------------------ .../src/main/res/drawable/ic_light_mode.xml | 9 - .../android/src/main/res/drawable/ic_link.xml | 9 - .../src/main/res/drawable/ic_lock_filled.xml | 9 - .../src/main/res/drawable/ic_lock_open.xml | 9 - .../src/main/res/drawable/ic_login.xml | 9 - .../src/main/res/drawable/ic_logout.xml | 9 - .../android/src/main/res/drawable/ic_mail.xml | 9 - .../main/res/drawable/ic_manage_accounts.xml | 9 - .../src/main/res/drawable/ic_maps_ugc.xml | 9 - .../main/res/drawable/ic_mark_chat_unread.xml | 9 - .../android/src/main/res/drawable/ic_menu.xml | 9 - .../android/src/main/res/drawable/ic_mic.xml | 9 - .../src/main/res/drawable/ic_mic_filled.xml | 9 - .../src/main/res/drawable/ic_mic_off.xml | 9 - .../src/main/res/drawable/ic_more_horiz.xml | 9 - .../src/main/res/drawable/ic_note_add.xml | 9 - .../main/res/drawable/ic_notifications.xml | 9 - .../res/drawable/ic_notifications_off.xml | 9 - .../drawable/ic_notifications_off_filled.xml | 9 - .../src/main/res/drawable/ic_open_in_new.xml | 9 - .../main/res/drawable/ic_outline_terminal.xml | 10 -- .../src/main/res/drawable/ic_pause_filled.xml | 9 - .../src/main/res/drawable/ic_pending.xml | 9 - .../main/res/drawable/ic_pending_filled.xml | 9 - .../src/main/res/drawable/ic_person.xml | 9 - .../src/main/res/drawable/ic_person_add.xml | 9 - .../main/res/drawable/ic_person_add_500.xml | 9 - .../res/drawable/ic_phone_in_talk_filled.xml | 9 - .../src/main/res/drawable/ic_photo_camera.xml | 9 - .../res/drawable/ic_play_arrow_filled.xml | 9 - .../res/drawable/ic_power_settings_new.xml | 4 - .../main/res/drawable/ic_priority_high.xml | 9 - .../src/main/res/drawable/ic_qr_code.xml | 9 - .../src/main/res/drawable/ic_repeat_one.xml | 9 - .../src/main/res/drawable/ic_replay.xml | 9 - .../src/main/res/drawable/ic_reply.xml | 9 - .../main/res/drawable/ic_report_filled.xml | 9 - .../src/main/res/drawable/ic_restart_alt.xml | 4 - .../src/main/res/drawable/ic_ring_volume.xml | 9 - .../main/res/drawable/ic_safety_divider.xml | 9 - .../src/main/res/drawable/ic_search.xml | 9 - .../src/main/res/drawable/ic_search_500.xml | 9 - .../src/main/res/drawable/ic_security.xml | 9 - .../src/main/res/drawable/ic_settings.xml | 9 - .../drawable/ic_settings_backup_restore.xml | 9 - .../res/drawable/ic_settings_ethernet.xml | 9 - .../main/res/drawable/ic_settings_phone.xml | 9 - .../src/main/res/drawable/ic_share.xml | 9 - .../src/main/res/drawable/ic_share_filled.xml | 9 - .../src/main/res/drawable/ic_shield.xml | 9 - .../main/res/drawable/ic_smart_display.xml | 9 - .../android/src/main/res/drawable/ic_star.xml | 9 - .../src/main/res/drawable/ic_star_filled.xml | 9 - .../src/main/res/drawable/ic_star_off.xml | 9 - .../src/main/res/drawable/ic_stop_filled.xml | 9 - .../ic_supervised_user_circle_filled.xml | 9 - .../drawable/ic_swap_horizontal_circle.xml | 9 - .../ic_swap_horizontal_circle_filled.xml | 9 - .../android/src/main/res/drawable/ic_tag.xml | 9 - .../android/src/main/res/drawable/ic_task.xml | 9 - .../main/res/drawable/ic_theater_comedy.xml | 9 - .../res/drawable/ic_theater_comedy_filled.xml | 9 - .../src/main/res/drawable/ic_timer.xml | 9 - .../src/main/res/drawable/ic_timer_filled.xml | 9 - .../src/main/res/drawable/ic_toggle_on.xml | 9 - .../src/main/res/drawable/ic_translate.xml | 9 - .../main/res/drawable/ic_travel_explore.xml | 9 - .../src/main/res/drawable/ic_upload_file.xml | 9 - .../main/res/drawable/ic_verified_user.xml | 9 - .../src/main/res/drawable/ic_videocam.xml | 9 - .../main/res/drawable/ic_videocam_filled.xml | 9 - .../src/main/res/drawable/ic_videocam_off.xml | 9 - .../src/main/res/drawable/ic_visibility.xml | 9 - .../res/drawable/ic_visibility_filled.xml | 9 - .../main/res/drawable/ic_visibility_off.xml | 9 - .../res/drawable/ic_visibility_off_filled.xml | 9 - .../src/main/res/drawable/ic_volume_down.xml | 9 - .../src/main/res/drawable/ic_volume_up.xml | 9 - .../main/res/drawable/ic_vpn_key_filled.xml | 9 - .../res/drawable/ic_vpn_key_off_filled.xml | 9 - .../main/res/drawable/ic_warning_filled.xml | 9 - .../main/res/drawable/ic_wifi_tethering.xml | 9 - .../drawable/icon_dark_blue_round_common.png | Bin 0 -> 9870 bytes .../icon_foreground_android_common.png | Bin 0 -> 25226 bytes .../res/drawable/icon_round_common.png | Bin 0 -> 11666 bytes .../res/drawable/send_msg_view_background.xml | 12 ++ .../src/androidMain/res/raw/ring_once.mp3 | Bin 0 -> 72269 bytes .../resources/MR/fonts/Inter-Bold.ttf} | Bin .../resources/MR/fonts/Inter-Italic.ttf} | Bin .../resources/MR/fonts/Inter-Light.ttf} | Bin .../resources/MR/fonts/Inter-Medium.ttf} | Bin .../resources/MR/fonts/Inter-Regular.ttf} | Bin .../resources/MR/fonts/Inter-Semibold.ttf} | Bin .../MR/images/decentralized@1.5x.png} | Bin .../resources/MR/images/decentralized@1x.png} | Bin .../resources/MR/images/decentralized@2x.png} | Bin .../resources/MR/images/decentralized@3x.png} | Bin .../resources/MR/images/decentralized@4x.png} | Bin .../MR/images/decentralized_light@1.5x.png} | Bin .../MR/images/decentralized_light@1x.png} | Bin .../MR/images/decentralized_light@2x.png} | Bin .../MR/images/decentralized_light@3x.png} | Bin .../MR/images/decentralized_light@4x.png} | Bin .../MR/images/ic_account_circle_filled.svg | 1 + .../commonMain/resources/MR/images/ic_add.svg | 1 + .../resources/MR/images/ic_add_link.svg | 1 + .../resources/MR/images/ic_add_photo.svg | 1 + .../resources/MR/images/ic_add_reaction.svg | 1 + .../MR/images/ic_add_reaction_filled.svg | 1 + .../resources/MR/images/ic_all_inclusive.svg | 1 + .../MR/images/ic_arrow_back_ios_new.svg | 1 + .../resources/MR/images/ic_arrow_downward.svg | 1 + .../MR/images/ic_arrow_forward_ios.svg | 1 + .../resources/MR/images/ic_arrow_upward.svg | 1 + .../resources/MR/images/ic_article.svg | 1 + .../MR/images/ic_attach_file_filled.svg | 1 + .../MR/images/ic_attach_file_filled_500.svg | 1 + .../resources/MR/images/ic_backspace.svg | 1 + .../resources/MR/images/ic_backup.svg | 1 + .../resources/MR/images/ic_battery_2_bar.svg | 1 + .../resources/MR/images/ic_battery_3_bar.svg | 1 + .../resources/MR/images/ic_bolt.svg | 1 + .../resources/MR/images/ic_bolt_filled.svg | 1 + .../resources/MR/images/ic_cable.svg | 1 + .../resources/MR/images/ic_call.svg | 1 + .../resources/MR/images/ic_call_500.svg | 1 + .../resources/MR/images/ic_call_end.svg | 1 + .../MR/images/ic_call_end_filled.svg | 1 + .../resources/MR/images/ic_call_filled.svg | 1 + .../resources/MR/images/ic_camera_enhance.svg | 1 + .../resources/MR/images/ic_cancel_filled.svg | 1 + .../resources/MR/images/ic_chat.svg | 1 + .../resources/MR/images/ic_check.svg | 1 + .../MR/images/ic_check_circle_filled.svg | 1 + .../resources/MR/images/ic_check_filled.svg | 1 + .../resources/MR/images/ic_chevron_right.svg | 1 + .../resources/MR/images/ic_circle.svg | 1 + .../resources/MR/images/ic_circle_filled.svg | 1 + .../resources/MR/images/ic_close.svg | 1 + .../resources/MR/images/ic_code.svg | 1 + .../resources/MR/images/ic_content_copy.svg | 1 + .../resources/MR/images/ic_content_paste.svg | 1 + .../resources/MR/images/ic_database.svg | 1 + .../resources/MR/images/ic_delete.svg | 1 + .../resources/MR/images/ic_delete_forever.svg | 1 + .../MR/images/ic_delete_forever_filled.svg | 1 + .../commonMain/resources/MR/images/ic_dns.svg | 1 + .../MR/images/ic_do_not_disturb_on.svg | 1 + .../resources/MR/images/ic_done_filled.svg | 1 + .../resources/MR/images/ic_download.svg | 1 + .../resources/MR/images/ic_draft.svg | 1 + .../resources/MR/images/ic_draft_filled.svg | 1 + .../MR/images/ic_drive_folder_upload.svg | 1 + .../resources/MR/images/ic_edit.svg | 1 + .../resources/MR/images/ic_edit_filled.svg | 1 + .../resources/MR/images/ic_edit_note.svg | 1 + .../MR/images/ic_electrical_services.svg | 1 + .../resources/MR/images/ic_error.svg | 1 + .../resources/MR/images/ic_error_filled.svg | 1 + .../resources/MR/images/ic_expand_less.svg | 1 + .../resources/MR/images/ic_expand_more.svg | 1 + .../resources/MR/images/ic_filter_list.svg | 1 + .../resources/MR/images/ic_flag.svg | 1 + .../images/ic_flip_camera_android_filled.svg | 1 + .../resources/MR/images/ic_folder_open.svg | 1 + .../resources/MR/images/ic_github.svg | 1 + .../resources/MR/images/ic_group.svg | 1 + .../resources/MR/images/ic_help.svg | 1 + .../resources/MR/images/ic_image.svg | 1 + .../resources/MR/images/ic_info.svg | 1 + .../resources/MR/images/ic_inventory_2.svg | 1 + .../resources/MR/images/ic_ios_share.svg | 1 + .../resources/MR/images/ic_keyboard.svg | 1 + .../MR/images/ic_keyboard_arrow_down.svg | 1 + .../resources/MR/images/ic_keyboard_voice.svg | 1 + .../MR/images/ic_keyboard_voice_filled.svg | 1 + .../resources/MR/images/ic_light_mode.svg | 1 + .../resources/MR/images/ic_link.svg | 1 + .../resources/MR/images/ic_lock.svg | 1 + .../resources/MR/images/ic_lock_filled.svg | 1 + .../resources/MR/images/ic_lock_open.svg | 1 + .../resources/MR/images/ic_login.svg | 1 + .../resources/MR/images/ic_logout.svg | 1 + .../resources/MR/images/ic_mail.svg | 1 + .../MR/images/ic_manage_accounts.svg | 1 + .../resources/MR/images/ic_maps_ugc.svg | 1 + .../MR/images/ic_mark_chat_unread.svg | 1 + .../resources/MR/images/ic_menu.svg | 1 + .../commonMain/resources/MR/images/ic_mic.svg | 1 + .../resources/MR/images/ic_mic_filled.svg | 1 + .../resources/MR/images/ic_mic_off.svg | 1 + .../resources/MR/images/ic_more_horiz.svg | 1 + .../resources/MR/images/ic_more_vert.svg | 1 + .../resources/MR/images/ic_note_add.svg | 1 + .../resources/MR/images/ic_notifications.svg | 1 + .../MR/images/ic_notifications_off.svg | 1 + .../MR/images/ic_notifications_off_filled.svg | 1 + .../resources/MR/images/ic_open_in_new.svg | 1 + .../MR/images/ic_outline_terminal.svg | 1 + .../resources/MR/images/ic_pause_filled.svg | 1 + .../resources/MR/images/ic_pending.svg | 1 + .../resources/MR/images/ic_pending_filled.svg | 1 + .../resources/MR/images/ic_person.svg | 1 + .../resources/MR/images/ic_person_add.svg | 1 + .../resources/MR/images/ic_person_add_500.svg | 1 + .../MR/images/ic_phone_in_talk_filled.svg | 1 + .../resources/MR/images/ic_photo_camera.svg | 1 + .../MR/images/ic_play_arrow_filled.svg | 1 + .../MR/images/ic_power_settings_new.svg | 1 + .../resources/MR/images/ic_priority_high.svg | 1 + .../resources/MR/images/ic_qr_code.svg | 1 + .../resources/MR/images/ic_repeat_one.svg | 1 + .../resources/MR/images/ic_replay.svg | 1 + .../resources/MR/images/ic_reply.svg | 1 + .../resources/MR/images/ic_report_filled.svg | 1 + .../resources/MR/images/ic_restart_alt.svg | 1 + .../resources/MR/images/ic_ring_volume.svg | 1 + .../resources/MR/images/ic_safety_divider.svg | 1 + .../resources/MR/images/ic_search.svg | 1 + .../resources/MR/images/ic_search_500.svg | 1 + .../resources/MR/images/ic_security.svg | 1 + .../resources/MR/images/ic_settings.svg | 1 + .../MR/images/ic_settings_backup_restore.svg | 1 + .../MR/images/ic_settings_ethernet.svg | 1 + .../resources/MR/images/ic_settings_phone.svg | 1 + .../resources/MR/images/ic_share.svg | 1 + .../resources/MR/images/ic_share_filled.svg | 1 + .../resources/MR/images/ic_shield.svg | 1 + .../resources/MR/images/ic_smart_display.svg | 1 + .../resources/MR/images/ic_star.svg | 1 + .../resources/MR/images/ic_star_filled.svg | 2 + .../resources/MR/images/ic_star_off.svg | 29 +++ .../resources/MR/images/ic_start.svg | 1 + .../resources/MR/images/ic_stop_filled.svg | 1 + .../ic_supervised_user_circle_filled.svg | 1 + .../MR/images/ic_swap_horizontal_circle.svg | 1 + .../ic_swap_horizontal_circle_filled.svg | 1 + .../commonMain/resources/MR/images/ic_tag.svg | 1 + .../resources/MR/images/ic_task.svg | 1 + .../resources/MR/images/ic_theater_comedy.svg | 1 + .../MR/images/ic_theater_comedy_filled.svg | 1 + .../resources/MR/images/ic_timer.svg | 1 + .../resources/MR/images/ic_timer_filled.svg | 1 + .../resources/MR/images/ic_toggle_on.svg | 1 + .../resources/MR/images/ic_translate.svg | 1 + .../resources/MR/images/ic_travel_explore.svg | 1 + .../resources/MR/images/ic_upload_file.svg | 1 + .../resources/MR/images/ic_verified_user.svg | 1 + .../resources/MR/images/ic_videocam.svg | 1 + .../MR/images/ic_videocam_filled.svg | 1 + .../resources/MR/images/ic_videocam_off.svg | 1 + .../resources/MR/images/ic_visibility.svg | 1 + .../MR/images/ic_visibility_filled.svg | 1 + .../resources/MR/images/ic_visibility_off.svg | 1 + .../MR/images/ic_visibility_off_filled.svg | 1 + .../resources/MR/images/ic_volume_down.svg | 1 + .../resources/MR/images/ic_volume_up.svg | 1 + .../resources/MR/images/ic_vpn_key_filled.svg | 1 + .../MR/images/ic_vpn_key_off_filled.svg | 1 + .../resources/MR/images/ic_warning_filled.svg | 1 + .../resources/MR/images/ic_wifi_tethering.svg | 1 + .../MR/images/icon_foreground_common@4x.png | Bin 0 -> 25226 bytes .../resources/MR/images/logo@4x.png | Bin 0 -> 17601 bytes .../resources/MR/images/logo_light@4x.png | Bin 0 -> 23606 bytes .../resources/MR/images/privacy@1.5x.png} | Bin .../resources/MR/images/privacy@1x.png} | Bin .../resources/MR/images/privacy@2x.png} | Bin .../resources/MR/images/privacy@3x.png} | Bin .../resources/MR/images/privacy@4x.png} | Bin .../resources/MR/images/shield@1.5x.png} | Bin .../resources/MR/images/shield@1x.png} | Bin .../resources/MR/images/shield@2x.png} | Bin .../resources/MR/images/shield@3x.png} | Bin .../resources/MR/images/shield@4x.png} | Bin .../resources/distribute/SimpleX.desktop | 7 + .../resources/distribute/simplex.png | Bin 0 -> 25226 bytes 426 files changed, 707 insertions(+), 2031 deletions(-) delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_account_circle_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_add.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_add_link.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_add_photo.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_add_reaction.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_add_reaction_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_all_inclusive.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_arrow_back_ios_new.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_arrow_downward.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_arrow_forward_ios.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_arrow_upward.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_article.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_attach_file_filled_500.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_backspace.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_backup.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_battery_2_bar.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_battery_3_bar.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_bolt.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_bolt_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_cable.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_call.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_call_500.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_call_end.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_call_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_camera_enhance.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_cancel_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_chat.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_check.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_check_circle_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_check_fill.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_chevron_right.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_circle.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_circle_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_code.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_content_copy.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_content_paste.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_database.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_delete.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_delete_forever.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_delete_forever_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_dns.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_do_not_disturb_on.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_done_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_download.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_draft.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_draft_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_drive_folder_upload.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_edit.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_edit_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_edit_note.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_electrical_services.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_error.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_error_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_expand_less.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_expand_more.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_filter_list.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_flag.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_flip_camera_android_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_github.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_group.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_help.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_image.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_info.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_inventory_2.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_ios_share.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_keyboard.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_keyboard_arrow_down.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_light_mode.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_link.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_lock_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_lock_open.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_login.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_logout.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_mail.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_manage_accounts.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_maps_ugc.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_mark_chat_unread.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_menu.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_mic.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_mic_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_mic_off.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_more_horiz.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_note_add.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_notifications.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_notifications_off.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_notifications_off_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_open_in_new.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_outline_terminal.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_pause_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_pending.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_pending_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_person.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_person_add.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_person_add_500.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_phone_in_talk_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_photo_camera.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_play_arrow_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_power_settings_new.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_priority_high.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_qr_code.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_repeat_one.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_replay.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_reply.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_report_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_restart_alt.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_ring_volume.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_safety_divider.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_search.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_search_500.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_security.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_settings.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_settings_backup_restore.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_settings_ethernet.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_settings_phone.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_share.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_share_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_shield.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_smart_display.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_star.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_star_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_star_off.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_stop_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_supervised_user_circle_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_tag.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_task.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_timer.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_timer_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_toggle_on.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_translate.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_travel_explore.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_upload_file.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_verified_user.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_videocam.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_videocam_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_videocam_off.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_visibility.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_visibility_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_visibility_off.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_visibility_off_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_volume_down.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_volume_up.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_off_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_warning_filled.xml delete mode 100644 apps/multiplatform/android/src/main/res/drawable/ic_wifi_tethering.xml create mode 100644 apps/multiplatform/common/src/androidMain/res/drawable/icon_dark_blue_round_common.png create mode 100644 apps/multiplatform/common/src/androidMain/res/drawable/icon_foreground_android_common.png create mode 100644 apps/multiplatform/common/src/androidMain/res/drawable/icon_round_common.png create mode 100644 apps/multiplatform/common/src/androidMain/res/drawable/send_msg_view_background.xml create mode 100644 apps/multiplatform/common/src/androidMain/res/raw/ring_once.mp3 rename apps/multiplatform/{android/src/main/res/font/inter_bold.ttf => common/src/commonMain/resources/MR/fonts/Inter-Bold.ttf} (100%) rename apps/multiplatform/{android/src/main/res/font/inter_italic.ttf => common/src/commonMain/resources/MR/fonts/Inter-Italic.ttf} (100%) rename apps/multiplatform/{android/src/main/res/font/inter_light.ttf => common/src/commonMain/resources/MR/fonts/Inter-Light.ttf} (100%) rename apps/multiplatform/{android/src/main/res/font/inter_medium.ttf => common/src/commonMain/resources/MR/fonts/Inter-Medium.ttf} (100%) rename apps/multiplatform/{android/src/main/res/font/inter_regular.ttf => common/src/commonMain/resources/MR/fonts/Inter-Regular.ttf} (100%) rename apps/multiplatform/{android/src/main/res/font/inter_semi_bold.ttf => common/src/commonMain/resources/MR/fonts/Inter-Semibold.ttf} (100%) rename apps/multiplatform/{android/src/main/res/drawable-hdpi/decentralized.png => common/src/commonMain/resources/MR/images/decentralized@1.5x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-mdpi/decentralized.png => common/src/commonMain/resources/MR/images/decentralized@1x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xhdpi/decentralized.png => common/src/commonMain/resources/MR/images/decentralized@2x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxhdpi/decentralized.png => common/src/commonMain/resources/MR/images/decentralized@3x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxxhdpi/decentralized.png => common/src/commonMain/resources/MR/images/decentralized@4x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-hdpi/decentralized_light.png => common/src/commonMain/resources/MR/images/decentralized_light@1.5x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-mdpi/decentralized_light.png => common/src/commonMain/resources/MR/images/decentralized_light@1x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xhdpi/decentralized_light.png => common/src/commonMain/resources/MR/images/decentralized_light@2x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxhdpi/decentralized_light.png => common/src/commonMain/resources/MR/images/decentralized_light@3x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxxhdpi/decentralized_light.png => common/src/commonMain/resources/MR/images/decentralized_light@4x.png} (100%) create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_account_circle_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_link.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_photo.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_all_inclusive.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_back_ios_new.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_downward.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_forward_ios.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_upward.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_article.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled_500.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backspace.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backup.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_2_bar.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_3_bar.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cable.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_500.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_camera_enhance.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cancel_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chat.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_circle_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_close.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_code.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_copy.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_paste.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_database.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_dns.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_do_not_disturb_on.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_done_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_download.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_drive_folder_upload.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_note.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_electrical_services.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_less.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_more.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_filter_list.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flag.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flip_camera_android_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_folder_open.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_github.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_group.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_image.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_info.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_inventory_2.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ios_share.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_arrow_down.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_light_mode.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_link.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_open.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_login.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_logout.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mail.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_manage_accounts.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_maps_ugc.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mark_chat_unread.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_menu.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_off.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_horiz.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_vert.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_note_add.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_open_in_new.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_outline_terminal.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pause_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add_500.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_phone_in_talk_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_photo_camera.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_play_arrow_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_power_settings_new.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_priority_high.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_qr_code.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_repeat_one.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_replay.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_reply.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_report_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_restart_alt.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ring_volume.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_safety_divider.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search_500.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_security.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_backup_restore.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_ethernet.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_phone.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_shield.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_smart_display.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_off.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_start.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_stop_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_supervised_user_circle_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_tag.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_task.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_toggle_on.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_translate.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_travel_explore.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_upload_file.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_verified_user.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_off.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_down.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_up.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_off_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_warning_filled.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_wifi_tethering.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/icon_foreground_common@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/logo@4x.png create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/logo_light@4x.png rename apps/multiplatform/{android/src/main/res/drawable-hdpi/privacy.png => common/src/commonMain/resources/MR/images/privacy@1.5x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-mdpi/privacy.png => common/src/commonMain/resources/MR/images/privacy@1x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xhdpi/privacy.png => common/src/commonMain/resources/MR/images/privacy@2x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxhdpi/privacy.png => common/src/commonMain/resources/MR/images/privacy@3x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxxhdpi/privacy.png => common/src/commonMain/resources/MR/images/privacy@4x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-hdpi/shield.png => common/src/commonMain/resources/MR/images/shield@1.5x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-mdpi/shield.png => common/src/commonMain/resources/MR/images/shield@1x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xhdpi/shield.png => common/src/commonMain/resources/MR/images/shield@2x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxhdpi/shield.png => common/src/commonMain/resources/MR/images/shield@3x.png} (100%) rename apps/multiplatform/{android/src/main/res/drawable-xxxhdpi/shield.png => common/src/commonMain/resources/MR/images/shield@4x.png} (100%) create mode 100644 apps/multiplatform/common/src/commonMain/resources/distribute/SimpleX.desktop create mode 100644 apps/multiplatform/common/src/commonMain/resources/distribute/simplex.png diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt index 772a6dd5f7..1b04b1e673 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/MainActivity.kt @@ -17,7 +17,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.fragment.app.FragmentActivity import androidx.lifecycle.* @@ -39,6 +38,7 @@ import chat.simplex.app.views.newchat.* import chat.simplex.app.views.onboarding.* import chat.simplex.app.views.usersettings.LAMode import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.* import kotlinx.coroutines.flow.distinctUntilChanged @@ -435,7 +435,7 @@ fun MainPage( ) { SimpleButton( stringResource(MR.strings.auth_unlock), - icon = painterResource(R.drawable.ic_lock), + icon = painterResource(MR.images.ic_lock), click = { laFailed.value = false runAuthenticate() diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/ChatModel.kt index a4f66c357b..f7ff5a80c8 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -16,6 +16,7 @@ import chat.simplex.app.views.onboarding.OnboardingStage import chat.simplex.app.views.usersettings.NotificationPreviewMode import chat.simplex.app.views.usersettings.NotificationsMode import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource import kotlinx.coroutines.* import kotlinx.datetime.* @@ -1578,12 +1579,12 @@ data class CIMeta ( val isRcvNew: Boolean get() = itemStatus is CIStatus.RcvNew - fun statusIcon(primaryColor: Color, metaColor: Color = CurrentColors.value.colors.secondary): Pair? = + fun statusIcon(primaryColor: Color, metaColor: Color = CurrentColors.value.colors.secondary): Pair? = when (itemStatus) { - is CIStatus.SndSent -> R.drawable.ic_check_filled to metaColor - is CIStatus.SndErrorAuth -> R.drawable.ic_close to Color.Red - is CIStatus.SndError -> R.drawable.ic_warning_filled to WarningYellow - is CIStatus.RcvNew -> R.drawable.ic_circle_filled to primaryColor + is CIStatus.SndSent -> MR.images.ic_check_filled to metaColor + is CIStatus.SndErrorAuth -> MR.images.ic_close to Color.Red + is CIStatus.SndError -> MR.images.ic_warning_filled to WarningYellow + is CIStatus.RcvNew -> MR.images.ic_circle_filled to primaryColor else -> null } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index be21e2d8a9..ba96000544 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -1707,7 +1707,7 @@ object ChatController { title = { Row { Icon( - painterResource(R.drawable.ic_bolt), + painterResource(MR.images.ic_bolt), contentDescription = if (mode == NotificationsMode.SERVICE) stringResource(MR.strings.icon_descr_instant_notifications) else stringResource(MR.strings.periodic_notifications), ) @@ -1744,7 +1744,7 @@ object ChatController { title = { Row { Icon( - painterResource(R.drawable.ic_bolt), + painterResource(MR.images.ic_bolt), contentDescription = if (mode == NotificationsMode.SERVICE) stringResource(MR.strings.icon_descr_instant_notifications) else stringResource(MR.strings.periodic_notifications), ) @@ -1775,7 +1775,7 @@ object ChatController { title = { Row { Icon( - painterResource(R.drawable.ic_bolt), + painterResource(MR.images.ic_bolt), contentDescription = if (mode == NotificationsMode.SERVICE) stringResource(MR.strings.icon_descr_instant_notifications) else stringResource(MR.strings.periodic_notifications), ) @@ -2856,20 +2856,20 @@ enum class ChatFeature: Feature { val icon: Painter @Composable get() = when(this) { - TimedMessages -> painterResource(R.drawable.ic_timer) - FullDelete -> painterResource(R.drawable.ic_delete_forever) - Reactions -> painterResource(R.drawable.ic_add_reaction) - Voice -> painterResource(R.drawable.ic_keyboard_voice) - Calls -> painterResource(R.drawable.ic_call) + TimedMessages -> painterResource(MR.images.ic_timer) + FullDelete -> painterResource(MR.images.ic_delete_forever) + Reactions -> painterResource(MR.images.ic_add_reaction) + Voice -> painterResource(MR.images.ic_keyboard_voice) + Calls -> painterResource(MR.images.ic_call) } @Composable override fun iconFilled(): Painter = when(this) { - TimedMessages -> painterResource(R.drawable.ic_timer_filled) - FullDelete -> painterResource(R.drawable.ic_delete_forever_filled) - Reactions -> painterResource(R.drawable.ic_add_reaction_filled) - Voice -> painterResource(R.drawable.ic_keyboard_voice_filled) - Calls -> painterResource(R.drawable.ic_call_filled) + TimedMessages -> painterResource(MR.images.ic_timer_filled) + FullDelete -> painterResource(MR.images.ic_delete_forever_filled) + Reactions -> painterResource(MR.images.ic_add_reaction_filled) + Voice -> painterResource(MR.images.ic_keyboard_voice_filled) + Calls -> painterResource(MR.images.ic_call_filled) } fun allowDescription(allowed: FeatureAllowed): String = @@ -2962,22 +2962,22 @@ enum class GroupFeature: Feature { val icon: Painter @Composable get() = when(this) { - TimedMessages -> painterResource(R.drawable.ic_timer) - DirectMessages -> painterResource(R.drawable.ic_swap_horizontal_circle) - FullDelete -> painterResource(R.drawable.ic_delete_forever) - Reactions -> painterResource(R.drawable.ic_add_reaction) - Voice -> painterResource(R.drawable.ic_keyboard_voice) - Files -> painterResource(R.drawable.ic_draft) + TimedMessages -> painterResource(MR.images.ic_timer) + DirectMessages -> painterResource(MR.images.ic_swap_horizontal_circle) + FullDelete -> painterResource(MR.images.ic_delete_forever) + Reactions -> painterResource(MR.images.ic_add_reaction) + Voice -> painterResource(MR.images.ic_keyboard_voice) + Files -> painterResource(MR.images.ic_draft) } @Composable override fun iconFilled(): Painter = when(this) { - TimedMessages -> painterResource(R.drawable.ic_timer_filled) - DirectMessages -> painterResource(R.drawable.ic_swap_horizontal_circle_filled) - FullDelete -> painterResource(R.drawable.ic_delete_forever_filled) - Reactions -> painterResource(R.drawable.ic_add_reaction_filled) - Voice -> painterResource(R.drawable.ic_keyboard_voice_filled) - Files -> painterResource(R.drawable.ic_draft_filled) + TimedMessages -> painterResource(MR.images.ic_timer_filled) + DirectMessages -> painterResource(MR.images.ic_swap_horizontal_circle_filled) + FullDelete -> painterResource(MR.images.ic_delete_forever_filled) + Reactions -> painterResource(MR.images.ic_add_reaction_filled) + Voice -> painterResource(MR.images.ic_keyboard_voice_filled) + Files -> painterResource(MR.images.ic_draft_filled) } fun enableDescription(enabled: GroupFeatureEnabled, canEdit: Boolean): String = diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/ui/theme/Type.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/ui/theme/Type.kt index 177a8effad..a67a14d0c1 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/ui/theme/Type.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/ui/theme/Type.kt @@ -4,16 +4,16 @@ import androidx.compose.material.Typography import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.unit.sp -import chat.simplex.app.R +import chat.simplex.res.MR // https://github.com/rsms/inter -val Inter = FontFamily( - Font(R.font.inter_regular), - Font(R.font.inter_italic, style = FontStyle.Italic), - Font(R.font.inter_bold, weight = FontWeight.Bold), - Font(R.font.inter_semi_bold, weight = FontWeight.SemiBold), - Font(R.font.inter_medium, weight = FontWeight.Medium), - Font(R.font.inter_light, weight = FontWeight.Light), +val Inter: FontFamily = FontFamily( + Font(MR.fonts.Inter.regular.fontResourceId), + Font(MR.fonts.Inter.italic.fontResourceId, style = FontStyle.Italic), + Font(MR.fonts.Inter.bold.fontResourceId, FontWeight.Bold), + Font(MR.fonts.Inter.semibold.fontResourceId, FontWeight.SemiBold), + Font(MR.fonts.Inter.medium.fontResourceId, FontWeight.Medium), + Font(MR.fonts.Inter.light.fontResourceId, FontWeight.Light) ) // Set of Material typography styles to start with diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/SplashView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/SplashView.kt index a831bcc3a9..9491ea75e0 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/SplashView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/SplashView.kt @@ -14,7 +14,7 @@ fun SplashView() { color = MaterialTheme.colors.background ) { // Image( -// painter = painterResource(R.drawable.logo), +// painter = painterResource(MR.images.logo), // contentDescription = "Simplex Icon", // modifier = Modifier // .height(230.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/WelcomeView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/WelcomeView.kt index 5156155120..57ca136cf0 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/WelcomeView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/WelcomeView.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -88,7 +88,7 @@ fun CreateProfilePanel(chatModel: ChatModel, close: () -> Unit) { if (chatModel.users.isEmpty()) { SimpleButtonDecorated( text = stringResource(MR.strings.about_simplex), - icon = painterResource(R.drawable.ic_arrow_back_ios_new), + icon = painterResource(MR.images.ic_arrow_back_ios_new), textDecoration = TextDecoration.None, fontWeight = FontWeight.Medium ) { chatModel.onboardingStage.value = OnboardingStage.Step1_SimpleXInfo } @@ -107,7 +107,7 @@ fun CreateProfilePanel(chatModel: ChatModel, close: () -> Unit) { Surface(shape = RoundedCornerShape(20.dp), color = Color.Transparent) { Row(verticalAlignment = Alignment.CenterVertically, modifier = createModifier) { Text(stringResource(MR.strings.create_profile_button), style = MaterialTheme.typography.caption, color = createColor, fontWeight = FontWeight.Medium) - Icon(painterResource(R.drawable.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = createColor) + Icon(painterResource(MR.images.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = createColor) } } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallView.kt index bcebcdd580..e69d4c54f1 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallView.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview @@ -273,14 +273,14 @@ private fun ActiveCallOverlayLayout( ToggleAudioButton(call, toggleAudio) Spacer(Modifier.size(40.dp)) IconButton(onClick = dismiss) { - Icon(painterResource(R.drawable.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = Color.Red, modifier = Modifier.size(64.dp)) + Icon(painterResource(MR.images.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = Color.Red, modifier = Modifier.size(64.dp)) } if (call.videoEnabled) { - ControlButton(call, painterResource(R.drawable.ic_flip_camera_android_filled), MR.strings.icon_descr_flip_camera, flipCamera) - ControlButton(call, painterResource(R.drawable.ic_videocam_filled), MR.strings.icon_descr_video_off, toggleVideo) + ControlButton(call, painterResource(MR.images.ic_flip_camera_android_filled), MR.strings.icon_descr_flip_camera, flipCamera) + ControlButton(call, painterResource(MR.images.ic_videocam_filled), MR.strings.icon_descr_video_off, toggleVideo) } else { Spacer(Modifier.size(48.dp)) - ControlButton(call, painterResource(R.drawable.ic_videocam_off), MR.strings.icon_descr_video_on, toggleVideo) + ControlButton(call, painterResource(MR.images.ic_videocam_off), MR.strings.icon_descr_video_on, toggleVideo) } } } @@ -298,7 +298,7 @@ private fun ActiveCallOverlayLayout( Box(Modifier.fillMaxWidth().padding(bottom = DEFAULT_BOTTOM_PADDING), contentAlignment = Alignment.CenterStart) { Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { IconButton(onClick = dismiss) { - Icon(painterResource(R.drawable.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = Color.Red, modifier = Modifier.size(64.dp)) + Icon(painterResource(MR.images.ic_call_end_filled), stringResource(MR.strings.icon_descr_hang_up), tint = Color.Red, modifier = Modifier.size(64.dp)) } } Box(Modifier.padding(start = 32.dp)) { @@ -329,18 +329,18 @@ private fun ControlButton(call: Call, icon: Painter, iconText: StringResource, a @Composable private fun ToggleAudioButton(call: Call, toggleAudio: () -> Unit) { if (call.audioEnabled) { - ControlButton(call, painterResource(R.drawable.ic_mic), MR.strings.icon_descr_audio_off, toggleAudio) + ControlButton(call, painterResource(MR.images.ic_mic), MR.strings.icon_descr_audio_off, toggleAudio) } else { - ControlButton(call, painterResource(R.drawable.ic_mic_off), MR.strings.icon_descr_audio_on, toggleAudio) + ControlButton(call, painterResource(MR.images.ic_mic_off), MR.strings.icon_descr_audio_on, toggleAudio) } } @Composable private fun ToggleSoundButton(call: Call, enabled: Boolean, toggleSound: () -> Unit) { if (call.soundSpeaker) { - ControlButton(call, painterResource(R.drawable.ic_volume_up), MR.strings.icon_descr_speaker_off, toggleSound, enabled) + ControlButton(call, painterResource(MR.images.ic_volume_up), MR.strings.icon_descr_speaker_off, toggleSound, enabled) } else { - ControlButton(call, painterResource(R.drawable.ic_volume_down), MR.strings.icon_descr_speaker_on, toggleSound, enabled) + ControlButton(call, painterResource(MR.images.ic_volume_down), MR.strings.icon_descr_speaker_on, toggleSound, enabled) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallActivity.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallActivity.kt index 95181e0509..d2ffc507e0 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallActivity.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallActivity.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -171,18 +171,18 @@ fun IncomingCallLockScreenAlertLayout( Text(invitation.contact.chatViewName, style = MaterialTheme.typography.h2) Spacer(Modifier.fillMaxHeight().weight(1f)) Row { - LockScreenCallButton(stringResource(MR.strings.reject), painterResource(R.drawable.ic_call_end_filled), Color.Red, rejectCall) + LockScreenCallButton(stringResource(MR.strings.reject), painterResource(MR.images.ic_call_end_filled), Color.Red, rejectCall) Spacer(Modifier.size(48.dp)) - LockScreenCallButton(stringResource(MR.strings.ignore), painterResource(R.drawable.ic_close), MaterialTheme.colors.primary, ignoreCall) + LockScreenCallButton(stringResource(MR.strings.ignore), painterResource(MR.images.ic_close), MaterialTheme.colors.primary, ignoreCall) Spacer(Modifier.size(48.dp)) - LockScreenCallButton(stringResource(MR.strings.accept), painterResource(R.drawable.ic_check_filled), SimplexGreen, acceptCall) + LockScreenCallButton(stringResource(MR.strings.accept), painterResource(MR.images.ic_check_filled), SimplexGreen, acceptCall) } } else if (callOnLockScreen == CallOnLockScreen.SHOW) { SimpleXLogo() Text(stringResource(MR.strings.open_simplex_chat_to_accept_call), textAlign = TextAlign.Center, lineHeight = 22.sp) Text(stringResource(MR.strings.allow_accepting_calls_from_lock_screen), textAlign = TextAlign.Center, style = MaterialTheme.typography.body2, lineHeight = 22.sp) Spacer(Modifier.fillMaxHeight().weight(1f)) - SimpleButton(text = stringResource(MR.strings.open_verb), icon = painterResource(R.drawable.ic_check_filled), click = openApp) + SimpleButton(text = stringResource(MR.strings.open_verb), icon = painterResource(MR.images.ic_check_filled), click = openApp) } } } @@ -190,7 +190,7 @@ fun IncomingCallLockScreenAlertLayout( @Composable private fun SimpleXLogo() { Image( - painter = painterResource(if (isInDarkTheme()) R.drawable.logo_light else R.drawable.logo), + painter = painterResource(if (isInDarkTheme()) MR.images.logo_light else MR.images.logo), contentDescription = stringResource(MR.strings.image_descr_simplex_logo), modifier = Modifier .padding(vertical = DEFAULT_PADDING) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallAlertView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallAlertView.kt index b7e663954e..532ecda9c6 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallAlertView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/IncomingCallAlertView.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -60,9 +60,9 @@ fun IncomingCallAlertLayout( ProfilePreview(profileOf = invitation.contact, size = 64.dp) } Row(verticalAlignment = Alignment.CenterVertically) { - CallButton(stringResource(MR.strings.reject), painterResource(R.drawable.ic_call_end_filled), Color.Red, rejectCall) - CallButton(stringResource(MR.strings.ignore), painterResource(R.drawable.ic_close), MaterialTheme.colors.primary, ignoreCall) - CallButton(stringResource(MR.strings.accept), painterResource(R.drawable.ic_check_filled), SimplexGreen, acceptCall) + CallButton(stringResource(MR.strings.reject), painterResource(MR.images.ic_call_end_filled), Color.Red, rejectCall) + CallButton(stringResource(MR.strings.ignore), painterResource(MR.images.ic_close), MaterialTheme.colors.primary, ignoreCall) + CallButton(stringResource(MR.strings.accept), painterResource(MR.images.ic_check_filled), SimplexGreen, acceptCall) } } } @@ -76,8 +76,8 @@ fun IncomingCallInfo(invitation: RcvCallInvitation, chatModel: ChatModel) { ProfileImage(size = 32.dp, image = invitation.user.profile.image, color = MaterialTheme.colors.secondaryVariant) Spacer(Modifier.width(4.dp)) } - if (invitation.callType.media == CallMediaType.Video) CallIcon(painterResource(R.drawable.ic_videocam_filled), stringResource(MR.strings.icon_descr_video_call)) - else CallIcon(painterResource(R.drawable.ic_call_filled), stringResource(MR.strings.icon_descr_audio_call)) + if (invitation.callType.media == CallMediaType.Video) CallIcon(painterResource(MR.images.ic_videocam_filled), stringResource(MR.strings.icon_descr_video_call)) + else CallIcon(painterResource(MR.images.ic_call_filled), stringResource(MR.strings.icon_descr_audio_call)) Spacer(Modifier.width(4.dp)) Text(invitation.callTypeText, color = MaterialTheme.colors.onBackground) } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index b6ff8c2c49..f7e28ff365 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextStyle @@ -275,7 +275,7 @@ fun ChatInfoHeader(cInfo: ChatInfo, contact: Contact) { ChatInfoImage(cInfo, size = 192.dp, iconColor = if (isInDarkTheme()) GroupDark else SettingsSecondaryLight) Row(Modifier.padding(bottom = 8.dp), verticalAlignment = Alignment.CenterVertically) { if (contact.verified) { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.padding(end = 6.dp, top = 4.dp).size(24.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.padding(end = 6.dp, top = 4.dp).size(24.dp), tint = MaterialTheme.colors.secondary) } Text( contact.profile.displayName, style = MaterialTheme.typography.h1.copy(fontWeight = FontWeight.Normal), @@ -320,7 +320,7 @@ fun LocalAliasEditor( ) }, leadingIcon = if (leadingIcon) { - { Icon(painterResource(R.drawable.ic_edit_filled), null, Modifier.padding(start = 7.dp)) } + { Icon(painterResource(MR.images.ic_edit_filled), null, Modifier.padding(start = 7.dp)) } } else null, color = MaterialTheme.colors.secondary, focus = focus, @@ -357,7 +357,7 @@ private fun NetworkStatusRow(networkStatus: NetworkStatus) { ) { Text(stringResource(MR.strings.network_status)) Icon( - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), stringResource(MR.strings.network_status), tint = MaterialTheme.colors.primary ) @@ -381,12 +381,12 @@ private fun ServerImage(networkStatus: NetworkStatus) { Box(Modifier.size(18.dp)) { when (networkStatus) { is NetworkStatus.Connected -> - Icon(painterResource(R.drawable.ic_circle_filled), stringResource(MR.strings.icon_descr_server_status_connected), tint = Color.Green) + Icon(painterResource(MR.images.ic_circle_filled), stringResource(MR.strings.icon_descr_server_status_connected), tint = Color.Green) is NetworkStatus.Disconnected -> - Icon(painterResource(R.drawable.ic_pending_filled), stringResource(MR.strings.icon_descr_server_status_disconnected), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_pending_filled), stringResource(MR.strings.icon_descr_server_status_disconnected), tint = MaterialTheme.colors.secondary) is NetworkStatus.Error -> - Icon(painterResource(R.drawable.ic_error_filled), stringResource(MR.strings.icon_descr_server_status_error), tint = MaterialTheme.colors.secondary) - else -> Icon(painterResource(R.drawable.ic_circle), stringResource(MR.strings.icon_descr_server_status_pending), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_error_filled), stringResource(MR.strings.icon_descr_server_status_error), tint = MaterialTheme.colors.secondary) + else -> Icon(painterResource(MR.images.ic_circle), stringResource(MR.strings.icon_descr_server_status_pending), tint = MaterialTheme.colors.secondary) } } } @@ -424,7 +424,7 @@ fun AbortSwitchAddressButton(disabled: Boolean, abortSwitchAddress: () -> Unit) @Composable fun VerifyCodeButton(contactVerified: Boolean, onClick: () -> Unit) { SettingsActionItem( - if (contactVerified) painterResource(R.drawable.ic_verified_user) else painterResource(R.drawable.ic_shield), + if (contactVerified) painterResource(MR.images.ic_verified_user) else painterResource(MR.images.ic_shield), stringResource(if (contactVerified) MR.strings.view_security_code else MR.strings.verify_security_code), click = onClick, iconColor = MaterialTheme.colors.secondary, @@ -434,7 +434,7 @@ fun VerifyCodeButton(contactVerified: Boolean, onClick: () -> Unit) { @Composable private fun ContactPreferencesButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_toggle_on), + painterResource(MR.images.ic_toggle_on), stringResource(MR.strings.contact_preferences), click = onClick ) @@ -443,7 +443,7 @@ private fun ContactPreferencesButton(onClick: () -> Unit) { @Composable fun ClearChatButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_settings_backup_restore), + painterResource(MR.images.ic_settings_backup_restore), stringResource(MR.strings.clear_chat_button), click = onClick, textColor = WarningOrange, @@ -454,7 +454,7 @@ fun ClearChatButton(onClick: () -> Unit) { @Composable private fun DeleteContactButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.button_delete_contact), click = onClick, textColor = Color.Red, @@ -465,7 +465,7 @@ private fun DeleteContactButton(onClick: () -> Unit) { @Composable fun ShareAddressButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_share_filled), + painterResource(MR.images.ic_share_filled), stringResource(MR.strings.share_address), onClick, iconColor = MaterialTheme.colors.primary, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatItemInfoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatItemInfoView.kt index 97a8da402f..6eebb7901d 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatItemInfoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatItemInfoView.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.unit.dp @@ -81,11 +81,11 @@ fun ChatItemInfoView(ci: ChatItem, ciInfo: ChatItemInfo, devTools: Boolean) { } if (text != "") { DefaultDropdownMenu(showMenu) { - ItemAction(stringResource(MR.strings.share_verb), painterResource(R.drawable.ic_share), onClick = { + ItemAction(stringResource(MR.strings.share_verb), painterResource(MR.images.ic_share), onClick = { shareText(text) showMenu.value = false }) - ItemAction(stringResource(MR.strings.copy_verb), painterResource(R.drawable.ic_content_copy), onClick = { + ItemAction(stringResource(MR.strings.copy_verb), painterResource(MR.images.ic_content_copy), onClick = { copyText(text) showMenu.value = false }) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatView.kt index 8ffaac1535..6f7b61725c 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ChatView.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.font.FontWeight @@ -422,7 +422,7 @@ fun ChatInfoToolbar( val barButtons = arrayListOf<@Composable RowScope.() -> Unit>() val menuItems = arrayListOf<@Composable () -> Unit>() menuItems.add { - ItemAction(stringResource(MR.strings.search_verb).capitalize(Locale.current), painterResource(R.drawable.ic_search), onClick = { + ItemAction(stringResource(MR.strings.search_verb).capitalize(Locale.current), painterResource(MR.images.ic_search), onClick = { showMenu.value = false showSearch = true }) @@ -434,11 +434,11 @@ fun ChatInfoToolbar( showMenu.value = false startCall(CallMediaType.Audio) }) { - Icon(painterResource(R.drawable.ic_call_500), stringResource(MR.strings.icon_descr_more_button), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_call_500), stringResource(MR.strings.icon_descr_more_button), tint = MaterialTheme.colors.primary) } } menuItems.add { - ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(R.drawable.ic_videocam), onClick = { + ItemAction(stringResource(MR.strings.icon_descr_video_call).capitalize(Locale.current), painterResource(MR.images.ic_videocam), onClick = { showMenu.value = false startCall(CallMediaType.Video) }) @@ -449,7 +449,7 @@ fun ChatInfoToolbar( showMenu.value = false addMembers(chat.chatInfo.groupInfo) }) { - Icon(painterResource(R.drawable.ic_person_add_500), stringResource(MR.strings.icon_descr_add_members), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_person_add_500), stringResource(MR.strings.icon_descr_add_members), tint = MaterialTheme.colors.primary) } } } @@ -457,7 +457,7 @@ fun ChatInfoToolbar( menuItems.add { ItemAction( if (ntfsEnabled.value) stringResource(MR.strings.mute_chat) else stringResource(MR.strings.unmute_chat), - if (ntfsEnabled.value) painterResource(R.drawable.ic_notifications_off) else painterResource(R.drawable.ic_notifications), + if (ntfsEnabled.value) painterResource(MR.images.ic_notifications_off) else painterResource(MR.images.ic_notifications), onClick = { showMenu.value = false // Just to make a delay before changing state of ntfsEnabled, otherwise it will redraw menu item with new value before closing the menu @@ -528,7 +528,7 @@ fun ChatInfoToolbarTitle(cInfo: ChatInfo, imageSize: Dp = 40.dp, iconColor: Colo @Composable private fun ContactVerifiedShield() { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.size(18.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(18.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) } data class CIListState(val scrolled: Boolean, val itemCount: Int, val keyboardState: KeyboardState) @@ -830,7 +830,7 @@ fun BoxWithConstraintsScope.FloatingButtons( DefaultDropdownMenu(showDropDown, offset = DpOffset(maxWidth - DEFAULT_PADDING, 24.dp + fabSize)) { ItemAction( generalGetString(MR.strings.mark_read), - painterResource(R.drawable.ic_check), + painterResource(MR.images.ic_check), onClick = { markRead( CC.ItemRange(minUnreadItemId, chatItems[chatItems.size - listState.layoutInfo.visibleItemsInfo.lastIndex - 1].id - 1), @@ -937,7 +937,7 @@ private fun bottomEndFloatingButton( backgroundColor = MaterialTheme.colors.secondaryVariant, ) { Icon( - painter = painterResource(R.drawable.ic_keyboard_arrow_down), + painter = painterResource(MR.images.ic_keyboard_arrow_down), contentDescription = null, tint = MaterialTheme.colors.primary ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeFileView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeFileView.kt index 5b51f74a88..8043b7c8e8 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeFileView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeFileView.kt @@ -5,7 +5,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -25,7 +25,7 @@ fun ComposeFileView(fileName: String, cancelFile: () -> Unit, cancelEnabled: Boo verticalAlignment = Alignment.CenterVertically ) { Icon( - painterResource(R.drawable.ic_draft_filled), + painterResource(MR.images.ic_draft_filled), stringResource(MR.strings.icon_descr_file), Modifier .padding(start = 4.dp, end = 2.dp) @@ -37,7 +37,7 @@ fun ComposeFileView(fileName: String, cancelFile: () -> Unit, cancelEnabled: Boo if (cancelEnabled) { IconButton(onClick = cancelFile, modifier = Modifier.padding(0.dp)) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.icon_descr_cancel_file_preview), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(10.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeImageView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeImageView.kt index 14750c04b1..3c36a6e2af 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeImageView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeImageView.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.app.R @@ -45,7 +45,7 @@ fun ComposeImageView(media: ComposePreview.MediaPreview, cancelImages: () -> Uni modifier = Modifier.widthIn(max = 80.dp).height(60.dp) ) Icon( - painterResource(R.drawable.ic_videocam_filled), + painterResource(MR.images.ic_videocam_filled), "preview video", Modifier .size(20.dp), @@ -65,7 +65,7 @@ fun ComposeImageView(media: ComposePreview.MediaPreview, cancelImages: () -> Uni if (cancelEnabled) { IconButton(onClick = cancelImages) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.icon_descr_cancel_image_preview), tint = MaterialTheme.colors.primary, ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeView.kt index a57c2c611b..f0569c6661 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeView.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat @@ -660,10 +660,10 @@ fun ComposeView( fun contextItemView() { when (val contextItem = composeState.value.contextItem) { ComposeContextItem.NoContextItem -> {} - is ComposeContextItem.QuotedItem -> ContextItemView(contextItem.chatItem, painterResource(R.drawable.ic_reply)) { + is ComposeContextItem.QuotedItem -> ContextItemView(contextItem.chatItem, painterResource(MR.images.ic_reply)) { composeState.value = composeState.value.copy(contextItem = ComposeContextItem.NoContextItem) } - is ComposeContextItem.EditingItem -> ContextItemView(contextItem.chatItem, painterResource(R.drawable.ic_edit_filled)) { + is ComposeContextItem.EditingItem -> ContextItemView(contextItem.chatItem, painterResource(MR.images.ic_edit_filled)) { clearState() } } @@ -728,7 +728,7 @@ fun ComposeView( } IconButton(attachmentClicked, enabled = !composeState.value.attachmentDisabled && rememberUpdatedState(chat.userCanSend).value) { Icon( - painterResource(R.drawable.ic_attach_file_filled_500), + painterResource(MR.images.ic_attach_file_filled_500), contentDescription = stringResource(MR.strings.attach), tint = if (!composeState.value.attachmentDisabled && userCanSend.value && !isGroupAndProhibitedFiles) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeVoiceView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeVoiceView.kt index dc293af439..6ea0b345f8 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeVoiceView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ComposeVoiceView.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -58,7 +58,7 @@ fun ComposeVoiceView( enabled = finishedRecording ) { Icon( - if (audioPlaying.value) painterResource(R.drawable.ic_pause_filled) else painterResource(R.drawable.ic_play_arrow_filled), + if (audioPlaying.value) painterResource(MR.images.ic_pause_filled) else painterResource(MR.images.ic_play_arrow_filled), stringResource(MR.strings.icon_descr_file), Modifier .padding(start = 4.dp, end = 2.dp) @@ -90,7 +90,7 @@ fun ComposeVoiceView( modifier = Modifier.padding(0.dp) ) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.icon_descr_cancel_file_preview), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(10.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ContextItemView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ContextItemView.kt index fda4893d47..a92db078c3 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ContextItemView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/ContextItemView.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -59,7 +59,7 @@ fun ContextItemView( } IconButton(onClick = cancelContextItem) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.cancel_verb), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(10.dp) @@ -74,7 +74,7 @@ fun PreviewContextItemView() { SimpleXTheme { ContextItemView( contextItem = ChatItem.getSampleData(1, CIDirection.DirectRcv(), Clock.System.now(), "hello"), - contextIcon = painterResource(R.drawable.ic_edit_filled) + contextIcon = painterResource(MR.images.ic_edit_filled) ) {} } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/SendMsgView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/SendMsgView.kt index 6565ad2908..4c2bf1ca27 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/SendMsgView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/SendMsgView.kt @@ -50,6 +50,7 @@ import chat.simplex.app.views.helpers.* import com.google.accompanist.permissions.rememberMultiplePermissionsState import chat.simplex.res.MR import dev.icerock.moko.resources.StringResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.* import java.lang.reflect.Field @@ -160,7 +161,7 @@ fun SendMsgView( } else -> { val cs = composeState.value - val icon = if (cs.editing || cs.liveMessage != null) painterResource(R.drawable.ic_check_filled) else painterResource(R.drawable.ic_arrow_upward) + val icon = if (cs.editing || cs.liveMessage != null) painterResource(MR.images.ic_check_filled) else painterResource(MR.images.ic_arrow_upward) val disabled = !cs.sendEnabled() || (!allowedVoiceByPrefs && cs.preview is ComposePreview.VoicePreview) || cs.endLiveDisabled @@ -191,7 +192,7 @@ fun SendMsgView( menuItems.add { ItemAction( generalGetString(MR.strings.disappearing_message), - painterResource(R.drawable.ic_timer), + painterResource(MR.images.ic_timer), onClick = { showCustomDisappearingMessageDialog.value = true showDropdown.value = false @@ -281,7 +282,7 @@ private fun CustomDisappearingMessageDialog( color = MaterialTheme.colors.secondary ) Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), generalGetString(MR.strings.icon_descr_close_button), tint = MaterialTheme.colors.secondary, modifier = Modifier @@ -436,7 +437,7 @@ private fun BoxScope.DeleteTextButton(composeState: MutableState) { composeState.value = composeState.value.copy(message = "") }, Modifier.align(Alignment.TopEnd).size(36.dp) ) { - Icon(painterResource(R.drawable.ic_close), null, Modifier.padding(7.dp).size(36.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_close), null, Modifier.padding(7.dp).size(36.dp), tint = MaterialTheme.colors.secondary) } } @@ -493,7 +494,7 @@ private fun RecordVoiceView(recState: MutableState, stopRecOnNex private fun DisallowedVoiceButton(enabled: Boolean, onClick: () -> Unit) { IconButton(onClick, Modifier.size(36.dp), enabled = enabled) { Icon( - painterResource(R.drawable.ic_keyboard_voice), + painterResource(MR.images.ic_keyboard_voice), stringResource(MR.strings.icon_descr_record_voice_message), tint = MaterialTheme.colors.secondary, modifier = Modifier @@ -507,7 +508,7 @@ private fun DisallowedVoiceButton(enabled: Boolean, onClick: () -> Unit) { private fun VoiceButtonWithoutPermission(onClick: () -> Unit) { IconButton(onClick, Modifier.size(36.dp)) { Icon( - painterResource(R.drawable.ic_keyboard_voice_filled), + painterResource(MR.images.ic_keyboard_voice_filled), stringResource(MR.strings.icon_descr_record_voice_message), tint = MaterialTheme.colors.primary, modifier = Modifier @@ -539,7 +540,7 @@ private fun LockToCurrentOrientationUntilDispose() { private fun StopRecordButton(onClick: () -> Unit) { IconButton(onClick, Modifier.size(36.dp)) { Icon( - painterResource(R.drawable.ic_stop_filled), + painterResource(MR.images.ic_stop_filled), stringResource(MR.strings.icon_descr_record_voice_message), tint = MaterialTheme.colors.primary, modifier = Modifier @@ -553,7 +554,7 @@ private fun StopRecordButton(onClick: () -> Unit) { private fun RecordVoiceButton(interactionSource: MutableInteractionSource) { IconButton({}, Modifier.size(36.dp), interactionSource = interactionSource) { Icon( - painterResource(R.drawable.ic_keyboard_voice_filled), + painterResource(MR.images.ic_keyboard_voice_filled), stringResource(MR.strings.icon_descr_record_voice_message), tint = MaterialTheme.colors.primary, modifier = Modifier @@ -574,7 +575,7 @@ private fun CancelLiveMessageButton( ) { IconButton(onClick, Modifier.size(36.dp)) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), stringResource(MR.strings.icon_descr_cancel_live_message), tint = MaterialTheme.colors.primary, modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/VerifyCodeView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/VerifyCodeView.kt index 48b2e80e06..9a122f360b 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/VerifyCodeView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/VerifyCodeView.kt @@ -10,7 +10,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp @@ -65,7 +65,7 @@ private fun VerifyCodeLayout( val splitCode = splitToParts(connectionCode, 24) Row(Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF), horizontalArrangement = Arrangement.Center) { if (connectionVerified) { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.padding(end = 4.dp).size(22.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.padding(end = 4.dp).size(22.dp), tint = MaterialTheme.colors.secondary) Text(String.format(stringResource(MR.strings.is_verified), displayName)) } else { Text(String.format(stringResource(MR.strings.is_not_verified), displayName)) @@ -88,7 +88,7 @@ private fun VerifyCodeLayout( } Box(Modifier.weight(1f)) { IconButton({ shareText(connectionCode) }, Modifier.size(20.dp).align(Alignment.CenterStart)) { - Icon(painterResource(R.drawable.ic_share_filled), null, tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_share_filled), null, tint = MaterialTheme.colors.primary) } } Spacer(Modifier.weight(1f)) @@ -104,16 +104,16 @@ private fun VerifyCodeLayout( horizontalArrangement = Arrangement.spacedBy(10.dp) ) { if (connectionVerified) { - SimpleButton(generalGetString(MR.strings.clear_verification), painterResource(R.drawable.ic_shield)) { + SimpleButton(generalGetString(MR.strings.clear_verification), painterResource(MR.images.ic_shield)) { verifyCode(null) {} } } else { - SimpleButton(generalGetString(MR.strings.scan_code), painterResource(R.drawable.ic_qr_code)) { + SimpleButton(generalGetString(MR.strings.scan_code), painterResource(MR.images.ic_qr_code)) { ModalManager.shared.showModal { ScanCodeView(verifyCode) { } } } - SimpleButton(generalGetString(MR.strings.mark_code_verified), painterResource(R.drawable.ic_verified_user)) { + SimpleButton(generalGetString(MR.strings.mark_code_verified), painterResource(MR.images.ic_verified_user)) { verifyCode(connectionCode) { verified -> if (!verified) { AlertManager.shared.showAlertMsg( diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/AddGroupMembersView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/AddGroupMembersView.kt index 764621f4a1..555d6c4a2e 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/AddGroupMembersView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/AddGroupMembersView.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextOverflow @@ -180,7 +180,7 @@ private fun SearchRowView( selectedContactsSize: Int ) { Box(Modifier.width(36.dp), contentAlignment = Alignment.Center) { - Icon(painterResource(R.drawable.ic_search), stringResource(MR.strings.search_verb), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_search), stringResource(MR.strings.search_verb), tint = MaterialTheme.colors.secondary) } Spacer(Modifier.width(DEFAULT_SPACE_AFTER_ICON)) SearchTextField(Modifier.fillMaxWidth(), searchText = searchText, alwaysVisible = true) { @@ -214,7 +214,7 @@ private fun RoleSelectionRow(groupInfo: GroupInfo, selectedRole: MutableState Unit, disabled: Boolean) { SettingsActionItem( - painterResource(R.drawable.ic_check), + painterResource(MR.images.ic_check), stringResource(MR.strings.invite_to_group_button), click = onClick, textColor = MaterialTheme.colors.primary, @@ -226,7 +226,7 @@ fun InviteMembersButton(onClick: () -> Unit, disabled: Boolean) { @Composable fun SkipInvitingButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_check), + painterResource(MR.images.ic_check), stringResource(MR.strings.skip_inviting_button), click = onClick, textColor = MaterialTheme.colors.primary, @@ -299,13 +299,13 @@ fun ContactCheckRow( val icon: Painter val iconColor: Color if (prohibitedToInviteIncognito) { - icon = painterResource(R.drawable.ic_theater_comedy_filled) + icon = painterResource(MR.images.ic_theater_comedy_filled) iconColor = MaterialTheme.colors.secondary } else if (checked) { - icon = painterResource(R.drawable.ic_check_circle_filled) + icon = painterResource(MR.images.ic_check_circle_filled) iconColor = if (enabled) MaterialTheme.colors.primary else MaterialTheme.colors.secondary } else { - icon = painterResource(R.drawable.ic_circle) + icon = painterResource(MR.images.ic_circle) iconColor = MaterialTheme.colors.secondary } SectionItemView( diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt index b5b972b959..a2c8d21684 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt @@ -17,7 +17,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.TextFieldValue @@ -260,7 +260,7 @@ private fun GroupChatInfoHeader(cInfo: ChatInfo) { @Composable private fun GroupPreferencesButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_toggle_on), + painterResource(MR.images.ic_toggle_on), stringResource(MR.strings.group_preferences), click = onClick ) @@ -269,7 +269,7 @@ private fun GroupPreferencesButton(onClick: () -> Unit) { @Composable private fun AddMembersButton(tint: Color = MaterialTheme.colors.primary, onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_add), + painterResource(MR.images.ic_add), stringResource(MR.strings.button_add_members), onClick, iconColor = tint, @@ -333,13 +333,13 @@ private fun MemberRow(member: GroupMember, user: Boolean = false) { @Composable private fun MemberVerifiedShield() { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.padding(end = 3.dp).size(16.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.padding(end = 3.dp).size(16.dp), tint = MaterialTheme.colors.secondary) } @Composable private fun GroupLinkButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_link), + painterResource(MR.images.ic_link), stringResource(MR.strings.group_link), onClick, iconColor = MaterialTheme.colors.secondary @@ -349,7 +349,7 @@ private fun GroupLinkButton(onClick: () -> Unit) { @Composable private fun CreateGroupLinkButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_add_link), + painterResource(MR.images.ic_add_link), stringResource(MR.strings.create_group_link), onClick, iconColor = MaterialTheme.colors.secondary @@ -359,7 +359,7 @@ private fun CreateGroupLinkButton(onClick: () -> Unit) { @Composable fun EditGroupProfileButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_edit), + painterResource(MR.images.ic_edit), stringResource(MR.strings.button_edit_group_profile), onClick, iconColor = MaterialTheme.colors.secondary @@ -374,7 +374,7 @@ private fun AddOrEditWelcomeMessage(welcomeMessage: String?, onClick: () -> Unit stringResource(MR.strings.button_welcome_message) } SettingsActionItem( - painterResource(R.drawable.ic_maps_ugc), + painterResource(MR.images.ic_maps_ugc), text, onClick, iconColor = MaterialTheme.colors.secondary @@ -384,7 +384,7 @@ private fun AddOrEditWelcomeMessage(welcomeMessage: String?, onClick: () -> Unit @Composable private fun LeaveGroupButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_logout), + painterResource(MR.images.ic_logout), stringResource(MR.strings.button_leave_group), onClick, iconColor = Color.Red, @@ -395,7 +395,7 @@ private fun LeaveGroupButton(onClick: () -> Unit) { @Composable private fun DeleteGroupButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.button_delete_group), onClick, iconColor = Color.Red, @@ -408,7 +408,7 @@ private fun SearchRowView( searchText: MutableState = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) } ) { Box(Modifier.width(36.dp), contentAlignment = Alignment.Center) { - Icon(painterResource(R.drawable.ic_search), stringResource(MR.strings.search_verb), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_search), stringResource(MR.strings.search_verb), tint = MaterialTheme.colors.secondary) } Spacer(Modifier.width(14.dp)) SearchTextField(Modifier.fillMaxWidth(), searchText = searchText, alwaysVisible = true) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt index f473ac4cbd..025251cd8b 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt @@ -10,7 +10,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -113,7 +113,7 @@ fun GroupLinkLayout( verticalArrangement = Arrangement.SpaceEvenly ) { if (groupLink == null) { - SimpleButton(stringResource(MR.strings.button_create_group_link), icon = painterResource(R.drawable.ic_add_link), disabled = creatingLink, click = createLink) + SimpleButton(stringResource(MR.strings.button_create_group_link), icon = painterResource(MR.images.ic_add_link), disabled = creatingLink, click = createLink) } else { RoleSelectionRow(groupInfo, groupLinkMemberRole) var initialLaunch by remember { mutableStateOf(true) } @@ -131,12 +131,12 @@ fun GroupLinkLayout( ) { SimpleButton( stringResource(MR.strings.share_link), - icon = painterResource(R.drawable.ic_share), + icon = painterResource(MR.images.ic_share), click = share ) SimpleButton( stringResource(MR.strings.delete_link), - icon = painterResource(R.drawable.ic_delete), + icon = painterResource(MR.images.ic_delete), color = Color.Red, click = deleteLink ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt index a9a29f011d..8c17466312 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -301,7 +301,7 @@ fun GroupMemberInfoHeader(member: GroupMember) { ProfileImage(size = 192.dp, member.image, color = if (isInDarkTheme()) GroupDark else SettingsSecondaryLight) Row(verticalAlignment = Alignment.CenterVertically) { if (member.verified) { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.padding(end = 6.dp, top = 4.dp).size(24.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.padding(end = 6.dp, top = 4.dp).size(24.dp), tint = MaterialTheme.colors.secondary) } Text( member.displayName, style = MaterialTheme.typography.h1.copy(fontWeight = FontWeight.Normal), @@ -324,7 +324,7 @@ fun GroupMemberInfoHeader(member: GroupMember) { @Composable fun RemoveMemberButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.button_remove_member), click = onClick, textColor = Color.Red, @@ -335,7 +335,7 @@ fun RemoveMemberButton(onClick: () -> Unit) { @Composable fun OpenChatButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_chat), + painterResource(MR.images.ic_chat), stringResource(MR.strings.button_send_direct_message), click = onClick, textColor = MaterialTheme.colors.primary, @@ -346,7 +346,7 @@ fun OpenChatButton(onClick: () -> Unit) { @Composable fun ConnectViaAddressButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_link), + painterResource(MR.images.ic_link), stringResource(MR.strings.connect_button), click = onClick, textColor = MaterialTheme.colors.primary, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/WelcomeMessageView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/WelcomeMessageView.kt index 8875b61dfc..7cd7c9ca38 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/WelcomeMessageView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/group/WelcomeMessageView.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -141,7 +141,7 @@ private fun SaveButton(save: () -> Unit, disabled: Boolean) { private fun ChangeModeButton(editMode: Boolean, click: () -> Unit, disabled: Boolean) { SectionItemView(click, disabled = disabled) { Icon( - painterResource(if (editMode) R.drawable.ic_visibility else R.drawable.ic_edit), + painterResource(if (editMode) MR.images.ic_visibility else MR.images.ic_edit), contentDescription = generalGetString(MR.strings.edit_verb), tint = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary, ) @@ -157,7 +157,7 @@ private fun ChangeModeButton(editMode: Boolean, click: () -> Unit, disabled: Boo private fun CopyTextButton(click: () -> Unit) { SectionItemView(click) { Icon( - painterResource(R.drawable.ic_content_copy), + painterResource(MR.images.ic_content_copy), contentDescription = generalGetString(MR.strings.copy_verb), tint = MaterialTheme.colors.primary, ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CICallItemView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CICallItemView.kt index 12d2b9e5e5..b2f2245d23 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CICallItemView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CICallItemView.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -22,20 +22,20 @@ fun CICallItemView(cInfo: ChatInfo, cItem: ChatItem, status: CICallStatus, durat Modifier .padding(horizontal = 4.dp) .padding(bottom = 8.dp), horizontalAlignment = Alignment.CenterHorizontally) { - @Composable fun ConnectingCallIcon() = Icon(painterResource(R.drawable.ic_settings_phone), stringResource(MR.strings.icon_descr_call_connecting), tint = SimplexGreen) + @Composable fun ConnectingCallIcon() = Icon(painterResource(MR.images.ic_settings_phone), stringResource(MR.strings.icon_descr_call_connecting), tint = SimplexGreen) when (status) { CICallStatus.Pending -> if (sent) { - Icon(painterResource(R.drawable.ic_call), stringResource(MR.strings.icon_descr_call_pending_sent)) + Icon(painterResource(MR.images.ic_call), stringResource(MR.strings.icon_descr_call_pending_sent)) } else { AcceptCallButton(cInfo, acceptCall) } - CICallStatus.Missed -> Icon(painterResource(R.drawable.ic_call), stringResource(MR.strings.icon_descr_call_missed), tint = Color.Red) - CICallStatus.Rejected -> Icon(painterResource(R.drawable.ic_call_end), stringResource(MR.strings.icon_descr_call_rejected), tint = Color.Red) + CICallStatus.Missed -> Icon(painterResource(MR.images.ic_call), stringResource(MR.strings.icon_descr_call_missed), tint = Color.Red) + CICallStatus.Rejected -> Icon(painterResource(MR.images.ic_call_end), stringResource(MR.strings.icon_descr_call_rejected), tint = Color.Red) CICallStatus.Accepted -> ConnectingCallIcon() CICallStatus.Negotiated -> ConnectingCallIcon() - CICallStatus.Progress -> Icon(painterResource(R.drawable.ic_phone_in_talk_filled), stringResource(MR.strings.icon_descr_call_progress), tint = SimplexGreen) + CICallStatus.Progress -> Icon(painterResource(MR.images.ic_phone_in_talk_filled), stringResource(MR.strings.icon_descr_call_progress), tint = SimplexGreen) CICallStatus.Ended -> Row { - Icon(painterResource(R.drawable.ic_call_end), stringResource(MR.strings.icon_descr_call_ended), tint = MaterialTheme.colors.secondary, modifier = Modifier.padding(end = 4.dp)) + Icon(painterResource(MR.images.ic_call_end), stringResource(MR.strings.icon_descr_call_ended), tint = MaterialTheme.colors.secondary, modifier = Modifier.padding(end = 4.dp)) Text(durationText(duration), color = MaterialTheme.colors.secondary) } CICallStatus.Error -> {} @@ -53,9 +53,9 @@ fun CICallItemView(cInfo: ChatInfo, cItem: ChatItem, status: CICallStatus, durat @Composable fun AcceptCallButton(cInfo: ChatInfo, acceptCall: (Contact) -> Unit) { if (cInfo is ChatInfo.Direct) { - SimpleButton(stringResource(MR.strings.answer_call), painterResource(R.drawable.ic_ring_volume)) { acceptCall(cInfo.contact) } + SimpleButton(stringResource(MR.strings.answer_call), painterResource(MR.images.ic_ring_volume)) { acceptCall(cInfo.contact) } } else { - Icon(painterResource(R.drawable.ic_ring_volume), stringResource(MR.strings.answer_call), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_ring_volume), stringResource(MR.strings.answer_call), tint = MaterialTheme.colors.secondary) } // if case let .direct(contact) = chatInfo { // Button { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIFileView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIFileView.kt index ac2491f88e..7c9e49766b 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIFileView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIFileView.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.* import androidx.compose.ui.unit.dp @@ -44,7 +44,7 @@ fun CIFileView( contentAlignment = Alignment.Center ) { Icon( - painterResource(R.drawable.ic_draft_filled), + painterResource(MR.images.ic_draft_filled), stringResource(MR.strings.icon_descr_file), Modifier.fillMaxSize(), tint = color @@ -152,15 +152,15 @@ fun CIFileView( FileProtocol.XFTP -> progressCircle(file.fileStatus.sndProgress, file.fileStatus.sndTotal) FileProtocol.SMP -> progressIndicator() } - is CIFileStatus.SndComplete -> fileIcon(innerIcon = painterResource(R.drawable.ic_check_filled)) - is CIFileStatus.SndCancelled -> fileIcon(innerIcon = painterResource(R.drawable.ic_close)) - is CIFileStatus.SndError -> fileIcon(innerIcon = painterResource(R.drawable.ic_close)) + is CIFileStatus.SndComplete -> fileIcon(innerIcon = painterResource(MR.images.ic_check_filled)) + is CIFileStatus.SndCancelled -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) + is CIFileStatus.SndError -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) is CIFileStatus.RcvInvitation -> if (fileSizeValid()) - fileIcon(innerIcon = painterResource(R.drawable.ic_arrow_downward), color = MaterialTheme.colors.primary) + fileIcon(innerIcon = painterResource(MR.images.ic_arrow_downward), color = MaterialTheme.colors.primary) else - fileIcon(innerIcon = painterResource(R.drawable.ic_priority_high), color = WarningOrange) - is CIFileStatus.RcvAccepted -> fileIcon(innerIcon = painterResource(R.drawable.ic_more_horiz)) + fileIcon(innerIcon = painterResource(MR.images.ic_priority_high), color = WarningOrange) + is CIFileStatus.RcvAccepted -> fileIcon(innerIcon = painterResource(MR.images.ic_more_horiz)) is CIFileStatus.RcvTransfer -> if (file.fileProtocol == FileProtocol.XFTP && file.fileStatus.rcvProgress < file.fileStatus.rcvTotal) { progressCircle(file.fileStatus.rcvProgress, file.fileStatus.rcvTotal) @@ -168,8 +168,8 @@ fun CIFileView( progressIndicator() } is CIFileStatus.RcvComplete -> fileIcon() - is CIFileStatus.RcvCancelled -> fileIcon(innerIcon = painterResource(R.drawable.ic_close)) - is CIFileStatus.RcvError -> fileIcon(innerIcon = painterResource(R.drawable.ic_close)) + is CIFileStatus.RcvCancelled -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) + is CIFileStatus.RcvError -> fileIcon(innerIcon = painterResource(MR.images.ic_close)) } } else { fileIcon() diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIGroupInvitationView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIGroupInvitationView.kt index 6a0e07619a..d66dc4ae23 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIGroupInvitationView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIGroupInvitationView.kt @@ -44,7 +44,7 @@ fun CIGroupInvitationView( .padding(vertical = 4.dp) .padding(end = 2.dp) ) { - ProfileImage(size = 60.dp, image = groupInvitation.groupProfile.image, icon = R.drawable.ic_supervised_user_circle_filled, color = iconColor) + ProfileImage(size = 60.dp, image = groupInvitation.groupProfile.image, icon = MR.images.ic_supervised_user_circle_filled, color = iconColor) Spacer(Modifier.padding(horizontal = 3.dp)) Column( Modifier.defaultMinSize(minHeight = 60.dp), diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIImageView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIImageView.kt index b5933c9d35..642757f271 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIImageView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIImageView.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.layoutId import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -78,14 +78,14 @@ fun CIImageView( FileProtocol.SMP -> {} } is CIFileStatus.SndTransfer -> progressIndicator() - is CIFileStatus.SndComplete -> fileIcon(painterResource(R.drawable.ic_check_filled), MR.strings.icon_descr_image_snd_complete) - is CIFileStatus.SndCancelled -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.SndError -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.RcvInvitation -> fileIcon(painterResource(R.drawable.ic_arrow_downward), MR.strings.icon_descr_asked_to_receive) - is CIFileStatus.RcvAccepted -> fileIcon(painterResource(R.drawable.ic_more_horiz), MR.strings.icon_descr_waiting_for_image) + is CIFileStatus.SndComplete -> fileIcon(painterResource(MR.images.ic_check_filled), MR.strings.icon_descr_image_snd_complete) + is CIFileStatus.SndCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.SndError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvInvitation -> fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_asked_to_receive) + is CIFileStatus.RcvAccepted -> fileIcon(painterResource(MR.images.ic_more_horiz), MR.strings.icon_descr_waiting_for_image) is CIFileStatus.RcvTransfer -> progressIndicator() - is CIFileStatus.RcvCancelled -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.RcvError -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) else -> {} } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIInvalidJSONView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIInvalidJSONView.kt index d1aad7c297..64111ee4ea 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIInvalidJSONView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIInvalidJSONView.kt @@ -7,7 +7,7 @@ import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.unit.dp @@ -32,7 +32,7 @@ fun InvalidJSONView(json: String) { Column { Spacer(Modifier.height(DEFAULT_PADDING)) SectionView { - SettingsActionItem(painterResource(R.drawable.ic_share), generalGetString(MR.strings.share_verb), click = { + SettingsActionItem(painterResource(MR.images.ic_share), generalGetString(MR.strings.share_verb), click = { shareText(json) }) } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt index eace6bed88..9404b24369 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIMetaView.kt @@ -3,8 +3,7 @@ package chat.simplex.app.views.chat.item import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource -import chat.simplex.app.R +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -15,6 +14,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.app.model.* import chat.simplex.app.ui.theme.CurrentColors +import chat.simplex.res.MR import kotlinx.datetime.Clock @Composable @@ -37,11 +37,11 @@ fun CIMetaView(chatItem: ChatItem, timedMessagesTTL: Int?, metaColor: Color = Ma // changing this function requires updating reserveSpaceForMeta private fun CIMetaText(meta: CIMeta, chatTTL: Int?, color: Color) { if (meta.itemEdited) { - StatusIconText(painterResource(R.drawable.ic_edit), color) + StatusIconText(painterResource(MR.images.ic_edit), color) Spacer(Modifier.width(3.dp)) } if (meta.disappearing) { - StatusIconText(painterResource(R.drawable.ic_timer), color) + StatusIconText(painterResource(MR.images.ic_timer), color) val ttl = meta.itemTimed?.ttl if (ttl != chatTTL) { Text(shortTimeText(ttl), color = color, fontSize = 12.sp) @@ -54,7 +54,7 @@ private fun CIMetaText(meta: CIMeta, chatTTL: Int?, color: Color) { StatusIconText(painterResource(icon), statusColor) Spacer(Modifier.width(4.dp)) } else if (!meta.disappearing) { - StatusIconText(painterResource(R.drawable.ic_circle_filled), Color.Transparent) + StatusIconText(painterResource(MR.images.ic_circle_filled), Color.Transparent) Spacer(Modifier.width(4.dp)) } Text(meta.timestampText, color = color, fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVideoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVideoView.kt index 71f27a40c4..f6123e7bed 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVideoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVideoView.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.* import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.* import androidx.compose.ui.viewinterop.AndroidView @@ -162,7 +162,7 @@ private fun BoxScope.PlayButton(error: Boolean = false, onLongClick: () -> Unit, contentAlignment = Alignment.Center ) { Icon( - painterResource(R.drawable.ic_play_arrow_filled), + painterResource(MR.images.ic_play_arrow_filled), contentDescription = null, tint = if (error) WarningOrange else Color.White ) @@ -190,7 +190,7 @@ private fun DurationProgress(file: CIFile, playing: MutableState, durat color = Color.White ) /*if (!soundEnabled.value) { - Icon(painterResource(R.drawable.ic_volume_off_filled), null, + Icon(painterResource(MR.images.ic_volume_off_filled), null, Modifier.padding(start = 5.dp).size(10.dp), tint = Color.White ) @@ -296,19 +296,19 @@ private fun loadingIndicator(file: CIFile?) { FileProtocol.XFTP -> progressCircle(file.fileStatus.sndProgress, file.fileStatus.sndTotal) FileProtocol.SMP -> progressIndicator() } - is CIFileStatus.SndComplete -> fileIcon(painterResource(R.drawable.ic_check_filled), MR.strings.icon_descr_video_snd_complete) - is CIFileStatus.SndCancelled -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.SndError -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.RcvInvitation -> fileIcon(painterResource(R.drawable.ic_arrow_downward), MR.strings.icon_descr_video_asked_to_receive) - is CIFileStatus.RcvAccepted -> fileIcon(painterResource(R.drawable.ic_more_horiz), MR.strings.icon_descr_waiting_for_video) + is CIFileStatus.SndComplete -> fileIcon(painterResource(MR.images.ic_check_filled), MR.strings.icon_descr_video_snd_complete) + is CIFileStatus.SndCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.SndError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvInvitation -> fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_video_asked_to_receive) + is CIFileStatus.RcvAccepted -> fileIcon(painterResource(MR.images.ic_more_horiz), MR.strings.icon_descr_waiting_for_video) is CIFileStatus.RcvTransfer -> if (file.fileProtocol == FileProtocol.XFTP && file.fileStatus.rcvProgress < file.fileStatus.rcvTotal) { progressCircle(file.fileStatus.rcvProgress, file.fileStatus.rcvTotal) } else { progressIndicator() } - is CIFileStatus.RcvCancelled -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) - is CIFileStatus.RcvError -> fileIcon(painterResource(R.drawable.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) + is CIFileStatus.RcvError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file) else -> {} } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVoiceView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVoiceView.kt index 840ba7b03f..8d331c2276 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVoiceView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/CIVoiceView.kt @@ -1,6 +1,5 @@ package chat.simplex.app.views.chat.item -import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CornerSize @@ -16,12 +15,12 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.* -import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.* +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource import kotlinx.coroutines.flow.distinctUntilChanged // TODO refactor https://github.com/simplex-chat/simplex-chat/pull/1451#discussion_r1033429901 @@ -226,7 +225,7 @@ private fun PlayPauseButton( contentAlignment = Alignment.Center ) { Icon( - if (audioPlaying) painterResource(R.drawable.ic_pause_filled) else painterResource(R.drawable.ic_play_arrow_filled), + if (audioPlaying) painterResource(MR.images.ic_pause_filled) else painterResource(MR.images.ic_play_arrow_filled), contentDescription = null, Modifier.size(36.dp), tint = if (error) WarningOrange else if (!enabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary @@ -256,7 +255,7 @@ private fun VoiceMsgIndicator( if (hasText) { IconButton({ if (!audioPlaying) play() else pause() }, Modifier.size(56.dp).drawRingModifier(angle, strokeColor, strokeWidth)) { Icon( - if (audioPlaying) painterResource(R.drawable.ic_pause_filled) else painterResource(R.drawable.ic_play_arrow_filled), + if (audioPlaying) painterResource(MR.images.ic_pause_filled) else painterResource(MR.images.ic_play_arrow_filled), contentDescription = null, Modifier.size(36.dp), tint = MaterialTheme.colors.primary diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt index 6f4946064f..93a4670dfe 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview @@ -164,7 +164,7 @@ fun ChatItemView( MsgReactionsMenu() } if (cItem.meta.itemDeleted == null && !live) { - ItemAction(stringResource(MR.strings.reply_verb), painterResource(R.drawable.ic_reply), onClick = { + ItemAction(stringResource(MR.strings.reply_verb), painterResource(MR.images.ic_reply), onClick = { if (composeState.value.editing) { composeState.value = ComposeState(contextItem = ComposeContextItem.QuotedItem(cItem), useLinkPreviews = useLinkPreviews) } else { @@ -173,7 +173,7 @@ fun ChatItemView( showMenu.value = false }) } - ItemAction(stringResource(MR.strings.share_verb), painterResource(R.drawable.ic_share), onClick = { + ItemAction(stringResource(MR.strings.share_verb), painterResource(MR.images.ic_share), onClick = { val filePath = getLoadedFilePath(cItem.file) when { filePath != null -> shareFile(cItem.text, filePath) @@ -181,7 +181,7 @@ fun ChatItemView( } showMenu.value = false }) - ItemAction(stringResource(MR.strings.copy_verb), painterResource(R.drawable.ic_content_copy), onClick = { + ItemAction(stringResource(MR.strings.copy_verb), painterResource(MR.images.ic_content_copy), onClick = { copyText(cItem.content.text) showMenu.value = false }) @@ -189,7 +189,7 @@ fun ChatItemView( val filePath = getLoadedFilePath(cItem.file) if (filePath != null) { val writePermissionState = rememberPermissionState(permission = Manifest.permission.WRITE_EXTERNAL_STORAGE) - ItemAction(stringResource(MR.strings.save_verb), painterResource(R.drawable.ic_download), onClick = { + ItemAction(stringResource(MR.strings.save_verb), painterResource(MR.images.ic_download), onClick = { when (cItem.content.msgContent) { is MsgContent.MCImage -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || writePermissionState.hasPermission) { @@ -206,7 +206,7 @@ fun ChatItemView( } } if (cItem.meta.editable && cItem.content.msgContent !is MsgContent.MCVoice && !live) { - ItemAction(stringResource(MR.strings.edit_verb), painterResource(R.drawable.ic_edit_filled), onClick = { + ItemAction(stringResource(MR.strings.edit_verb), painterResource(MR.images.ic_edit_filled), onClick = { composeState.value = ComposeState(editingItem = cItem, useLinkPreviews = useLinkPreviews) showMenu.value = false }) @@ -214,7 +214,7 @@ fun ChatItemView( if (cItem.meta.itemDeleted != null && revealed.value) { ItemAction( stringResource(MR.strings.hide_verb), - painterResource(R.drawable.ic_visibility_off), + painterResource(MR.images.ic_visibility_off), onClick = { revealed.value = false showMenu.value = false @@ -241,7 +241,7 @@ fun ChatItemView( if (!cItem.isDeletedContent) { ItemAction( stringResource(MR.strings.reveal_verb), - painterResource(R.drawable.ic_visibility), + painterResource(MR.images.ic_visibility), onClick = { revealed.value = true showMenu.value = false @@ -342,7 +342,7 @@ fun CancelFileItemAction( ) { ItemAction( stringResource(cancelAction.uiActionId), - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), onClick = { showMenu.value = false cancelFileAlertDialog(fileId, cancelFile = cancelFile, cancelAction = cancelAction) @@ -360,7 +360,7 @@ fun ItemInfoAction( ) { ItemAction( stringResource(MR.strings.info_menu), - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), onClick = { showItemDetails(cInfo, cItem) showMenu.value = false @@ -378,7 +378,7 @@ fun DeleteItemAction( ) { ItemAction( stringResource(MR.strings.delete_verb), - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), onClick = { showMenu.value = false deleteMessageAlertDialog(cItem, questionText, deleteMessage = deleteMessage) @@ -396,7 +396,7 @@ fun ModerateItemAction( ) { ItemAction( stringResource(MR.strings.moderate_verb), - painterResource(R.drawable.ic_flag), + painterResource(MR.images.ic_flag), onClick = { showMenu.value = false moderateMessageAlertDialog(cItem, questionText, deleteMessage = deleteMessage) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/FramedItemView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/FramedItemView.kt index 52044a87f8..6dc7920235 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/FramedItemView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chat/item/FramedItemView.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.* import androidx.compose.ui.platform.UriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontStyle @@ -141,7 +141,7 @@ fun FramedItemView( ciQuotedMsgView(qi) } Icon( - if (qi.content is MsgContent.MCFile) painterResource(R.drawable.ic_draft_filled) else painterResource(R.drawable.ic_mic_filled), + if (qi.content is MsgContent.MCFile) painterResource(MR.images.ic_draft_filled) else painterResource(MR.images.ic_mic_filled), if (qi.content is MsgContent.MCFile) stringResource(MR.strings.icon_descr_file) else stringResource(MR.strings.voice_message), Modifier .padding(top = 6.dp, end = 4.dp) @@ -182,9 +182,9 @@ fun FramedItemView( PriorityLayout(Modifier, CHAT_IMAGE_LAYOUT_ID) { if (ci.meta.itemDeleted != null) { if (ci.meta.itemDeleted is CIDeleted.Moderated) { - FramedItemHeader(String.format(stringResource(MR.strings.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName), true, painterResource(R.drawable.ic_flag)) + FramedItemHeader(String.format(stringResource(MR.strings.moderated_item_description), ci.meta.itemDeleted.byGroupMember.chatViewName), true, painterResource(MR.images.ic_flag)) } else { - FramedItemHeader(stringResource(MR.strings.marked_deleted_description), true, painterResource(R.drawable.ic_delete)) + FramedItemHeader(stringResource(MR.strings.marked_deleted_description), true, painterResource(MR.images.ic_delete)) } } else if (ci.meta.isLive) { FramedItemHeader(stringResource(MR.strings.live), false) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatHelpView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatHelpView.kt index 20a3ef44ed..94f9632080 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatHelpView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatHelpView.kt @@ -4,7 +4,7 @@ import android.content.res.Configuration import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -46,7 +46,7 @@ fun ChatHelpView(addContact: (() -> Unit)? = null) { ) { Text(stringResource(MR.strings.chat_help_tap_button)) Icon( - painterResource(R.drawable.ic_person_add), + painterResource(MR.images.ic_person_add), stringResource(MR.strings.add_contact), modifier = if (addContact != null) Modifier.clickable(onClick = addContact) else Modifier, ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt index 46a0bd1866..4f3294706b 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt @@ -9,14 +9,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.chat.* @@ -192,7 +191,7 @@ fun GroupMenuItems(chat: Chat, groupInfo: GroupInfo, chatModel: ChatModel, showM fun MarkReadChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.mark_read), - painterResource(R.drawable.ic_check), + painterResource(MR.images.ic_check), onClick = { markChatRead(chat, chatModel) chatModel.controller.ntfManager.cancelNotificationsForChat(chat.id) @@ -205,7 +204,7 @@ fun MarkReadChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState< fun MarkUnreadChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.mark_unread), - painterResource(R.drawable.ic_mark_chat_unread), + painterResource(MR.images.ic_mark_chat_unread), onClick = { markChatUnread(chat, chatModel) showMenu.value = false @@ -217,7 +216,7 @@ fun MarkUnreadChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableStat fun ToggleFavoritesChatAction(chat: Chat, chatModel: ChatModel, favorite: Boolean, showMenu: MutableState) { ItemAction( if (favorite) stringResource(MR.strings.unfavorite_chat) else stringResource(MR.strings.favorite_chat), - if (favorite) painterResource(R.drawable.ic_star_off) else painterResource(R.drawable.ic_star), + if (favorite) painterResource(MR.images.ic_star_off) else painterResource(MR.images.ic_star), onClick = { toggleChatFavorite(chat, !favorite, chatModel) showMenu.value = false @@ -229,7 +228,7 @@ fun ToggleFavoritesChatAction(chat: Chat, chatModel: ChatModel, favorite: Boolea fun ToggleNotificationsChatAction(chat: Chat, chatModel: ChatModel, ntfsEnabled: Boolean, showMenu: MutableState) { ItemAction( if (ntfsEnabled) stringResource(MR.strings.mute_chat) else stringResource(MR.strings.unmute_chat), - if (ntfsEnabled) painterResource(R.drawable.ic_notifications_off) else painterResource(R.drawable.ic_notifications), + if (ntfsEnabled) painterResource(MR.images.ic_notifications_off) else painterResource(MR.images.ic_notifications), onClick = { toggleNotifications(chat, !ntfsEnabled, chatModel) showMenu.value = false @@ -241,7 +240,7 @@ fun ToggleNotificationsChatAction(chat: Chat, chatModel: ChatModel, ntfsEnabled: fun ClearChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.clear_chat_menu_action), - painterResource(R.drawable.ic_settings_backup_restore), + painterResource(MR.images.ic_settings_backup_restore), onClick = { clearChatDialog(chat.chatInfo, chatModel) showMenu.value = false @@ -254,7 +253,7 @@ fun ClearChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.delete_contact_menu_action), - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), onClick = { deleteContactDialog(chat.chatInfo, chatModel) showMenu.value = false @@ -267,7 +266,7 @@ fun DeleteContactAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState fun DeleteGroupAction(chat: Chat, groupInfo: GroupInfo, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.delete_group_menu_action), - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), onClick = { deleteGroupDialog(chat.chatInfo, groupInfo, chatModel) showMenu.value = false @@ -281,7 +280,7 @@ fun JoinGroupAction(chat: Chat, groupInfo: GroupInfo, chatModel: ChatModel, show val joinGroup: () -> Unit = { withApi { chatModel.controller.apiJoinGroup(groupInfo.groupId) } } ItemAction( if (chat.chatInfo.incognito) stringResource(MR.strings.join_group_incognito_button) else stringResource(MR.strings.join_group_button), - if (chat.chatInfo.incognito) painterResource(R.drawable.ic_theater_comedy_filled) else painterResource(R.drawable.ic_login), + if (chat.chatInfo.incognito) painterResource(MR.images.ic_theater_comedy_filled) else painterResource(MR.images.ic_login), color = if (chat.chatInfo.incognito) Indigo else MaterialTheme.colors.onBackground, onClick = { joinGroup() @@ -294,7 +293,7 @@ fun JoinGroupAction(chat: Chat, groupInfo: GroupInfo, chatModel: ChatModel, show fun LeaveGroupAction(groupInfo: GroupInfo, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.leave_group_button), - painterResource(R.drawable.ic_logout), + painterResource(MR.images.ic_logout), onClick = { leaveGroupDialog(groupInfo, chatModel) showMenu.value = false @@ -307,7 +306,7 @@ fun LeaveGroupAction(groupInfo: GroupInfo, chatModel: ChatModel, showMenu: Mutab fun ContactRequestMenuItems(chatInfo: ChatInfo.ContactRequest, chatModel: ChatModel, showMenu: MutableState) { ItemAction( if (chatModel.incognito.value) stringResource(MR.strings.accept_contact_incognito_button) else stringResource(MR.strings.accept_contact_button), - if (chatModel.incognito.value) painterResource(R.drawable.ic_theater_comedy_filled) else painterResource(R.drawable.ic_check), + if (chatModel.incognito.value) painterResource(MR.images.ic_theater_comedy_filled) else painterResource(MR.images.ic_check), color = if (chatModel.incognito.value) Indigo else MaterialTheme.colors.onBackground, onClick = { acceptContactRequest(chatInfo.apiId, chatInfo, true, chatModel) @@ -316,7 +315,7 @@ fun ContactRequestMenuItems(chatInfo: ChatInfo.ContactRequest, chatModel: ChatMo ) ItemAction( stringResource(MR.strings.reject_contact_button), - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), onClick = { rejectContactRequest(chatInfo, chatModel) showMenu.value = false @@ -329,7 +328,7 @@ fun ContactRequestMenuItems(chatInfo: ChatInfo.ContactRequest, chatModel: ChatMo fun ContactConnectionMenuItems(chatInfo: ChatInfo.ContactConnection, chatModel: ChatModel, showMenu: MutableState) { ItemAction( stringResource(MR.strings.set_contact_name), - painterResource(R.drawable.ic_edit), + painterResource(MR.images.ic_edit), onClick = { ModalManager.shared.showModalCloseable(true) { close -> ContactConnectionInfoView(chatModel, chatInfo.contactConnection.connReqInv, chatInfo.contactConnection, true, close) @@ -339,7 +338,7 @@ fun ContactConnectionMenuItems(chatInfo: ChatInfo.ContactConnection, chatModel: ) ItemAction( stringResource(MR.strings.delete_verb), - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), onClick = { deleteContactConnectionAlert(chatInfo.contactConnection, chatModel) {} showMenu.value = false @@ -351,7 +350,7 @@ fun ContactConnectionMenuItems(chatInfo: ChatInfo.ContactConnection, chatModel: @Composable private fun InvalidDataView() { Row { - ProfileImage(72.dp, null, R.drawable.ic_account_circle_filled, MaterialTheme.colors.secondary) + ProfileImage(72.dp, null, MR.images.ic_account_circle_filled, MaterialTheme.colors.secondary) Column( modifier = Modifier .padding(horizontal = 8.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt index 11db16e9d6..3d93cab587 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt @@ -13,16 +13,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.* import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.intl.Locale -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* -import androidx.fragment.app.FragmentActivity import chat.simplex.app.* -import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.* @@ -89,7 +86,7 @@ fun ChatListView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, stopped: backgroundColor = if (!stopped) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, contentColor = Color.White ) { - Icon(if (!newChatSheetState.collectAsState().value.isVisible()) painterResource(R.drawable.ic_edit_filled) else painterResource(R.drawable.ic_close), stringResource(MR.strings.add_contact_or_create_group)) + Icon(if (!newChatSheetState.collectAsState().value.isVisible()) painterResource(MR.images.ic_edit_filled) else painterResource(MR.images.ic_close), stringResource(MR.strings.add_contact_or_create_group)) } } } @@ -181,7 +178,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user if (chatModel.chats.size > 0) { barButtons.add { IconButton({ showSearch = true }) { - Icon(painterResource(R.drawable.ic_search_500), stringResource(MR.strings.search_verb).capitalize(Locale.current), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_search_500), stringResource(MR.strings.search_verb).capitalize(Locale.current), tint = MaterialTheme.colors.primary) } } } @@ -194,7 +191,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user ) }) { Icon( - painterResource(R.drawable.ic_report_filled), + painterResource(MR.images.ic_report_filled), generalGetString(MR.strings.chat_is_stopped_indication), tint = Color.Red, ) @@ -226,7 +223,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user Row(verticalAlignment = Alignment.CenterVertically) { if (chatModel.incognito.value) { Icon( - painterResource(R.drawable.ic_theater_comedy_filled), + painterResource(MR.images.ic_theater_comedy_filled), stringResource(MR.strings.incognito), tint = Indigo, modifier = Modifier.padding(10.dp).size(26.dp) @@ -285,7 +282,7 @@ private fun ToggleFilterButton() { val pref = remember { SimplexApp.context.chatModel.controller.appPrefs.showUnreadAndFavorites } IconButton(onClick = { pref.set(!pref.get()) }) { Icon( - painterResource(R.drawable.ic_filter_list), + painterResource(MR.images.ic_filter_list), null, tint = if (pref.state.value) MaterialTheme.colors.background else MaterialTheme.colors.primary, modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt index 9059ce8be7..efa51a3790 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight @@ -27,6 +27,7 @@ import chat.simplex.app.views.chat.ComposeState import chat.simplex.app.views.chat.item.MarkdownText import chat.simplex.app.views.helpers.* import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource @Composable fun ChatPreviewView( @@ -44,7 +45,7 @@ fun ChatPreviewView( @Composable fun groupInactiveIcon() { Icon( - painterResource(R.drawable.ic_cancel_filled), + painterResource(MR.images.ic_cancel_filled), stringResource(MR.strings.icon_descr_group_inactive), Modifier.size(18.dp).background(MaterialTheme.colors.background, CircleShape), tint = MaterialTheme.colors.secondary @@ -77,15 +78,15 @@ fun ChatPreviewView( @Composable fun VerifiedIcon() { - Icon(painterResource(R.drawable.ic_verified_user), null, Modifier.size(19.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(19.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) } fun messageDraft(draft: ComposeState): Pair> { - fun attachment(): Pair? = + fun attachment(): Pair? = when (draft.preview) { - is ComposePreview.FilePreview -> R.drawable.ic_draft_filled to draft.preview.fileName - is ComposePreview.MediaPreview -> R.drawable.ic_image to null - is ComposePreview.VoicePreview -> R.drawable.ic_play_arrow_filled to durationText(draft.preview.durationMs / 1000) + is ComposePreview.FilePreview -> MR.images.ic_draft_filled to draft.preview.fileName + is ComposePreview.MediaPreview -> MR.images.ic_image to null + is ComposePreview.VoicePreview -> MR.images.ic_play_arrow_filled to durationText(draft.preview.durationMs / 1000) else -> null } @@ -106,12 +107,12 @@ fun ChatPreviewView( "editIcon" to InlineTextContent( Placeholder(20.sp, 20.sp, PlaceholderVerticalAlign.TextCenter) ) { - Icon(painterResource(R.drawable.ic_edit_note), null, tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_edit_note), null, tint = MaterialTheme.colors.primary) }, "attachmentIcon" to InlineTextContent( Placeholder(20.sp, 20.sp, PlaceholderVerticalAlign.TextCenter) ) { - Icon(if (attachment?.first != null) painterResource(attachment.first) else painterResource(R.drawable.ic_edit_note), null, tint = MaterialTheme.colors.secondary) + Icon(if (attachment?.first != null) painterResource(attachment.first) else painterResource(MR.images.ic_edit_note), null, tint = MaterialTheme.colors.secondary) } ) return text to inlineContent @@ -237,7 +238,7 @@ fun ChatPreviewView( contentAlignment = Alignment.Center ) { Icon( - painterResource(R.drawable.ic_notifications_off_filled), + painterResource(MR.images.ic_notifications_off_filled), contentDescription = generalGetString(MR.strings.notifications), tint = MaterialTheme.colors.secondary, modifier = Modifier @@ -252,7 +253,7 @@ fun ChatPreviewView( contentAlignment = Alignment.Center ) { Icon( - painterResource(R.drawable.ic_star_filled), + painterResource(MR.images.ic_star_filled), contentDescription = generalGetString(MR.strings.favorite_chat), tint = MaterialTheme.colors.secondary, modifier = Modifier @@ -294,7 +295,7 @@ fun ChatStatusImage(s: NetworkStatus?) { val descr = s?.statusString if (s is NetworkStatus.Error) { Icon( - painterResource(R.drawable.ic_error), + painterResource(MR.images.ic_error), contentDescription = descr, tint = MaterialTheme.colors.secondary, modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ContactConnectionView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ContactConnectionView.kt index de6fe43d50..39c0b583a3 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ContactConnectionView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ContactConnectionView.kt @@ -7,21 +7,21 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource 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 chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.ProfileImage +import chat.simplex.res.MR @Composable fun ContactConnectionView(contactConnection: PendingContactConnection) { Row { Box(Modifier.size(72.dp), contentAlignment = Alignment.Center) { - ProfileImage(size = 54.dp, null, if (contactConnection.initiated) R.drawable.ic_add_link else R.drawable.ic_link) + ProfileImage(size = 54.dp, null, if (contactConnection.initiated) MR.images.ic_add_link else MR.images.ic_link) } Column( modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt index 19593dd032..3a3f929fcc 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt @@ -11,7 +11,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.font.FontWeight @@ -83,7 +83,7 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState if (chatModel.chats.size >= 8) { barButtons.add { IconButton({ showSearch = true }) { - Icon(painterResource(R.drawable.ic_search_500), stringResource(MR.strings.search_verb).capitalize(Locale.current), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_search_500), stringResource(MR.strings.search_verb).capitalize(Locale.current), tint = MaterialTheme.colors.primary) } } } @@ -96,7 +96,7 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState ) }) { Icon( - painterResource(R.drawable.ic_report_filled), + painterResource(MR.images.ic_report_filled), generalGetString(MR.strings.chat_is_stopped_indication), tint = Color.Red, ) @@ -120,7 +120,7 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState ) if (chatModel.incognito.value) { Icon( - painterResource(R.drawable.ic_theater_comedy_filled), + painterResource(MR.images.ic_theater_comedy_filled), stringResource(MR.strings.incognito), tint = Indigo, modifier = Modifier.padding(10.dp).size(26.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt index 0c74769e55..5395c73f37 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.intl.Locale @@ -168,9 +168,9 @@ fun UserProfilePickerItem(u: User, unreadCount: Int = 0, padding: PaddingValues ) { UserProfileRow(u) if (u.activeUser) { - Icon(painterResource(R.drawable.ic_done_filled), null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_done_filled), null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) } else if (u.hidden) { - Icon(painterResource(R.drawable.ic_lock), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_lock), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) } else if (unreadCount > 0) { Box( contentAlignment = Alignment.Center @@ -186,7 +186,7 @@ fun UserProfilePickerItem(u: User, unreadCount: Int = 0, padding: PaddingValues ) } } else if (!u.showNtfs) { - Icon(painterResource(R.drawable.ic_notifications_off), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_notifications_off), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) } else { Box(Modifier.size(20.dp)) } @@ -219,7 +219,7 @@ fun UserProfileRow(u: User) { private fun SettingsPickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current) - Icon(painterResource(R.drawable.ic_settings), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_settings), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text( text, @@ -232,7 +232,7 @@ private fun SettingsPickerItem(onClick: () -> Unit) { private fun CancelPickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.cancel_verb) - Icon(painterResource(R.drawable.ic_close), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_close), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text( text, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/ChatArchiveView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/ChatArchiveView.kt index 7c2cb32506..69b8f49d1a 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/ChatArchiveView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/ChatArchiveView.kt @@ -17,7 +17,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import chat.simplex.app.* @@ -59,14 +59,14 @@ fun ChatArchiveLayout( AppBarTitle(title) SectionView(stringResource(MR.strings.chat_archive_section)) { SettingsActionItem( - painterResource(R.drawable.ic_ios_share), + painterResource(MR.images.ic_ios_share), stringResource(MR.strings.save_archive), saveArchive, textColor = MaterialTheme.colors.primary, iconColor = MaterialTheme.colors.primary, ) SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.delete_archive), deleteArchiveAlert, textColor = Color.Red, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseEncryptionView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseEncryptionView.kt index 156c51b52d..07be9dcef7 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseEncryptionView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseEncryptionView.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight @@ -291,7 +291,7 @@ fun SavePassphraseSetting( SectionItemView(minHeight = minHeight) { Row(verticalAlignment = Alignment.CenterVertically) { Icon( - if (storedKey) painterResource(R.drawable.ic_vpn_key_filled) else painterResource(R.drawable.ic_vpn_key_off_filled), + if (storedKey) painterResource(MR.images.ic_vpn_key_filled) else painterResource(MR.images.ic_vpn_key_off_filled), stringResource(MR.strings.save_passphrase_in_keychain), tint = if (storedKey) SimplexGreen else MaterialTheme.colors.secondary ) @@ -358,8 +358,8 @@ fun PassphraseField( var valid by remember { mutableStateOf(validKey(key.value)) } var showKey by remember { mutableStateOf(false) } val icon = if (valid) { - if (showKey) painterResource(R.drawable.ic_visibility_off_filled) else painterResource(R.drawable.ic_visibility_filled) - } else painterResource(R.drawable.ic_error) + if (showKey) painterResource(MR.images.ic_visibility_off_filled) else painterResource(MR.images.ic_visibility_filled) + } else painterResource(MR.images.ic_error) val iconColor = if (valid) { if (showStrength && key.value.isNotEmpty()) PassphraseStrength.check(key.value).color else MaterialTheme.colors.secondary } else Color.Red diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseView.kt index 89e685d8c4..ebb88e3e0d 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/database/DatabaseView.kt @@ -22,7 +22,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight @@ -178,8 +178,8 @@ fun DatabaseLayout( SectionView(stringResource(MR.strings.chat_database_section)) { val unencrypted = chatDbEncrypted == false SettingsActionItem( - if (unencrypted) painterResource(R.drawable.ic_lock_open) else if (useKeyChain) painterResource(R.drawable.ic_vpn_key_filled) - else painterResource(R.drawable.ic_lock), + if (unencrypted) painterResource(MR.images.ic_lock_open) else if (useKeyChain) painterResource(MR.images.ic_vpn_key_filled) + else painterResource(MR.images.ic_lock), stringResource(MR.strings.database_passphrase), click = showSettingsModal() { DatabaseEncryptionView(it) }, iconColor = if (unencrypted) WarningOrange else MaterialTheme.colors.secondary, @@ -188,7 +188,7 @@ fun DatabaseLayout( AppDataBackupPreference(privacyFullBackup, initialRandomDBPassphrase) SectionDividerSpaced(maxBottomPadding = false) SettingsActionItem( - painterResource(R.drawable.ic_ios_share), + painterResource(MR.images.ic_ios_share), stringResource(MR.strings.export_database), click = { if (initialRandomDBPassphrase.get()) { @@ -202,7 +202,7 @@ fun DatabaseLayout( disabled = operationsDisabled ) SettingsActionItem( - painterResource(R.drawable.ic_download), + painterResource(MR.images.ic_download), stringResource(MR.strings.import_database), { importArchiveLauncher.launch("application/zip") }, textColor = Color.Red, @@ -215,14 +215,14 @@ fun DatabaseLayout( if (chatArchiveNameVal != null && chatArchiveTimeVal != null && chatLastStartVal != null) { val title = chatArchiveTitle(chatArchiveTimeVal, chatLastStartVal) SettingsActionItem( - painterResource(R.drawable.ic_inventory_2), + painterResource(MR.images.ic_inventory_2), title, click = showSettingsModal { ChatArchiveView(it, title, chatArchiveNameVal, chatArchiveTimeVal) }, disabled = operationsDisabled ) } SettingsActionItem( - painterResource(R.drawable.ic_delete_forever), + painterResource(MR.images.ic_delete_forever), stringResource(MR.strings.delete_database), deleteChatAlert, textColor = Color.Red, @@ -266,7 +266,7 @@ fun DatabaseLayout( @Composable private fun AppDataBackupPreference(privacyFullBackup: SharedPreference, initialRandomDBPassphrase: SharedPreference) { SettingsPreferenceItem( - painterResource(R.drawable.ic_backup), + painterResource(MR.images.ic_backup), iconColor = MaterialTheme.colors.secondary, pref = privacyFullBackup, text = stringResource(MR.strings.full_backup) @@ -331,7 +331,7 @@ fun RunChatSetting( ) { val chatRunningText = if (stopped) stringResource(MR.strings.chat_is_stopped) else stringResource(MR.strings.chat_is_running) SettingsActionItemWithContent( - icon = if (stopped) painterResource(R.drawable.ic_report_filled) else painterResource(R.drawable.ic_play_arrow_filled), + icon = if (stopped) painterResource(MR.images.ic_report_filled) else painterResource(MR.images.ic_play_arrow_filled), text = chatRunningText, iconColor = if (stopped) Color.Red else MaterialTheme.colors.primary, ) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt index e5c03f654e..175d27c7c4 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChatInfoImage.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.* import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp @@ -19,12 +19,13 @@ import chat.simplex.app.R import chat.simplex.app.model.ChatInfo import chat.simplex.app.ui.theme.SimpleXTheme import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource @Composable fun ChatInfoImage(chatInfo: ChatInfo, size: Dp, iconColor: Color = MaterialTheme.colors.secondaryVariant) { val icon = - if (chatInfo is ChatInfo.Group) R.drawable.ic_supervised_user_circle_filled - else R.drawable.ic_account_circle_filled + if (chatInfo is ChatInfo.Group) MR.images.ic_supervised_user_circle_filled + else MR.images.ic_account_circle_filled ProfileImage(size, chatInfo.image, icon, iconColor) } @@ -32,7 +33,7 @@ fun ChatInfoImage(chatInfo: ChatInfo, size: Dp, iconColor: Color = MaterialTheme fun IncognitoImage(size: Dp, iconColor: Color = MaterialTheme.colors.secondaryVariant) { Box(Modifier.size(size)) { Icon( - painterResource(R.drawable.ic_theater_comedy_filled), stringResource(MR.strings.incognito), + painterResource(MR.images.ic_theater_comedy_filled), stringResource(MR.strings.incognito), modifier = Modifier.size(size).padding(size / 12), iconColor ) @@ -43,14 +44,14 @@ fun IncognitoImage(size: Dp, iconColor: Color = MaterialTheme.colors.secondaryVa fun ProfileImage( size: Dp, image: String? = null, - icon: Int = R.drawable.ic_account_circle_filled, + icon: ImageResource = MR.images.ic_account_circle_filled, color: Color = MaterialTheme.colors.secondaryVariant ) { Box(Modifier.size(size)) { if (image == null) { val iconToReplace = when (icon) { - R.drawable.ic_account_circle_filled -> AccountCircleFilled - R.drawable.ic_supervised_user_circle_filled -> SupervisedUserCircleFilled + MR.images.ic_account_circle_filled -> AccountCircleFilled + MR.images.ic_supervised_user_circle_filled -> SupervisedUserCircleFilled else -> null } if (iconToReplace != null) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChooseAttachmentView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChooseAttachmentView.kt index edbee83186..38b2f0e219 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChooseAttachmentView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ChooseAttachmentView.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.app.R @@ -41,19 +41,19 @@ fun ChooseAttachmentView( .padding(horizontal = 8.dp, vertical = 30.dp), horizontalArrangement = Arrangement.SpaceEvenly ) { - ActionButton(Modifier.fillMaxWidth(0.25f), null, stringResource(MR.strings.use_camera_button), icon = painterResource(R.drawable.ic_camera_enhance)) { + ActionButton(Modifier.fillMaxWidth(0.25f), null, stringResource(MR.strings.use_camera_button), icon = painterResource(MR.images.ic_camera_enhance)) { attachmentOption.value = AttachmentOption.CameraPhoto hide() } - ActionButton(Modifier.fillMaxWidth(0.33f), null, stringResource(MR.strings.gallery_image_button), icon = painterResource(R.drawable.ic_add_photo)) { + ActionButton(Modifier.fillMaxWidth(0.33f), null, stringResource(MR.strings.gallery_image_button), icon = painterResource(MR.images.ic_add_photo)) { attachmentOption.value = AttachmentOption.GalleryImage hide() } - ActionButton(Modifier.fillMaxWidth(0.50f), null, stringResource(MR.strings.gallery_video_button), icon = painterResource(R.drawable.ic_smart_display)) { + ActionButton(Modifier.fillMaxWidth(0.50f), null, stringResource(MR.strings.gallery_video_button), icon = painterResource(MR.images.ic_smart_display)) { attachmentOption.value = AttachmentOption.GalleryVideo hide() } - ActionButton(Modifier.fillMaxWidth(1f), null, stringResource(MR.strings.choose_file), icon = painterResource(R.drawable.ic_note_add)) { + ActionButton(Modifier.fillMaxWidth(1f), null, stringResource(MR.strings.choose_file), icon = painterResource(MR.images.ic_note_add)) { attachmentOption.value = AttachmentOption.File hide() } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/CustomTimePicker.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/CustomTimePicker.kt index c659353082..32c52dc1d5 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/CustomTimePicker.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/CustomTimePicker.kt @@ -8,7 +8,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Dialog @@ -174,7 +174,7 @@ fun CustomTimePickerDialog( color = MaterialTheme.colors.secondary ) Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), generalGetString(MR.strings.icon_descr_close_button), tint = MaterialTheme.colors.secondary, modifier = Modifier diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultBasicTextField.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultBasicTextField.kt index 2ea147014f..538ce4d86a 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultBasicTextField.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultBasicTextField.kt @@ -15,17 +15,16 @@ import androidx.compose.ui.focus.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.* import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import chat.simplex.app.R import chat.simplex.app.views.database.PassphraseStrength import chat.simplex.app.views.database.validKey +import chat.simplex.res.MR import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch @@ -133,8 +132,8 @@ fun DefaultConfigurableTextField( var valid by remember { mutableStateOf(validKey(state.value.text)) } var showKey by remember { mutableStateOf(false) } val icon = if (valid) { - if (showKey) painterResource(R.drawable.ic_visibility_off_filled) else painterResource(R.drawable.ic_visibility_filled) - } else painterResource(R.drawable.ic_error) + if (showKey) painterResource(MR.images.ic_visibility_off_filled) else painterResource(MR.images.ic_visibility_filled) + } else painterResource(MR.images.ic_error) val iconColor = if (valid) { if (showPasswordStrength && state.value.text.isNotEmpty()) PassphraseStrength.check(state.value.text).color else MaterialTheme.colors.secondary } else Color.Red diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultTopAppBar.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultTopAppBar.kt index ad2465acc7..44a56c441d 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultTopAppBar.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/DefaultTopAppBar.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.app.ui.theme.* @@ -48,7 +48,7 @@ fun DefaultTopAppBar( fun NavigationButtonBack(onButtonClicked: (() -> Unit)?) { IconButton(onButtonClicked ?: {}, enabled = onButtonClicked != null) { Icon( - painterResource(R.drawable.ic_arrow_back_ios_new), stringResource(MR.strings.back), tint = if (onButtonClicked != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary + painterResource(MR.images.ic_arrow_back_ios_new), stringResource(MR.strings.back), tint = if (onButtonClicked != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary ) } } @@ -57,7 +57,7 @@ fun NavigationButtonBack(onButtonClicked: (() -> Unit)?) { fun ShareButton(onButtonClicked: () -> Unit) { IconButton(onButtonClicked) { Icon( - painterResource(R.drawable.ic_share), stringResource(MR.strings.share_verb), tint = MaterialTheme.colors.primary + painterResource(MR.images.ic_share), stringResource(MR.strings.share_verb), tint = MaterialTheme.colors.primary ) } } @@ -66,7 +66,7 @@ fun ShareButton(onButtonClicked: () -> Unit) { fun NavigationButtonMenu(onButtonClicked: () -> Unit) { IconButton(onClick = onButtonClicked) { Icon( - painterResource(R.drawable.ic_menu), + painterResource(MR.images.ic_menu), stringResource(MR.strings.icon_descr_settings), tint = MaterialTheme.colors.primary, ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt index 9f06a9affd..eb563dbd0f 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt @@ -2,7 +2,7 @@ package chat.simplex.app.views.helpers import androidx.compose.foundation.layout.* import androidx.compose.material.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -51,7 +51,7 @@ fun ExposedDropDownSettingRow( ) Spacer(Modifier.size(12.dp)) Icon( - if (!expanded.value) painterResource(R.drawable.ic_expand_more) else painterResource(R.drawable.ic_expand_less), + if (!expanded.value) painterResource(MR.images.ic_expand_more) else painterResource(MR.images.ic_expand_less), generalGetString(MR.strings.icon_descr_more_button), tint = MaterialTheme.colors.secondary ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/GetImageView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/GetImageView.kt index d35c24817d..c7c8154900 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/GetImageView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/GetImageView.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat @@ -247,7 +247,7 @@ fun GetImageBottomSheet( .padding(horizontal = 8.dp, vertical = 30.dp), horizontalArrangement = Arrangement.SpaceEvenly ) { - ActionButton(null, stringResource(MR.strings.use_camera_button), icon = painterResource(R.drawable.ic_photo_camera)) { + ActionButton(null, stringResource(MR.strings.use_camera_button), icon = painterResource(MR.images.ic_photo_camera)) { when (PackageManager.PERMISSION_GRANTED) { ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) -> { cameraLauncher.launchWithFallback() @@ -258,7 +258,7 @@ fun GetImageBottomSheet( } } } - ActionButton(null, stringResource(MR.strings.from_gallery_button), icon = painterResource(R.drawable.ic_image)) { + ActionButton(null, stringResource(MR.strings.from_gallery_button), icon = painterResource(MR.images.ic_image)) { try { galleryLauncher.launch(0) } catch (e: ActivityNotFoundException) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/LinkPreviews.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/LinkPreviews.kt index e13dd83145..47efef1da3 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/LinkPreviews.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/LinkPreviews.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -113,7 +113,7 @@ fun ComposeLinkView(linkPreview: LinkPreview?, cancelPreview: () -> Unit, cancel if (cancelEnabled) { IconButton(onClick = cancelPreview, modifier = Modifier.padding(0.dp)) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.icon_descr_cancel_link_preview), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(10.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ModalView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ModalView.kt index 8fe2e05d92..724f0907fa 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ModalView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/ModalView.kt @@ -12,7 +12,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.intl.Locale diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SearchTextField.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SearchTextField.kt index 2855cd75a5..a7afb9441f 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SearchTextField.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SearchTextField.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.* import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -104,7 +104,7 @@ fun SearchTextField( searchText.value = TextFieldValue(""); onValueChange("") }) { - Icon(painterResource(R.drawable.ic_close), stringResource(MR.strings.icon_descr_close_button), tint = MaterialTheme.colors.primary,) + Icon(painterResource(MR.images.ic_close), stringResource(MR.strings.icon_descr_close_button), tint = MaterialTheme.colors.primary,) } }} else null, singleLine = true, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/Section.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/Section.kt index b61af759ea..5c7a40e282 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/Section.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/Section.kt @@ -10,15 +10,15 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.* -import chat.simplex.app.R import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.ValueTitleDesc import chat.simplex.app.views.helpers.ValueTitle import chat.simplex.app.views.usersettings.SettingsActionItemWithContent +import chat.simplex.res.MR @Composable fun SectionView(title: String? = null, padding: PaddingValues = PaddingValues(), content: (@Composable ColumnScope.() -> Unit)) { @@ -67,7 +67,7 @@ fun SectionViewSelectable( SectionItemViewSpaceBetween({ onSelected(item.value) }) { Text(item.title) if (currentValue.value == item.value) { - Icon(painterResource(R.drawable.ic_check), item.title, tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_check), item.title, tint = MaterialTheme.colors.primary) } } Spacer(Modifier.padding(horizontal = 4.dp)) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt index 9ae1ff7054..6202ded6de 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt @@ -1,11 +1,10 @@ package chat.simplex.app.ui.theme -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -16,7 +15,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import chat.simplex.app.R +import chat.simplex.res.MR @Composable fun SimpleButton(text: String, icon: Painter, @@ -93,6 +92,6 @@ fun SimpleButtonFrame(click: () -> Unit, modifier: Modifier = Modifier, disabled @Composable fun PreviewCloseSheetBar() { SimpleXTheme { - SimpleButton(text = "Share", icon = painterResource(R.drawable.ic_share), click = {}) + SimpleButton(text = "Share", icon = painterResource(MR.images.ic_share), click = {}) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasscodeView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasscodeView.kt index 9a190d2750..42186f20c9 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasscodeView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasscodeView.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.unit.dp import chat.simplex.app.R import chat.simplex.app.ui.theme.DEFAULT_PADDING @@ -40,9 +40,9 @@ fun PasscodeView( } PasscodeEntry(passcode, true) Row { - SimpleButton(generalGetString(MR.strings.cancel_verb), icon = painterResource(R.drawable.ic_close), click = cancel) + SimpleButton(generalGetString(MR.strings.cancel_verb), icon = painterResource(MR.images.ic_close), click = cancel) Spacer(Modifier.size(20.dp)) - SimpleButton(submitLabel, icon = painterResource(R.drawable.ic_done_filled), disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit) + SimpleButton(submitLabel, icon = painterResource(MR.images.ic_done_filled), disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit) } } } @@ -83,8 +83,8 @@ fun PasscodeView( Modifier.padding(start = 30.dp).height(s * 3), verticalArrangement = Arrangement.SpaceEvenly ) { - SimpleButton(generalGetString(MR.strings.cancel_verb), icon = painterResource(R.drawable.ic_close), click = cancel) - SimpleButton(submitLabel, icon = painterResource(R.drawable.ic_done_filled), disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit) + SimpleButton(generalGetString(MR.strings.cancel_verb), icon = painterResource(MR.images.ic_close), click = cancel) + SimpleButton(submitLabel, icon = painterResource(MR.images.ic_done_filled), disabled = submitEnabled?.invoke(passcode.value) == false || passcode.value.length < 4, click = submit) } } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasswordEntry.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasswordEntry.kt index 0f6f063082..98a880b4f0 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasswordEntry.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/localauth/PasswordEntry.kt @@ -6,8 +6,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource -import chat.simplex.app.R +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment @@ -17,6 +16,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.* +import chat.simplex.res.MR @Composable fun PasscodeEntry( @@ -56,13 +56,13 @@ private fun BoxWithConstraintsScope.VerticalPasswordGrid(password: MutableState< DigitsRow(s, 7, 8, 9, password) Divider() Row(Modifier.requiredHeight(s)) { - PasswordEdit(s, painterResource(R.drawable.ic_close)) { + PasswordEdit(s, painterResource(MR.images.ic_close)) { password.value = "" } VerticalDivider() PasswordDigit(s, 0, password) VerticalDivider() - PasswordEdit(s, painterResource(R.drawable.ic_backspace)) { + PasswordEdit(s, painterResource(MR.images.ic_backspace)) { password.value = password.value.dropLast(1) } } @@ -76,7 +76,7 @@ private fun BoxWithConstraintsScope.HorizontalPasswordGrid(password: MutableStat Row(Modifier.height(IntrinsicSize.Min)) { DigitsRow(s, 1, 2, 3, password); VerticalDivider() - PasswordEdit(s, painterResource(R.drawable.ic_close)) { + PasswordEdit(s, painterResource(MR.images.ic_close)) { password.value = "" } } @@ -90,7 +90,7 @@ private fun BoxWithConstraintsScope.HorizontalPasswordGrid(password: MutableStat Row(Modifier.height(IntrinsicSize.Min)) { DigitsRow(s, 7, 8, 9, password) VerticalDivider() - PasswordEdit(s, painterResource(R.drawable.ic_backspace)) { + PasswordEdit(s, painterResource(MR.images.ic_backspace)) { password.value = password.value.dropLast(1) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddContactView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddContactView.kt index 45478c3cdc..39bd6cd333 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddContactView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddContactView.kt @@ -8,7 +8,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -98,7 +98,7 @@ fun ColumnScope.OneTimeLinkSection(connReq: String, share: () -> Unit, learnMore @Composable fun ShareLinkButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_share), + painterResource(MR.images.ic_share), stringResource(MR.strings.share_invitation_link), onClick, iconColor = MaterialTheme.colors.primary, @@ -109,7 +109,7 @@ fun ShareLinkButton(onClick: () -> Unit) { @Composable fun OneTimeLinkLearnMoreButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), stringResource(MR.strings.learn_more), onClick, ) @@ -126,7 +126,7 @@ fun InfoAboutIncognito(chatModelIncognito: Boolean, supportedIncognito: Boolean horizontalArrangement = if (centered) Arrangement.Center else Arrangement.Start ) { Icon( - if (supportedIncognito) painterResource(R.drawable.ic_theater_comedy_filled) else painterResource(R.drawable.ic_info), + if (supportedIncognito) painterResource(MR.images.ic_theater_comedy_filled) else painterResource(MR.images.ic_info), stringResource(MR.strings.incognito), tint = if (supportedIncognito) Indigo else WarningOrange, modifier = Modifier.padding(end = 10.dp).size(20.dp) @@ -142,7 +142,7 @@ fun InfoAboutIncognito(chatModelIncognito: Boolean, supportedIncognito: Boolean horizontalArrangement = if (centered) Arrangement.Center else Arrangement.Start ) { Icon( - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), stringResource(MR.strings.incognito), tint = MaterialTheme.colors.secondary, modifier = Modifier.padding(end = 10.dp).size(20.dp) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddGroupView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddGroupView.kt index d0ffd05eb7..2609098ebd 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddGroupView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/AddGroupView.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -163,7 +163,7 @@ fun CreateGroupButton(color: Color, modifier: Modifier) { Surface(shape = RoundedCornerShape(20.dp), color = Color.Transparent) { Row(modifier, verticalAlignment = Alignment.CenterVertically) { Text(stringResource(MR.strings.create_profile_button), style = MaterialTheme.typography.caption, color = color, fontWeight = FontWeight.Bold) - Icon(painterResource(R.drawable.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = color) + Icon(painterResource(MR.images.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = color) } } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ConnectViaLinkView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ConnectViaLinkView.kt index 4fae906866..15ada1e103 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ConnectViaLinkView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ConnectViaLinkView.kt @@ -5,7 +5,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.sp import chat.simplex.app.R @@ -58,7 +58,7 @@ fun ConnectViaLinkView(m: ChatModel, close: () -> Unit) { text = { Text(it, fontSize = 13.sp) }, icon = { Icon( - if (ConnectViaLinkTab.SCAN.ordinal == index) painterResource(R.drawable.ic_qr_code) else painterResource(R.drawable.ic_article), + if (ConnectViaLinkTab.SCAN.ordinal == index) painterResource(MR.images.ic_qr_code) else painterResource(MR.images.ic_article), it ) }, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ContactConnectionInfoView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ContactConnectionInfoView.kt index 0cd72e0472..3317472cc5 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ContactConnectionInfoView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/ContactConnectionInfoView.kt @@ -11,7 +11,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import chat.simplex.app.R @@ -123,7 +123,7 @@ private fun ContactConnectionInfoLayout( @Composable fun DeleteButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.delete_verb), click = onClick, textColor = Color.Red, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/CreateLinkView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/CreateLinkView.kt index 633b72720f..b0b7b923d7 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/CreateLinkView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/CreateLinkView.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.sp import chat.simplex.app.R @@ -79,7 +79,7 @@ fun CreateLinkView(m: ChatModel, initialSelection: CreateLinkTab) { text = { Text(it, fontSize = 13.sp) }, icon = { Icon( - if (CreateLinkTab.ONE_TIME.ordinal == index) painterResource(R.drawable.ic_repeat_one) else painterResource(R.drawable.ic_all_inclusive), + if (CreateLinkTab.ONE_TIME.ordinal == index) painterResource(MR.images.ic_repeat_one) else painterResource(MR.images.ic_all_inclusive), it ) }, diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt index 573348847d..fd7edeaa29 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/newchat/NewChatSheet.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -57,7 +57,7 @@ fun NewChatSheet(chatModel: ChatModel, newChatSheetState: StateFlow Unit) { fun ShareAddressButton(onClick: () -> Unit) { SimpleButtonFrame(onClick) { Icon( - painterResource(R.drawable.ic_share_filled), generalGetString(MR.strings.share_verb), tint = MaterialTheme.colors.primary, + painterResource(MR.images.ic_share_filled), generalGetString(MR.strings.share_verb), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(end = 8.dp).size(18.dp) ) Text(stringResource(MR.strings.share_verb), style = MaterialTheme.typography.caption, color = MaterialTheme.colors.primary) @@ -120,7 +120,7 @@ fun ShareAddressButton(onClick: () -> Unit) { fun ShareViaEmailButton(onClick: () -> Unit) { SimpleButtonFrame(onClick) { Icon( - painterResource(R.drawable.ic_mail), generalGetString(MR.strings.share_verb), tint = MaterialTheme.colors.primary, + painterResource(MR.images.ic_mail), generalGetString(MR.strings.share_verb), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(end = 8.dp).size(30.dp) ) Text(stringResource(MR.strings.invite_friends), style = MaterialTheme.typography.h6, color = MaterialTheme.colors.primary) @@ -129,12 +129,12 @@ fun ShareViaEmailButton(onClick: () -> Unit) { @Composable private fun ContinueButton(onClick: () -> Unit) { - SimpleButtonIconEnded(stringResource(MR.strings.continue_to_next_step), painterResource(R.drawable.ic_chevron_right), click = onClick) + SimpleButtonIconEnded(stringResource(MR.strings.continue_to_next_step), painterResource(MR.images.ic_chevron_right), click = onClick) } @Composable private fun SkipButton(onClick: () -> Unit) { - SimpleButtonIconEnded(stringResource(MR.strings.dont_create_address), painterResource(R.drawable.ic_chevron_right), click = onClick) + SimpleButtonIconEnded(stringResource(MR.strings.dont_create_address), painterResource(MR.images.ic_chevron_right), click = onClick) TextBelowButton(stringResource(MR.strings.you_can_create_it_later)) } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/SimpleXInfo.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/SimpleXInfo.kt index 8b828b0d60..9c47931a40 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/SimpleXInfo.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/SimpleXInfo.kt @@ -10,7 +10,7 @@ import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -52,9 +52,9 @@ fun SimpleXInfoLayout( Text(stringResource(MR.strings.next_generation_of_private_messaging), style = MaterialTheme.typography.h2, modifier = Modifier.padding(bottom = 48.dp).padding(horizontal = 36.dp), textAlign = TextAlign.Center) - InfoRow(painterResource(R.drawable.privacy), MR.strings.privacy_redefined, MR.strings.first_platform_without_user_ids, width = 80.dp) - InfoRow(painterResource(R.drawable.shield), MR.strings.immune_to_spam_and_abuse, MR.strings.people_can_connect_only_via_links_you_share) - InfoRow(painterResource(if (isInDarkTheme()) R.drawable.decentralized_light else R.drawable.decentralized), MR.strings.decentralized, MR.strings.opensource_protocol_and_code_anybody_can_run_servers) + InfoRow(painterResource(MR.images.privacy), MR.strings.privacy_redefined, MR.strings.first_platform_without_user_ids, width = 80.dp) + InfoRow(painterResource(MR.images.shield), MR.strings.immune_to_spam_and_abuse, MR.strings.people_can_connect_only_via_links_you_share) + InfoRow(painterResource(if (isInDarkTheme()) MR.images.decentralized_light else MR.images.decentralized), MR.strings.decentralized, MR.strings.opensource_protocol_and_code_anybody_can_run_servers) Spacer(Modifier.fillMaxHeight().weight(1f)) @@ -70,7 +70,7 @@ fun SimpleXInfoLayout( .fillMaxWidth() .padding(bottom = DEFAULT_PADDING.times(1.5f), top = DEFAULT_PADDING), contentAlignment = Alignment.Center ) { - SimpleButtonDecorated(text = stringResource(MR.strings.how_it_works), icon = painterResource(R.drawable.ic_info), + SimpleButtonDecorated(text = stringResource(MR.strings.how_it_works), icon = painterResource(MR.images.ic_info), click = showModal { HowItWorks(user, onboardingStage) }) } } @@ -79,7 +79,7 @@ fun SimpleXInfoLayout( @Composable fun SimpleXLogo() { Image( - painter = painterResource(if (isInDarkTheme()) R.drawable.logo_light else R.drawable.logo), + painter = painterResource(if (isInDarkTheme()) MR.images.logo_light else MR.images.logo), contentDescription = stringResource(MR.strings.image_descr_simplex_logo), modifier = Modifier .padding(vertical = DEFAULT_PADDING) @@ -137,7 +137,7 @@ fun OnboardingActionButton( }, modifier) { Text(stringResource(labelId), style = MaterialTheme.typography.h2, color = MaterialTheme.colors.primary, fontSize = 20.sp) Icon( - painterResource(R.drawable.ic_arrow_forward_ios), "next stage", tint = MaterialTheme.colors.primary, + painterResource(MR.images.ic_arrow_forward_ios), "next stage", tint = MaterialTheme.colors.primary, modifier = Modifier.padding(start = DEFAULT_PADDING.div(4)).size(20.dp) ) } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/WhatsNewView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/WhatsNewView.kt index 7cf67763a0..923b47eb83 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/WhatsNewView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/onboarding/WhatsNewView.kt @@ -13,7 +13,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import androidx.compose.ui.res.stringResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight @@ -28,6 +28,7 @@ import chat.simplex.app.model.ChatModel import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.* import chat.simplex.res.MR +import dev.icerock.moko.resources.ImageResource import dev.icerock.moko.resources.StringResource @Composable @@ -40,7 +41,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { fun linkButton(link: String) { val uriHandler = LocalUriHandler.current Icon( - painterResource(R.drawable.ic_open_in_new), stringResource(titleId), tint = MaterialTheme.colors.primary, + painterResource(MR.images.ic_open_in_new), stringResource(titleId), tint = MaterialTheme.colors.primary, modifier = Modifier .clickable { uriHandler.openUriCatching(link) } ) @@ -84,7 +85,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { .clickable { currentVersion.value = prev } .padding(8.dp) ) { - Icon(painterResource(R.drawable.ic_arrow_back_ios_new), "previous", tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_arrow_back_ios_new), "previous", tint = MaterialTheme.colors.primary) Text(versionDescriptions[prev].version, color = MaterialTheme.colors.primary) } } @@ -101,7 +102,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { .padding(8.dp) ) { Text(versionDescriptions[next].version, color = MaterialTheme.colors.primary) - Icon(painterResource(R.drawable.ic_arrow_forward_ios), "next", tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_arrow_forward_ios), "next", tint = MaterialTheme.colors.primary) } } } @@ -129,7 +130,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = DEFAULT_PADDING.div(4))) { Text(stringResource(MR.strings.whats_new_read_more), color = MaterialTheme.colors.primary, modifier = Modifier.clickable { uriHandler.openUriCatching(v.post) }) - Icon(painterResource(R.drawable.ic_open_in_new), stringResource(MR.strings.whats_new_read_more), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_open_in_new), stringResource(MR.strings.whats_new_read_more), tint = MaterialTheme.colors.primary) } } @@ -156,7 +157,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { } private data class FeatureDescription( - val icon: Int, + val icon: ImageResource, val titleId: StringResource, val descrId: StringResource, val link: String? = null @@ -174,18 +175,18 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_verified_user, + icon = MR.images.ic_verified_user, titleId = MR.strings.v4_2_security_assessment, descrId = MR.strings.v4_2_security_assessment_desc, link = "https://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html" ), FeatureDescription( - icon = R.drawable.ic_group, + icon = MR.images.ic_group, titleId = MR.strings.v4_2_group_links, descrId = MR.strings.v4_2_group_links_desc ), FeatureDescription( - icon = R.drawable.ic_check, + icon = MR.images.ic_check, titleId = MR.strings.v4_2_auto_accept_contact_requests, descrId = MR.strings.v4_2_auto_accept_contact_requests_desc ), @@ -196,22 +197,22 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20221206-simplex-chat-v4.3-voice-messages.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_mic, + icon = MR.images.ic_mic, titleId = MR.strings.v4_3_voice_messages, descrId = MR.strings.v4_3_voice_messages_desc ), FeatureDescription( - icon = R.drawable.ic_delete_forever, + icon = MR.images.ic_delete_forever, titleId = MR.strings.v4_3_irreversible_message_deletion, descrId = MR.strings.v4_3_irreversible_message_deletion_desc ), FeatureDescription( - icon = R.drawable.ic_wifi_tethering, + icon = MR.images.ic_wifi_tethering, titleId = MR.strings.v4_3_improved_server_configuration, descrId = MR.strings.v4_3_improved_server_configuration_desc ), FeatureDescription( - icon = R.drawable.ic_visibility_off, + icon = MR.images.ic_visibility_off, titleId = MR.strings.v4_3_improved_privacy_and_security, descrId = MR.strings.v4_3_improved_privacy_and_security_desc ), @@ -222,22 +223,22 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20230103-simplex-chat-v4.4-disappearing-messages.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_timer, + icon = MR.images.ic_timer, titleId = MR.strings.v4_4_disappearing_messages, descrId = MR.strings.v4_4_disappearing_messages_desc ), FeatureDescription( - icon = R.drawable.ic_pending, + icon = MR.images.ic_pending, titleId = MR.strings.v4_4_live_messages, descrId = MR.strings.v4_4_live_messages_desc ), FeatureDescription( - icon = R.drawable.ic_verified_user, + icon = MR.images.ic_verified_user, titleId = MR.strings.v4_4_verify_connection_security, descrId = MR.strings.v4_4_verify_connection_security_desc ), FeatureDescription( - icon = R.drawable.ic_translate, + icon = MR.images.ic_translate, titleId = MR.strings.v4_4_french_interface, descrId = MR.strings.v4_4_french_interface_descr ) @@ -248,33 +249,33 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_manage_accounts, + icon = MR.images.ic_manage_accounts, titleId = MR.strings.v4_5_multiple_chat_profiles, descrId = MR.strings.v4_5_multiple_chat_profiles_descr ), FeatureDescription( - icon = R.drawable.ic_edit_note, + icon = MR.images.ic_edit_note, titleId = MR.strings.v4_5_message_draft, descrId = MR.strings.v4_5_message_draft_descr ), FeatureDescription( - icon = R.drawable.ic_safety_divider, + icon = MR.images.ic_safety_divider, titleId = MR.strings.v4_5_transport_isolation, descrId = MR.strings.v4_5_transport_isolation_descr, link = "https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation" ), FeatureDescription( - icon = R.drawable.ic_task, + icon = MR.images.ic_task, titleId = MR.strings.v4_5_private_filenames, descrId = MR.strings.v4_5_private_filenames_descr ), FeatureDescription( - icon = R.drawable.ic_battery_2_bar, + icon = MR.images.ic_battery_2_bar, titleId = MR.strings.v4_5_reduced_battery_usage, descrId = MR.strings.v4_5_reduced_battery_usage_descr ), FeatureDescription( - icon = R.drawable.ic_translate, + icon = MR.images.ic_translate, titleId = MR.strings.v4_5_italian_interface, descrId = MR.strings.v4_5_italian_interface_descr, link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" @@ -286,32 +287,32 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20230328-simplex-chat-v4-6-hidden-profiles.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_lock, + icon = MR.images.ic_lock, titleId = MR.strings.v4_6_hidden_chat_profiles, descrId = MR.strings.v4_6_hidden_chat_profiles_descr ), FeatureDescription( - icon = R.drawable.ic_flag, + icon = MR.images.ic_flag, titleId = MR.strings.v4_6_group_moderation, descrId = MR.strings.v4_6_group_moderation_descr ), FeatureDescription( - icon = R.drawable.ic_maps_ugc, + icon = MR.images.ic_maps_ugc, titleId = MR.strings.v4_6_group_welcome_message, descrId = MR.strings.v4_6_group_welcome_message_descr ), FeatureDescription( - icon = R.drawable.ic_call, + icon = MR.images.ic_call, titleId = MR.strings.v4_6_audio_video_calls, descrId = MR.strings.v4_6_audio_video_calls_descr ), FeatureDescription( - icon = R.drawable.ic_battery_3_bar, + icon = MR.images.ic_battery_3_bar, titleId = MR.strings.v4_6_reduced_battery_usage, descrId = MR.strings.v4_6_reduced_battery_usage_descr ), FeatureDescription( - icon = R.drawable.ic_translate, + icon = MR.images.ic_translate, titleId = MR.strings.v4_6_chinese_spanish_interface, descrId = MR.strings.v4_6_chinese_spanish_interface_descr, link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" @@ -323,17 +324,17 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_upload_file, + icon = MR.images.ic_upload_file, titleId = MR.strings.v5_0_large_files_support, descrId = MR.strings.v5_0_large_files_support_descr ), FeatureDescription( - icon = R.drawable.ic_lock, + icon = MR.images.ic_lock, titleId = MR.strings.v5_0_app_passcode, descrId = MR.strings.v5_0_app_passcode_descr ), FeatureDescription( - icon = R.drawable.ic_translate, + icon = MR.images.ic_translate, titleId = MR.strings.v5_0_polish_interface, descrId = MR.strings.v5_0_polish_interface_descr, link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" @@ -351,27 +352,27 @@ private val versionDescriptions: List = listOf( post = "https://simplex.chat/blog/20230523-simplex-chat-v5-1-message-reactions-self-destruct-passcode.html", features = listOf( FeatureDescription( - icon = R.drawable.ic_add_reaction, + icon = MR.images.ic_add_reaction, titleId = MR.strings.v5_1_message_reactions, descrId = MR.strings.v5_1_message_reactions_descr ), FeatureDescription( - icon = R.drawable.ic_chat, + icon = MR.images.ic_chat, titleId = MR.strings.v5_1_better_messages, descrId = MR.strings.v5_1_better_messages_descr ), FeatureDescription( - icon = R.drawable.ic_light_mode, + icon = MR.images.ic_light_mode, titleId = MR.strings.v5_1_custom_themes, descrId = MR.strings.v5_1_custom_themes_descr ), FeatureDescription( - icon = R.drawable.ic_lock, + icon = MR.images.ic_lock, titleId = MR.strings.v5_1_self_destruct_passcode, descrId = MR.strings.v5_1_self_destruct_passcode_descr ), FeatureDescription( - icon = R.drawable.ic_translate, + icon = MR.images.ic_translate, titleId = MR.strings.v5_1_japanese_portuguese_interface, descrId = MR.strings.whats_new_thanks_to_users_contribute_weblate, link = "https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat" diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/AdvancedNetworkSettings.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/AdvancedNetworkSettings.kt index 2891861e8b..0c2341c69b 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/AdvancedNetworkSettings.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -24,6 +24,7 @@ import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.helpers.* import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource import java.text.DecimalFormat @Composable @@ -272,7 +273,7 @@ fun IntSettingRow(title: String, selection: MutableState, values: List ) Spacer(Modifier.size(4.dp)) Icon( - if (!expanded.value) painterResource(R.drawable.ic_expand_more) else painterResource(R.drawable.ic_expand_less), + if (!expanded.value) painterResource(MR.images.ic_expand_more) else painterResource(MR.images.ic_expand_less), generalGetString(MR.strings.invite_to_group_button), modifier = Modifier.padding(start = 8.dp), tint = MaterialTheme.colors.secondary @@ -332,7 +333,7 @@ fun TimeoutSettingRow(title: String, selection: MutableState, values: List ) Spacer(Modifier.size(4.dp)) Icon( - if (!expanded.value) painterResource(R.drawable.ic_expand_more) else painterResource(R.drawable.ic_expand_less), + if (!expanded.value) painterResource(MR.images.ic_expand_more) else painterResource(MR.images.ic_expand_less), generalGetString(MR.strings.invite_to_group_button), modifier = Modifier.padding(start = 8.dp), tint = MaterialTheme.colors.secondary @@ -368,8 +369,8 @@ fun SettingsSectionFooter(revert: () -> Unit, save: () -> Unit, disabled: Boolea horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { - FooterButton(painterResource(R.drawable.ic_replay), stringResource(MR.strings.network_options_revert), revert, disabled) - FooterButton(painterResource(R.drawable.ic_check), stringResource(MR.strings.network_options_save), save, disabled) + FooterButton(painterResource(MR.images.ic_replay), stringResource(MR.strings.network_options_revert), revert, disabled) + FooterButton(painterResource(MR.images.ic_check), stringResource(MR.strings.network_options_save), save, disabled) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt index 5047818ba3..cdf1f9900a 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.* import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -186,47 +186,47 @@ fun CustomizeThemeView(editColor: (ThemeColor, Color) -> Unit) { SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY, currentTheme.colors.primary) }) { val title = generalGetString(MR.strings.color_primary) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.primary) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.primary) } SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT, currentTheme.colors.primaryVariant) }) { val title = generalGetString(MR.strings.color_primary_variant) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.primaryVariant) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.primaryVariant) } SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY, currentTheme.colors.secondary) }) { val title = generalGetString(MR.strings.color_secondary) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.secondary) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.secondary) } SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY_VARIANT, currentTheme.colors.secondaryVariant) }) { val title = generalGetString(MR.strings.color_secondary_variant) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.secondaryVariant) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.secondaryVariant) } SectionItemViewSpaceBetween({ editColor(ThemeColor.BACKGROUND, currentTheme.colors.background) }) { val title = generalGetString(MR.strings.color_background) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.background) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.background) } SectionItemViewSpaceBetween({ editColor(ThemeColor.SURFACE, currentTheme.colors.surface) }) { val title = generalGetString(MR.strings.color_surface) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.surface) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = colors.surface) } SectionItemViewSpaceBetween({ editColor(ThemeColor.TITLE, currentTheme.appColors.title) }) { val title = generalGetString(MR.strings.color_title) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = currentTheme.appColors.title) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.title) } SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_MESSAGE, currentTheme.appColors.sentMessage) }) { val title = generalGetString(MR.strings.color_sent_message) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = currentTheme.appColors.sentMessage) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.sentMessage) } SectionItemViewSpaceBetween({ editColor(ThemeColor.RECEIVED_MESSAGE, currentTheme.appColors.receivedMessage) }) { val title = generalGetString(MR.strings.color_received_message) Text(title) - Icon(painterResource(R.drawable.ic_circle_filled), title, tint = currentTheme.appColors.receivedMessage) + Icon(painterResource(MR.images.ic_circle_filled), title, tint = currentTheme.appColors.receivedMessage) } } val isInDarkTheme = isInDarkTheme() diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/DeveloperView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/DeveloperView.kt index 5a566ac480..a3e51c1dab 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/DeveloperView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/DeveloperView.kt @@ -10,7 +10,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import chat.simplex.app.R import chat.simplex.app.model.ChatModel @@ -32,8 +32,8 @@ fun DeveloperView( SectionView() { InstallTerminalAppItem(uriHandler) ChatConsoleItem { withAuth(generalGetString(MR.strings.auth_open_chat_console), generalGetString(MR.strings.auth_log_in_using_credential), showCustomModal { it, close -> TerminalView(it, close) })} - SettingsPreferenceItem(painterResource(R.drawable.ic_drive_folder_upload), stringResource(MR.strings.confirm_database_upgrades), m.controller.appPrefs.confirmDBUpgrades) - SettingsPreferenceItem(painterResource(R.drawable.ic_code), stringResource(MR.strings.show_developer_options), developerTools) + SettingsPreferenceItem(painterResource(MR.images.ic_drive_folder_upload), stringResource(MR.strings.confirm_database_upgrades), m.controller.appPrefs.confirmDBUpgrades) + SettingsPreferenceItem(painterResource(MR.images.ic_code), stringResource(MR.strings.show_developer_options), developerTools) } SectionTextFooter( generalGetString(if (devTools.value) MR.strings.show_dev_options else MR.strings.hide_dev_options) + " " + diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt index da055fcbee..72292d80ba 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt @@ -15,11 +15,10 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.* import androidx.compose.ui.text.input.* import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -167,16 +166,16 @@ fun NetworkAndServersView( ) { AppBarTitle(stringResource(MR.strings.network_and_servers)) SectionView(generalGetString(MR.strings.settings_section_title_messages)) { - SettingsActionItem(painterResource(R.drawable.ic_dns), stringResource(MR.strings.smp_servers), showCustomModal { m, close -> ProtocolServersView(m, ServerProtocol.SMP, close) }) + SettingsActionItem(painterResource(MR.images.ic_dns), stringResource(MR.strings.smp_servers), showCustomModal { m, close -> ProtocolServersView(m, ServerProtocol.SMP, close) }) - SettingsActionItem(painterResource(R.drawable.ic_dns), stringResource(MR.strings.xftp_servers), showCustomModal { m, close -> ProtocolServersView(m, ServerProtocol.XFTP, close) }) + SettingsActionItem(painterResource(MR.images.ic_dns), stringResource(MR.strings.xftp_servers), showCustomModal { m, close -> ProtocolServersView(m, ServerProtocol.XFTP, close) }) UseSocksProxySwitch(networkUseSocksProxy, proxyPort, toggleSocksProxy, showSettingsModal) UseOnionHosts(onionHosts, networkUseSocksProxy, showSettingsModal, useOnion) if (developerTools) { SessionModePicker(sessionMode, showSettingsModal, updateSessionMode) } - SettingsActionItem(painterResource(R.drawable.ic_cable), stringResource(MR.strings.network_settings), showSettingsModal { AdvancedNetworkSettingsView(it) }) + SettingsActionItem(painterResource(MR.images.ic_cable), stringResource(MR.strings.network_settings), showSettingsModal { AdvancedNetworkSettingsView(it) }) } if (networkUseSocksProxy.value) { SectionCustomFooter { Text(annotatedStringResource(MR.strings.disable_onion_hosts_when_not_supported)) } @@ -186,7 +185,7 @@ fun NetworkAndServersView( } SectionView(generalGetString(MR.strings.settings_section_title_calls)) { - SettingsActionItem(painterResource(R.drawable.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), showModal { RTCServersView(it) }) + SettingsActionItem(painterResource(MR.images.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), showModal { RTCServersView(it) }) } SectionBottomSpacer() } @@ -209,7 +208,7 @@ fun UseSocksProxySwitch( verticalAlignment = Alignment.CenterVertically ) { Icon( - painterResource(R.drawable.ic_settings_ethernet), + painterResource(MR.images.ic_settings_ethernet), stringResource(MR.strings.network_socks_toggle_use_socks_proxy), tint = MaterialTheme.colors.secondary ) @@ -224,7 +223,7 @@ fun UseSocksProxySwitch( } ClickableText( text, - style = TextStyle(color = MaterialTheme.colors.onBackground, fontSize = 16.sp, fontFamily = FontFamily(Font(R.font.inter_regular))), + style = TextStyle(color = MaterialTheme.colors.onBackground, fontSize = 16.sp, fontFamily = Inter, fontWeight = FontWeight.Normal), onClick = { offset -> text.getStringAnnotations(tag = "PORT", start = offset, end = offset) .firstOrNull()?.let { _ -> @@ -356,7 +355,7 @@ private fun UseOnionHosts( generalGetString(MR.strings.network_use_onion_hosts), onionHosts, values, - icon = painterResource(R.drawable.ic_security), + icon = painterResource(MR.images.ic_security), enabled = enabled, onSelected = onSelected ) @@ -381,7 +380,7 @@ private fun SessionModePicker( generalGetString(MR.strings.network_session_mode_transport_isolation), sessionMode, values, - icon = painterResource(R.drawable.ic_safety_divider), + icon = painterResource(MR.images.ic_safety_divider), onSelected = showModal { Column( Modifier.fillMaxWidth(), @@ -400,8 +399,8 @@ private fun NetworkSectionFooter(revert: () -> Unit, save: () -> Unit, revertDis horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { - FooterButton(painterResource(R.drawable.ic_replay), stringResource(MR.strings.network_options_revert), revert, revertDisabled) - FooterButton(painterResource(R.drawable.ic_check), stringResource(MR.strings.network_options_save), save, saveDisabled) + FooterButton(painterResource(MR.images.ic_replay), stringResource(MR.strings.network_options_revert), revert, revertDisabled) + FooterButton(painterResource(MR.images.ic_check), stringResource(MR.strings.network_options_save), save, saveDisabled) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/PrivacySettings.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/PrivacySettings.kt index 9ca2439283..d4f8d1eccc 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/PrivacySettings.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/PrivacySettings.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -55,7 +55,7 @@ fun PrivacySettingsView( SectionView(stringResource(MR.strings.settings_section_title_device)) { ChatLockItem(chatModel, showSettingsModal, setPerformLA) val context = LocalContext.current - SettingsPreferenceItem(painterResource(R.drawable.ic_visibility_off), stringResource(MR.strings.protect_app_screen), chatModel.controller.appPrefs.privacyProtectScreen) { on -> + SettingsPreferenceItem(painterResource(MR.images.ic_visibility_off), stringResource(MR.strings.protect_app_screen), chatModel.controller.appPrefs.privacyProtectScreen) { on -> if (on) { (context as? FragmentActivity)?.window?.setFlags( WindowManager.LayoutParams.FLAG_SECURE, @@ -69,8 +69,8 @@ fun PrivacySettingsView( SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_chats)) { - SettingsPreferenceItem(painterResource(R.drawable.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages) - SettingsPreferenceItem(painterResource(R.drawable.ic_travel_explore), stringResource(MR.strings.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews) + SettingsPreferenceItem(painterResource(MR.images.ic_image), stringResource(MR.strings.auto_accept_images), chatModel.controller.appPrefs.privacyAcceptImages) + SettingsPreferenceItem(painterResource(MR.images.ic_travel_explore), stringResource(MR.strings.send_link_previews), chatModel.controller.appPrefs.privacyLinkPreviews) SimpleXLinkOptions(chatModel.simplexLinkMode, onSelected = { simplexLinkMode.set(it) chatModel.simplexLinkMode.value = it @@ -322,7 +322,7 @@ fun SimplexLockView( SettingsActionItemWithContent(null, null, click = openInfo) { SharedPreferenceToggleWithIcon( stringResource(MR.strings.enable_self_destruct), - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), openInfo, remember { selfDestructPref.state }.value ) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServerView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServerView.kt index a14f29062a..a711275ccf 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServerView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServerView.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily @@ -138,7 +138,7 @@ private fun CustomServer( } SectionView( stringResource(MR.strings.smp_servers_your_server_address).uppercase(), - icon = painterResource(R.drawable.ic_error), + icon = painterResource(MR.images.ic_error), iconTint = if (!valid.value) MaterialTheme.colors.error else Color.Transparent, ) { val testedPreviously = remember { mutableMapOf() } @@ -191,9 +191,9 @@ private fun UseServerSection( @Composable fun ShowTestStatus(server: ServerCfg, modifier: Modifier = Modifier) = when (server.tested) { - true -> Icon(painterResource(R.drawable.ic_check), null, modifier, tint = SimplexGreen) - false -> Icon(painterResource(R.drawable.ic_close), null, modifier, tint = MaterialTheme.colors.error) - else -> Icon(painterResource(R.drawable.ic_check), null, modifier, tint = Color.Transparent) + true -> Icon(painterResource(MR.images.ic_check), null, modifier, tint = SimplexGreen) + false -> Icon(painterResource(MR.images.ic_close), null, modifier, tint = MaterialTheme.colors.error) + else -> Icon(painterResource(MR.images.ic_check), null, modifier, tint = Color.Transparent) } suspend fun testServerConnection(server: ServerCfg, m: ChatModel): Pair = diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServersView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServersView.kt index 13b69b6287..6443bfc3f8 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServersView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/ProtocolServersView.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight @@ -204,7 +204,7 @@ private fun ProtocolServersLayout( } } SettingsActionItem( - painterResource(R.drawable.ic_add), + painterResource(MR.images.ic_add), stringResource(MR.strings.smp_servers_add), addServer, disabled = testing, @@ -249,7 +249,7 @@ private fun ProtocolServerView(serverProtocol: ServerProtocol, srv: ServerCfg, s val address = parseServerAddress(srv.server) when { address == null || !address.valid || address.serverProtocol != serverProtocol || !uniqueAddress(srv, address, servers) -> InvalidServer() - !srv.enabled -> Icon(painterResource(R.drawable.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary) + !srv.enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary) else -> ShowTestStatus(srv) } Spacer(Modifier.padding(horizontal = 4.dp)) @@ -265,7 +265,7 @@ private fun ProtocolServerView(serverProtocol: ServerProtocol, srv: ServerCfg, s private fun HowToButton() { val uriHandler = LocalUriHandler.current SettingsActionItem( - painterResource(R.drawable.ic_open_in_new), + painterResource(MR.images.ic_open_in_new), stringResource(MR.strings.how_to_use_your_servers), { uriHandler.openUriCatching("https://simplex.chat/docs/server.html") }, textColor = MaterialTheme.colors.primary, @@ -275,7 +275,7 @@ private fun HowToButton() { @Composable fun InvalidServer() { - Icon(painterResource(R.drawable.ic_error), null, tint = MaterialTheme.colors.error) + Icon(painterResource(MR.images.ic_error), null, tint = MaterialTheme.colors.error) } private fun uniqueAddress(s: ServerCfg, address: ServerAddress, servers: List): Boolean = servers.all { srv -> diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt index e21fbda51d..f79b968b15 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt @@ -12,7 +12,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily @@ -202,7 +202,7 @@ private fun howToButton() { ) { Text(stringResource(MR.strings.how_to), color = MaterialTheme.colors.primary) Icon( - painterResource(R.drawable.ic_open_in_new), stringResource(MR.strings.how_to), tint = MaterialTheme.colors.primary, + painterResource(MR.images.ic_open_in_new), stringResource(MR.strings.how_to), tint = MaterialTheme.colors.primary, modifier = Modifier.padding(horizontal = 5.dp) ) } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt index 18313e10b8..b033f69f38 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.* -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -100,7 +100,7 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) { ) { SimpleButton( stringResource(MR.strings.auth_unlock), - icon = painterResource(R.drawable.ic_lock), + icon = painterResource(MR.images.ic_lock), click = { runAuth(title, desc, onFinishAuth) } @@ -147,29 +147,29 @@ fun SettingsLayout( ProfilePreview(profile, stopped = stopped) } val profileHidden = rememberSaveable { mutableStateOf(false) } - SettingsActionItem(painterResource(R.drawable.ic_manage_accounts), stringResource(MR.strings.your_chat_profiles), { withAuth(generalGetString(MR.strings.auth_open_chat_profiles), generalGetString(MR.strings.auth_log_in_using_credential)) { showSettingsModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden) } } }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_manage_accounts), stringResource(MR.strings.your_chat_profiles), { withAuth(generalGetString(MR.strings.auth_open_chat_profiles), generalGetString(MR.strings.auth_log_in_using_credential)) { showSettingsModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden) } } }, disabled = stopped, extraPadding = true) SettingsIncognitoActionItem(incognitoPref, incognito, stopped) { showModal { IncognitoView() }() } - SettingsActionItem(painterResource(R.drawable.ic_qr_code), stringResource(MR.strings.your_simplex_contact_address), showCustomModal { it, close -> UserAddressView(it, shareViaProfile = it.currentUser.value!!.addressShared, close = close) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_qr_code), stringResource(MR.strings.your_simplex_contact_address), showCustomModal { it, close -> UserAddressView(it, shareViaProfile = it.currentUser.value!!.addressShared, close = close) }, disabled = stopped, extraPadding = true) ChatPreferencesItem(showCustomModal, stopped = stopped) } SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_settings)) { - SettingsActionItem(painterResource(R.drawable.ic_bolt), stringResource(MR.strings.notifications), showSettingsModal { NotificationsSettingsView(it) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showSettingsModal { NetworkAndServersView(it, showModal, showSettingsModal, showCustomModal) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_lock), stringResource(MR.strings.privacy_and_security), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_light_mode), stringResource(MR.strings.appearance_settings), showSettingsModal { AppearanceView(it, showSettingsModal) }, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_bolt), stringResource(MR.strings.notifications), showSettingsModal { NotificationsSettingsView(it) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showSettingsModal { NetworkAndServersView(it, showModal, showSettingsModal, showCustomModal) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.privacy_and_security), showSettingsModal { PrivacySettingsView(it, showSettingsModal, setPerformLA) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_light_mode), stringResource(MR.strings.appearance_settings), showSettingsModal { AppearanceView(it, showSettingsModal) }, extraPadding = true) DatabaseItem(encrypted, showSettingsModal { DatabaseView(it, showSettingsModal) }, stopped) } SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_help)) { - SettingsActionItem(painterResource(R.drawable.ic_help), stringResource(MR.strings.how_to_use_simplex_chat), showModal { HelpView(userDisplayName) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_add), stringResource(MR.strings.whats_new), showCustomModal { _, close -> WhatsNewView(viaSettings = true, close) }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_info), stringResource(MR.strings.about_simplex_chat), showModal { SimpleXInfo(it, onboarding = false) }, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_tag), stringResource(MR.strings.chat_with_the_founder), { uriHandler.openUriCatching(simplexTeamUri) }, textColor = MaterialTheme.colors.primary, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_mail), stringResource(MR.strings.send_us_an_email), { uriHandler.openUriCatching("mailto:chat@simplex.chat") }, textColor = MaterialTheme.colors.primary, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_help), stringResource(MR.strings.how_to_use_simplex_chat), showModal { HelpView(userDisplayName) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_add), stringResource(MR.strings.whats_new), showCustomModal { _, close -> WhatsNewView(viaSettings = true, close) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_info), stringResource(MR.strings.about_simplex_chat), showModal { SimpleXInfo(it, onboarding = false) }, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_tag), stringResource(MR.strings.chat_with_the_founder), { uriHandler.openUriCatching(simplexTeamUri) }, textColor = MaterialTheme.colors.primary, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_mail), stringResource(MR.strings.send_us_an_email), { uriHandler.openUriCatching("mailto:chat@simplex.chat") }, textColor = MaterialTheme.colors.primary, extraPadding = true) } SectionDividerSpaced() @@ -181,9 +181,9 @@ fun SettingsLayout( SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_app)) { - SettingsActionItem(painterResource(R.drawable.ic_restart_alt), stringResource(MR.strings.settings_restart_app), ::restartApp, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_power_settings_new), stringResource(MR.strings.settings_shutdown), { shutdownAppAlert(::shutdownApp) }, extraPadding = true) - SettingsActionItem(painterResource(R.drawable.ic_code), stringResource(MR.strings.settings_developer_tools), showSettingsModal { DeveloperView(it, showCustomModal, withAuth) }, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_restart_alt), stringResource(MR.strings.settings_restart_app), ::restartApp, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_power_settings_new), stringResource(MR.strings.settings_shutdown), { shutdownAppAlert(::shutdownApp) }, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_code), stringResource(MR.strings.settings_developer_tools), showSettingsModal { DeveloperView(it, showCustomModal, withAuth) }, extraPadding = true) AppVersionItem(showVersion) } SectionBottomSpacer() @@ -199,7 +199,7 @@ fun SettingsIncognitoActionItem( onClickInfo: () -> Unit, ) { SettingsPreferenceItemWithInfo( - if (incognito.value) painterResource(R.drawable.ic_theater_comedy_filled) else painterResource(R.drawable.ic_theater_comedy), + if (incognito.value) painterResource(MR.images.ic_theater_comedy_filled) else painterResource(MR.images.ic_theater_comedy), if (incognito.value) Indigo else MaterialTheme.colors.secondary, stringResource(MR.strings.incognito), stopped, @@ -236,7 +236,7 @@ fun MaintainIncognitoState(chatModel: ChatModel) { ) { Row(Modifier.weight(1f)) { Icon( - painterResource(R.drawable.ic_database), + painterResource(MR.images.ic_database), contentDescription = stringResource(MR.strings.database_passphrase_and_export), tint = if (encrypted) MaterialTheme.colors.secondary else WarningOrange, ) @@ -245,7 +245,7 @@ fun MaintainIncognitoState(chatModel: ChatModel) { } if (stopped) { Icon( - painterResource(R.drawable.ic_report_filled), + painterResource(MR.images.ic_report_filled), contentDescription = stringResource(MR.strings.chat_is_stopped), tint = Color.Red, modifier = Modifier.padding(end = 6.dp) @@ -257,7 +257,7 @@ fun MaintainIncognitoState(chatModel: ChatModel) { @Composable fun ChatPreferencesItem(showCustomModal: ((@Composable (ChatModel, () -> Unit) -> Unit) -> (() -> Unit)), stopped: Boolean) { SettingsActionItem( - painterResource(R.drawable.ic_toggle_on), + painterResource(MR.images.ic_toggle_on), stringResource(MR.strings.chat_preferences), click = if (stopped) null else ({ withApi { @@ -281,7 +281,7 @@ fun ChatLockItem( val currentLAMode = remember { chatModel.controller.appPrefs.laMode } SettingsActionItemWithContent( click = showSettingsModal { SimplexLockView(chatModel, currentLAMode, setPerformLA) }, - icon = if (performLA.value) painterResource(R.drawable.ic_lock_filled) else painterResource(R.drawable.ic_lock), + icon = if (performLA.value) painterResource(MR.images.ic_lock_filled) else painterResource(MR.images.ic_lock), text = stringResource(MR.strings.chat_lock), iconColor = if (performLA.value) SimplexGreen else MaterialTheme.colors.secondary, extraPadding = false, @@ -293,7 +293,7 @@ fun ChatLockItem( @Composable private fun ContributeItem(uriHandler: UriHandler) { SectionItemViewWithIcon({ uriHandler.openUriCatching("https://github.com/simplex-chat/simplex-chat#contribute") }) { Icon( - painterResource(R.drawable.ic_keyboard), + painterResource(MR.images.ic_keyboard), contentDescription = "GitHub", tint = MaterialTheme.colors.secondary, ) @@ -309,7 +309,7 @@ fun ChatLockItem( } ) { Icon( - painterResource(R.drawable.ic_star), + painterResource(MR.images.ic_star), contentDescription = "Google Play", tint = MaterialTheme.colors.secondary, ) @@ -321,7 +321,7 @@ fun ChatLockItem( @Composable private fun StarOnGithubItem(uriHandler: UriHandler) { SectionItemViewWithIcon({ uriHandler.openUriCatching("https://github.com/simplex-chat/simplex-chat") }) { Icon( - painter = painterResource(id = R.drawable.ic_github), + painter = painterResource(MR.images.ic_github), contentDescription = "GitHub", tint = MaterialTheme.colors.secondary, ) @@ -333,7 +333,7 @@ fun ChatLockItem( @Composable fun ChatConsoleItem(showTerminal: () -> Unit) { SectionItemView(showTerminal) { Icon( - painter = painterResource(id = R.drawable.ic_outline_terminal), + painter = painterResource(MR.images.ic_outline_terminal), contentDescription = stringResource(MR.strings.chat_console), tint = MaterialTheme.colors.secondary, ) @@ -345,7 +345,7 @@ fun ChatLockItem( @Composable fun InstallTerminalAppItem(uriHandler: UriHandler) { SectionItemView({ uriHandler.openUriCatching("https://github.com/simplex-chat/simplex-chat") }) { Icon( - painter = painterResource(id = R.drawable.ic_github), + painter = painterResource(MR.images.ic_github), contentDescription = "GitHub", tint = MaterialTheme.colors.secondary, ) @@ -443,7 +443,7 @@ fun SettingsPreferenceItemWithInfo( prefState: MutableState? = null ) { SettingsActionItemWithContent(icon, null, click = if (stopped) null else onClickInfo, iconColor = iconTint, extraPadding = true,) { - SharedPreferenceToggleWithIcon(text, painterResource(R.drawable.ic_info), stopped, onClickInfo, pref, prefState) + SharedPreferenceToggleWithIcon(text, painterResource(MR.images.ic_info), stopped, onClickInfo, pref, prefState) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserAddressView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserAddressView.kt index 9bbf00bbd9..2cd8484296 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserAddressView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserAddressView.kt @@ -16,7 +16,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -231,7 +231,7 @@ private fun UserAddressLayout( @Composable private fun CreateAddressButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_qr_code), + painterResource(MR.images.ic_qr_code), stringResource(MR.strings.create_simplex_address), onClick, iconColor = MaterialTheme.colors.primary, @@ -242,7 +242,7 @@ private fun CreateAddressButton(onClick: () -> Unit) { @Composable private fun LearnMoreButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_info), + painterResource(MR.images.ic_info), stringResource(MR.strings.learn_more_about_address), onClick, ) @@ -251,7 +251,7 @@ private fun LearnMoreButton(onClick: () -> Unit) { @Composable fun ShareViaEmailButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_mail), + painterResource(MR.images.ic_mail), stringResource(MR.strings.invite_friends), onClick, iconColor = MaterialTheme.colors.primary, @@ -263,7 +263,7 @@ fun ShareViaEmailButton(onClick: () -> Unit) { fun ShareWithContactsButton(shareViaProfile: MutableState, setProfileAddress: (Boolean) -> Unit) { PreferenceToggleWithIcon( stringResource(MR.strings.share_with_contacts), - painterResource(R.drawable.ic_person), + painterResource(MR.images.ic_person), checked = shareViaProfile.value, ) { on -> shareViaProfile.value = on @@ -301,7 +301,7 @@ fun ShareWithContactsButton(shareViaProfile: MutableState, setProfileAd @Composable private fun AutoAcceptToggle(autoAcceptState: MutableState, saveAas: (AutoAcceptState) -> Unit) { - PreferenceToggleWithIcon(stringResource(MR.strings.auto_accept_contact), painterResource(R.drawable.ic_check), checked = autoAcceptState.value.enable) { + PreferenceToggleWithIcon(stringResource(MR.strings.auto_accept_contact), painterResource(MR.images.ic_check), checked = autoAcceptState.value.enable) { autoAcceptState.value = if (!it) AutoAcceptState() else @@ -313,7 +313,7 @@ private fun AutoAcceptToggle(autoAcceptState: MutableState, sav @Composable private fun DeleteAddressButton(onClick: () -> Unit) { SettingsActionItem( - painterResource(R.drawable.ic_delete), + painterResource(MR.images.ic_delete), stringResource(MR.strings.delete_address), onClick, iconColor = MaterialTheme.colors.error, @@ -390,7 +390,7 @@ private fun AutoAcceptSection( private fun AcceptIncognitoToggle(autoAcceptState: MutableState) { PreferenceToggleWithIcon( stringResource(MR.strings.accept_contact_incognito_button), - if (autoAcceptState.value.incognito) painterResource(R.drawable.ic_theater_comedy_filled) else painterResource(R.drawable.ic_theater_comedy), + if (autoAcceptState.value.incognito) painterResource(MR.images.ic_theater_comedy_filled) else painterResource(MR.images.ic_theater_comedy), if (autoAcceptState.value.incognito) Indigo else MaterialTheme.colors.secondary, autoAcceptState.value.incognito, ) { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfileView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfileView.kt index 3b30c42e79..ee03a689ec 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfileView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfileView.kt @@ -13,7 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -188,7 +188,7 @@ fun EditImageButton(click: () -> Unit) { modifier = Modifier.size(30.dp) ) { Icon( - painterResource(R.drawable.ic_photo_camera), + painterResource(MR.images.ic_photo_camera), contentDescription = stringResource(MR.strings.edit_image), tint = MaterialTheme.colors.primary, modifier = Modifier.size(30.dp) @@ -200,7 +200,7 @@ fun EditImageButton(click: () -> Unit) { fun DeleteImageButton(click: () -> Unit) { IconButton(onClick = click) { Icon( - painterResource(R.drawable.ic_close), + painterResource(MR.images.ic_close), contentDescription = stringResource(MR.strings.delete_image), tint = MaterialTheme.colors.primary, ) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt index 0b49c2d889..49024f5977 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource +import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight @@ -159,7 +159,7 @@ private fun UserProfilesLayout( ) { if (profileHidden.value) { SectionView { - SettingsActionItem(painterResource(R.drawable.ic_lock_open), stringResource(MR.strings.enter_password_to_show), click = { + SettingsActionItem(painterResource(MR.images.ic_lock_open), stringResource(MR.strings.enter_password_to_show), click = { profileHidden.value = false } ) @@ -175,7 +175,7 @@ private fun UserProfilesLayout( } if (searchTextOrPassword.value.trim().isEmpty()) { SectionItemView(addUser, minHeight = 68.dp) { - Icon(painterResource(R.drawable.ic_add), stringResource(MR.strings.users_add), tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_add), stringResource(MR.strings.users_add), tint = MaterialTheme.colors.primary) Spacer(Modifier.padding(horizontal = 4.dp)) Text(stringResource(MR.strings.users_add), color = MaterialTheme.colors.primary) } @@ -218,30 +218,30 @@ private fun UserView( Box(Modifier.padding(horizontal = DEFAULT_PADDING)) { DefaultDropdownMenu(showMenu) { if (user.hidden) { - ItemAction(stringResource(MR.strings.user_unhide), painterResource(R.drawable.ic_lock_open), onClick = { + ItemAction(stringResource(MR.strings.user_unhide), painterResource(MR.images.ic_lock_open), onClick = { showMenu.value = false unhideUser(user) }) } else { if (visibleUsersCount > 1) { - ItemAction(stringResource(MR.strings.user_hide), painterResource(R.drawable.ic_lock), onClick = { + ItemAction(stringResource(MR.strings.user_hide), painterResource(MR.images.ic_lock), onClick = { showMenu.value = false showHiddenProfile(user) }) } if (user.showNtfs) { - ItemAction(stringResource(MR.strings.user_mute), painterResource(R.drawable.ic_notifications_off), onClick = { + ItemAction(stringResource(MR.strings.user_mute), painterResource(MR.images.ic_notifications_off), onClick = { showMenu.value = false muteUser(user) }) } else { - ItemAction(stringResource(MR.strings.user_unmute), painterResource(R.drawable.ic_notifications), onClick = { + ItemAction(stringResource(MR.strings.user_unmute), painterResource(MR.images.ic_notifications), onClick = { showMenu.value = false unmuteUser(user) }) } } - ItemAction(stringResource(MR.strings.delete_verb), painterResource(R.drawable.ic_delete), color = Color.Red, onClick = { + ItemAction(stringResource(MR.strings.delete_verb), painterResource(MR.images.ic_delete), color = Color.Red, onClick = { removeUser(user) showMenu.value = false }) diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_account_circle_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_account_circle_filled.xml deleted file mode 100644 index 3af5db1b74..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_account_circle_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_add.xml b/apps/multiplatform/android/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 4f306c05ae..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_add_link.xml b/apps/multiplatform/android/src/main/res/drawable/ic_add_link.xml deleted file mode 100644 index 0da3e849c2..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_add_link.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_add_photo.xml b/apps/multiplatform/android/src/main/res/drawable/ic_add_photo.xml deleted file mode 100644 index acbab9da1c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_add_photo.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction.xml b/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction.xml deleted file mode 100644 index 093d8fcc44..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction_filled.xml deleted file mode 100644 index 1ffc21bc28..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_add_reaction_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_all_inclusive.xml b/apps/multiplatform/android/src/main/res/drawable/ic_all_inclusive.xml deleted file mode 100644 index 08070a066c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_all_inclusive.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_back_ios_new.xml b/apps/multiplatform/android/src/main/res/drawable/ic_arrow_back_ios_new.xml deleted file mode 100644 index 8d3135bf15..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_back_ios_new.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_downward.xml b/apps/multiplatform/android/src/main/res/drawable/ic_arrow_downward.xml deleted file mode 100644 index d2cef9fe2d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_downward.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_forward_ios.xml b/apps/multiplatform/android/src/main/res/drawable/ic_arrow_forward_ios.xml deleted file mode 100644 index 1eb5f7a9fb..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_forward_ios.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_upward.xml b/apps/multiplatform/android/src/main/res/drawable/ic_arrow_upward.xml deleted file mode 100644 index 3a52b50248..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_arrow_upward.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_article.xml b/apps/multiplatform/android/src/main/res/drawable/ic_article.xml deleted file mode 100644 index 607c3d78ec..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_article.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_attach_file_filled_500.xml b/apps/multiplatform/android/src/main/res/drawable/ic_attach_file_filled_500.xml deleted file mode 100644 index f2f923b6d6..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_attach_file_filled_500.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_backspace.xml b/apps/multiplatform/android/src/main/res/drawable/ic_backspace.xml deleted file mode 100644 index b9837296dd..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_backspace.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_backup.xml b/apps/multiplatform/android/src/main/res/drawable/ic_backup.xml deleted file mode 100644 index 248404d464..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_backup.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_battery_2_bar.xml b/apps/multiplatform/android/src/main/res/drawable/ic_battery_2_bar.xml deleted file mode 100644 index cbbe134adf..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_battery_2_bar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_battery_3_bar.xml b/apps/multiplatform/android/src/main/res/drawable/ic_battery_3_bar.xml deleted file mode 100644 index 1e60f37eb1..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_battery_3_bar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_bolt.xml b/apps/multiplatform/android/src/main/res/drawable/ic_bolt.xml deleted file mode 100644 index 4ced77dc1d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_bolt.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_bolt_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_bolt_filled.xml deleted file mode 100644 index 64fa349468..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_bolt_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_cable.xml b/apps/multiplatform/android/src/main/res/drawable/ic_cable.xml deleted file mode 100644 index b801b36d83..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_cable.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_call.xml b/apps/multiplatform/android/src/main/res/drawable/ic_call.xml deleted file mode 100644 index c38c3fe70a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_call.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_call_500.xml b/apps/multiplatform/android/src/main/res/drawable/ic_call_500.xml deleted file mode 100644 index c53c2e6594..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_call_500.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_call_end.xml b/apps/multiplatform/android/src/main/res/drawable/ic_call_end.xml deleted file mode 100644 index f71577fa09..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_call_end.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_call_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_call_filled.xml deleted file mode 100644 index 873cc021e5..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_call_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_camera_enhance.xml b/apps/multiplatform/android/src/main/res/drawable/ic_camera_enhance.xml deleted file mode 100644 index 126527f211..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_camera_enhance.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_cancel_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_cancel_filled.xml deleted file mode 100644 index cbb3667bbb..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_cancel_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_chat.xml b/apps/multiplatform/android/src/main/res/drawable/ic_chat.xml deleted file mode 100644 index 726b53ab7b..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_chat.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_check.xml b/apps/multiplatform/android/src/main/res/drawable/ic_check.xml deleted file mode 100644 index cb47d7db19..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_check.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_check_circle_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_check_circle_filled.xml deleted file mode 100644 index a1f32800fe..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_check_circle_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_check_fill.xml b/apps/multiplatform/android/src/main/res/drawable/ic_check_fill.xml deleted file mode 100644 index da2028b14a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_check_fill.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_chevron_right.xml b/apps/multiplatform/android/src/main/res/drawable/ic_chevron_right.xml deleted file mode 100644 index 622e1984ac..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_chevron_right.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_circle.xml b/apps/multiplatform/android/src/main/res/drawable/ic_circle.xml deleted file mode 100644 index 129ad17b01..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_circle.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_circle_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_circle_filled.xml deleted file mode 100644 index fa62888802..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_circle_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_code.xml b/apps/multiplatform/android/src/main/res/drawable/ic_code.xml deleted file mode 100644 index a20431beb1..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_code.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_content_copy.xml b/apps/multiplatform/android/src/main/res/drawable/ic_content_copy.xml deleted file mode 100644 index b8952b0299..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_content_copy.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_content_paste.xml b/apps/multiplatform/android/src/main/res/drawable/ic_content_paste.xml deleted file mode 100644 index 4e586dab46..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_content_paste.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_database.xml b/apps/multiplatform/android/src/main/res/drawable/ic_database.xml deleted file mode 100644 index f56547850a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_database.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_delete.xml b/apps/multiplatform/android/src/main/res/drawable/ic_delete.xml deleted file mode 100644 index 5be76620e4..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_delete.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever.xml b/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever.xml deleted file mode 100644 index a82d8de833..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever_filled.xml deleted file mode 100644 index 476b04c7bd..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_delete_forever_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_dns.xml b/apps/multiplatform/android/src/main/res/drawable/ic_dns.xml deleted file mode 100644 index 60a762908c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_dns.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_do_not_disturb_on.xml b/apps/multiplatform/android/src/main/res/drawable/ic_do_not_disturb_on.xml deleted file mode 100644 index 6ffd006109..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_do_not_disturb_on.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_done_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_done_filled.xml deleted file mode 100644 index da2028b14a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_done_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_download.xml b/apps/multiplatform/android/src/main/res/drawable/ic_download.xml deleted file mode 100644 index 92d2447b67..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_download.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_draft.xml b/apps/multiplatform/android/src/main/res/drawable/ic_draft.xml deleted file mode 100644 index 7ec25c71a9..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_draft.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_draft_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_draft_filled.xml deleted file mode 100644 index 5a99658815..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_draft_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_drive_folder_upload.xml b/apps/multiplatform/android/src/main/res/drawable/ic_drive_folder_upload.xml deleted file mode 100644 index e2f302cbc9..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_drive_folder_upload.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_edit.xml b/apps/multiplatform/android/src/main/res/drawable/ic_edit.xml deleted file mode 100644 index 4584f093bf..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_edit.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_edit_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_edit_filled.xml deleted file mode 100644 index 7041946226..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_edit_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_edit_note.xml b/apps/multiplatform/android/src/main/res/drawable/ic_edit_note.xml deleted file mode 100644 index 4c45579a89..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_edit_note.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_electrical_services.xml b/apps/multiplatform/android/src/main/res/drawable/ic_electrical_services.xml deleted file mode 100644 index 0c9da67ae6..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_electrical_services.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_error.xml b/apps/multiplatform/android/src/main/res/drawable/ic_error.xml deleted file mode 100644 index 78bb603a3b..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_error.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_error_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_error_filled.xml deleted file mode 100644 index 377c6e25e4..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_error_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_expand_less.xml b/apps/multiplatform/android/src/main/res/drawable/ic_expand_less.xml deleted file mode 100644 index cd7865710f..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_expand_less.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_expand_more.xml b/apps/multiplatform/android/src/main/res/drawable/ic_expand_more.xml deleted file mode 100644 index 2033d51bfe..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_expand_more.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_filter_list.xml b/apps/multiplatform/android/src/main/res/drawable/ic_filter_list.xml deleted file mode 100644 index c34f1d13b8..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_filter_list.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_flag.xml b/apps/multiplatform/android/src/main/res/drawable/ic_flag.xml deleted file mode 100644 index 794d8944a1..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_flag.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_flip_camera_android_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_flip_camera_android_filled.xml deleted file mode 100644 index 7325087c95..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_flip_camera_android_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_github.xml b/apps/multiplatform/android/src/main/res/drawable/ic_github.xml deleted file mode 100644 index 1c7032037a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_github.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_group.xml b/apps/multiplatform/android/src/main/res/drawable/ic_group.xml deleted file mode 100644 index 3023eaac7d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_group.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_help.xml b/apps/multiplatform/android/src/main/res/drawable/ic_help.xml deleted file mode 100644 index 7811daed24..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_help.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_image.xml b/apps/multiplatform/android/src/main/res/drawable/ic_image.xml deleted file mode 100644 index 0319f37153..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_image.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_info.xml b/apps/multiplatform/android/src/main/res/drawable/ic_info.xml deleted file mode 100644 index 49d73a35ef..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_info.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_inventory_2.xml b/apps/multiplatform/android/src/main/res/drawable/ic_inventory_2.xml deleted file mode 100644 index c76a375f2e..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_inventory_2.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_ios_share.xml b/apps/multiplatform/android/src/main/res/drawable/ic_ios_share.xml deleted file mode 100644 index e7658452c0..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_ios_share.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard.xml b/apps/multiplatform/android/src/main/res/drawable/ic_keyboard.xml deleted file mode 100644 index 1b181cd9b3..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_arrow_down.xml b/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_arrow_down.xml deleted file mode 100644 index 64d16805e8..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_arrow_down.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice.xml b/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice.xml deleted file mode 100644 index 6abc105438..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice_filled.xml deleted file mode 100644 index 7b68c1c490..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_keyboard_voice_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_launcher_background.xml b/apps/multiplatform/android/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 140f829468..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_light_mode.xml b/apps/multiplatform/android/src/main/res/drawable/ic_light_mode.xml deleted file mode 100644 index 3ec23acc6e..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_light_mode.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_link.xml b/apps/multiplatform/android/src/main/res/drawable/ic_link.xml deleted file mode 100644 index 0654256956..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_link.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_lock_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_lock_filled.xml deleted file mode 100644 index 426350d6be..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_lock_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_lock_open.xml b/apps/multiplatform/android/src/main/res/drawable/ic_lock_open.xml deleted file mode 100644 index 2188d06927..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_lock_open.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_login.xml b/apps/multiplatform/android/src/main/res/drawable/ic_login.xml deleted file mode 100644 index 6cd2179c08..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_login.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_logout.xml b/apps/multiplatform/android/src/main/res/drawable/ic_logout.xml deleted file mode 100644 index 39eb443215..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_logout.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_mail.xml b/apps/multiplatform/android/src/main/res/drawable/ic_mail.xml deleted file mode 100644 index 3a063bd429..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_mail.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_manage_accounts.xml b/apps/multiplatform/android/src/main/res/drawable/ic_manage_accounts.xml deleted file mode 100644 index 0d1cc9bf77..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_manage_accounts.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_maps_ugc.xml b/apps/multiplatform/android/src/main/res/drawable/ic_maps_ugc.xml deleted file mode 100644 index 6450dd487b..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_maps_ugc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_mark_chat_unread.xml b/apps/multiplatform/android/src/main/res/drawable/ic_mark_chat_unread.xml deleted file mode 100644 index 7d41d7ef1d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_mark_chat_unread.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_menu.xml b/apps/multiplatform/android/src/main/res/drawable/ic_menu.xml deleted file mode 100644 index 81e2bfba4a..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_menu.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_mic.xml b/apps/multiplatform/android/src/main/res/drawable/ic_mic.xml deleted file mode 100644 index 6abc105438..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_mic.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_mic_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_mic_filled.xml deleted file mode 100644 index 7b68c1c490..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_mic_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_mic_off.xml b/apps/multiplatform/android/src/main/res/drawable/ic_mic_off.xml deleted file mode 100644 index 1c4870f5fe..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_mic_off.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_more_horiz.xml b/apps/multiplatform/android/src/main/res/drawable/ic_more_horiz.xml deleted file mode 100644 index db2892846d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_more_horiz.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_note_add.xml b/apps/multiplatform/android/src/main/res/drawable/ic_note_add.xml deleted file mode 100644 index 38cc20d3df..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_note_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_notifications.xml b/apps/multiplatform/android/src/main/res/drawable/ic_notifications.xml deleted file mode 100644 index 3cba3d1686..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_notifications.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off.xml b/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off.xml deleted file mode 100644 index da9106bff0..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off_filled.xml deleted file mode 100644 index 6f0b0b768b..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_notifications_off_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_open_in_new.xml b/apps/multiplatform/android/src/main/res/drawable/ic_open_in_new.xml deleted file mode 100644 index a9a964d5cc..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_open_in_new.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_outline_terminal.xml b/apps/multiplatform/android/src/main/res/drawable/ic_outline_terminal.xml deleted file mode 100644 index e03f112d70..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_outline_terminal.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_pause_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_pause_filled.xml deleted file mode 100644 index 3e985d21f4..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_pause_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_pending.xml b/apps/multiplatform/android/src/main/res/drawable/ic_pending.xml deleted file mode 100644 index 9cb97c8b19..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_pending.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_pending_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_pending_filled.xml deleted file mode 100644 index bf17063321..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_pending_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_person.xml b/apps/multiplatform/android/src/main/res/drawable/ic_person.xml deleted file mode 100644 index 12ca71b4f9..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_person.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_person_add.xml b/apps/multiplatform/android/src/main/res/drawable/ic_person_add.xml deleted file mode 100644 index f16ef30b2d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_person_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_person_add_500.xml b/apps/multiplatform/android/src/main/res/drawable/ic_person_add_500.xml deleted file mode 100644 index 9406a99761..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_person_add_500.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_phone_in_talk_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_phone_in_talk_filled.xml deleted file mode 100644 index 624d6e04a3..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_phone_in_talk_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_photo_camera.xml b/apps/multiplatform/android/src/main/res/drawable/ic_photo_camera.xml deleted file mode 100644 index e6c55dbba7..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_photo_camera.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_play_arrow_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_play_arrow_filled.xml deleted file mode 100644 index bcd917b7da..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_play_arrow_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_power_settings_new.xml b/apps/multiplatform/android/src/main/res/drawable/ic_power_settings_new.xml deleted file mode 100644 index a73a866f2e..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_power_settings_new.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_priority_high.xml b/apps/multiplatform/android/src/main/res/drawable/ic_priority_high.xml deleted file mode 100644 index b7ddf72318..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_priority_high.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_qr_code.xml b/apps/multiplatform/android/src/main/res/drawable/ic_qr_code.xml deleted file mode 100644 index 1eb7cfb059..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_qr_code.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_repeat_one.xml b/apps/multiplatform/android/src/main/res/drawable/ic_repeat_one.xml deleted file mode 100644 index 0987aadbf6..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_repeat_one.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_replay.xml b/apps/multiplatform/android/src/main/res/drawable/ic_replay.xml deleted file mode 100644 index 7a9c7d7589..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_replay.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_reply.xml b/apps/multiplatform/android/src/main/res/drawable/ic_reply.xml deleted file mode 100644 index 4a2dec582d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_reply.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_report_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_report_filled.xml deleted file mode 100644 index f1be1d2e41..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_report_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_restart_alt.xml b/apps/multiplatform/android/src/main/res/drawable/ic_restart_alt.xml deleted file mode 100644 index 92043a534d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_restart_alt.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_ring_volume.xml b/apps/multiplatform/android/src/main/res/drawable/ic_ring_volume.xml deleted file mode 100644 index a60020f3ea..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_ring_volume.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_safety_divider.xml b/apps/multiplatform/android/src/main/res/drawable/ic_safety_divider.xml deleted file mode 100644 index 8b49b2ac03..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_safety_divider.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_search.xml b/apps/multiplatform/android/src/main/res/drawable/ic_search.xml deleted file mode 100644 index a1c7c1f894..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_search.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_search_500.xml b/apps/multiplatform/android/src/main/res/drawable/ic_search_500.xml deleted file mode 100644 index 2a1d817b85..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_search_500.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_security.xml b/apps/multiplatform/android/src/main/res/drawable/ic_security.xml deleted file mode 100644 index cfe471b2ea..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_security.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_settings.xml b/apps/multiplatform/android/src/main/res/drawable/ic_settings.xml deleted file mode 100644 index a59cecf3d5..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_settings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_settings_backup_restore.xml b/apps/multiplatform/android/src/main/res/drawable/ic_settings_backup_restore.xml deleted file mode 100644 index 42e11a064d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_settings_backup_restore.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_settings_ethernet.xml b/apps/multiplatform/android/src/main/res/drawable/ic_settings_ethernet.xml deleted file mode 100644 index 0d049ce4d8..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_settings_ethernet.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_settings_phone.xml b/apps/multiplatform/android/src/main/res/drawable/ic_settings_phone.xml deleted file mode 100644 index d26a6b4e4c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_settings_phone.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_share.xml b/apps/multiplatform/android/src/main/res/drawable/ic_share.xml deleted file mode 100644 index dd674cd84b..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_share.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_share_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_share_filled.xml deleted file mode 100644 index 475cef6c18..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_share_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_shield.xml b/apps/multiplatform/android/src/main/res/drawable/ic_shield.xml deleted file mode 100644 index 27e75aab71..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_shield.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_smart_display.xml b/apps/multiplatform/android/src/main/res/drawable/ic_smart_display.xml deleted file mode 100644 index b7c815b66d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_smart_display.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_star.xml b/apps/multiplatform/android/src/main/res/drawable/ic_star.xml deleted file mode 100644 index 797b2514b7..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_star.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_star_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_star_filled.xml deleted file mode 100644 index 278b867186..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_star_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_star_off.xml b/apps/multiplatform/android/src/main/res/drawable/ic_star_off.xml deleted file mode 100644 index 8806fd1a5e..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_star_off.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_stop_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_stop_filled.xml deleted file mode 100644 index 412bcd6429..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_stop_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_supervised_user_circle_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_supervised_user_circle_filled.xml deleted file mode 100644 index 68545edc1d..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_supervised_user_circle_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle.xml b/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle.xml deleted file mode 100644 index 9e8b59d8a2..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle_filled.xml deleted file mode 100644 index 554f616d6e..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_swap_horizontal_circle_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_tag.xml b/apps/multiplatform/android/src/main/res/drawable/ic_tag.xml deleted file mode 100644 index a3c686ec3c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_tag.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_task.xml b/apps/multiplatform/android/src/main/res/drawable/ic_task.xml deleted file mode 100644 index 8fe57f2ee7..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_task.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy.xml b/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy.xml deleted file mode 100644 index d139cc2cef..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy_filled.xml deleted file mode 100644 index bff47ca72c..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_theater_comedy_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_timer.xml b/apps/multiplatform/android/src/main/res/drawable/ic_timer.xml deleted file mode 100644 index b29ec1a006..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_timer.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_timer_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_timer_filled.xml deleted file mode 100644 index d608045bbf..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_timer_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_toggle_on.xml b/apps/multiplatform/android/src/main/res/drawable/ic_toggle_on.xml deleted file mode 100644 index d5cd169318..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_toggle_on.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_translate.xml b/apps/multiplatform/android/src/main/res/drawable/ic_translate.xml deleted file mode 100644 index 7bd88bd420..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_translate.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_travel_explore.xml b/apps/multiplatform/android/src/main/res/drawable/ic_travel_explore.xml deleted file mode 100644 index 71c264d4be..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_travel_explore.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_upload_file.xml b/apps/multiplatform/android/src/main/res/drawable/ic_upload_file.xml deleted file mode 100644 index bc80a6e1db..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_upload_file.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_verified_user.xml b/apps/multiplatform/android/src/main/res/drawable/ic_verified_user.xml deleted file mode 100644 index 02951ba057..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_verified_user.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_videocam.xml b/apps/multiplatform/android/src/main/res/drawable/ic_videocam.xml deleted file mode 100644 index 964c287276..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_videocam.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_videocam_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_videocam_filled.xml deleted file mode 100644 index e67552c004..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_videocam_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_videocam_off.xml b/apps/multiplatform/android/src/main/res/drawable/ic_videocam_off.xml deleted file mode 100644 index d508eb273f..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_videocam_off.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_visibility.xml b/apps/multiplatform/android/src/main/res/drawable/ic_visibility.xml deleted file mode 100644 index e9f1762303..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_visibility.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_visibility_filled.xml deleted file mode 100644 index 35958c3a27..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off.xml b/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off.xml deleted file mode 100644 index 202fd6db1f..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off_filled.xml deleted file mode 100644 index 9656100328..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_visibility_off_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_volume_down.xml b/apps/multiplatform/android/src/main/res/drawable/ic_volume_down.xml deleted file mode 100644 index 6e19f180d4..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_volume_down.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_volume_up.xml b/apps/multiplatform/android/src/main/res/drawable/ic_volume_up.xml deleted file mode 100644 index 2e301273bb..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_volume_up.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_filled.xml deleted file mode 100644 index f13099ed6f..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_off_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_off_filled.xml deleted file mode 100644 index c07f49f274..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_vpn_key_off_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_warning_filled.xml b/apps/multiplatform/android/src/main/res/drawable/ic_warning_filled.xml deleted file mode 100644 index e7f71762ef..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_warning_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/android/src/main/res/drawable/ic_wifi_tethering.xml b/apps/multiplatform/android/src/main/res/drawable/ic_wifi_tethering.xml deleted file mode 100644 index 065c461542..0000000000 --- a/apps/multiplatform/android/src/main/res/drawable/ic_wifi_tethering.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/multiplatform/common/src/androidMain/res/drawable/icon_dark_blue_round_common.png b/apps/multiplatform/common/src/androidMain/res/drawable/icon_dark_blue_round_common.png new file mode 100644 index 0000000000000000000000000000000000000000..e413ad857da917bb0884e67a77f3db58e7227666 GIT binary patch literal 9870 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 AtpET3 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/androidMain/res/drawable/icon_foreground_android_common.png b/apps/multiplatform/common/src/androidMain/res/drawable/icon_foreground_android_common.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab60a329304d88d8aff82cc1bebd6b07fcaf320 GIT binary patch literal 25226 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 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/androidMain/res/drawable/send_msg_view_background.xml b/apps/multiplatform/common/src/androidMain/res/drawable/send_msg_view_background.xml new file mode 100644 index 0000000000..be98ce5da5 --- /dev/null +++ b/apps/multiplatform/common/src/androidMain/res/drawable/send_msg_view_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/apps/multiplatform/common/src/androidMain/res/raw/ring_once.mp3 b/apps/multiplatform/common/src/androidMain/res/raw/ring_once.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..958327733694183c605a93a07096194633869ed8 GIT binary patch literal 72269 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 literal 0 HcmV?d00001 diff --git a/apps/multiplatform/android/src/main/res/font/inter_bold.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Bold.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_bold.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Bold.ttf diff --git a/apps/multiplatform/android/src/main/res/font/inter_italic.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Italic.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_italic.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Italic.ttf diff --git a/apps/multiplatform/android/src/main/res/font/inter_light.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Light.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_light.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Light.ttf diff --git a/apps/multiplatform/android/src/main/res/font/inter_medium.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Medium.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_medium.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Medium.ttf diff --git a/apps/multiplatform/android/src/main/res/font/inter_regular.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Regular.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_regular.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Regular.ttf diff --git a/apps/multiplatform/android/src/main/res/font/inter_semi_bold.ttf b/apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Semibold.ttf similarity index 100% rename from apps/multiplatform/android/src/main/res/font/inter_semi_bold.ttf rename to apps/multiplatform/common/src/commonMain/resources/MR/fonts/Inter-Semibold.ttf diff --git a/apps/multiplatform/android/src/main/res/drawable-hdpi/decentralized.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@1.5x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-hdpi/decentralized.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@1.5x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-mdpi/decentralized.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@1x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-mdpi/decentralized.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@1x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xhdpi/decentralized.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@2x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xhdpi/decentralized.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@2x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxhdpi/decentralized.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@3x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxhdpi/decentralized.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@3x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxxhdpi/decentralized.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@4x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxxhdpi/decentralized.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized@4x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-hdpi/decentralized_light.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@1.5x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-hdpi/decentralized_light.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@1.5x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-mdpi/decentralized_light.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@1x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-mdpi/decentralized_light.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@1x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xhdpi/decentralized_light.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@2x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xhdpi/decentralized_light.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@2x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxhdpi/decentralized_light.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@3x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxhdpi/decentralized_light.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@3x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxxhdpi/decentralized_light.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@4x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxxhdpi/decentralized_light.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/decentralized_light@4x.png diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_account_circle_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_account_circle_filled.svg new file mode 100644 index 0000000000..f63966fbc8 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_account_circle_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add.svg new file mode 100644 index 0000000000..7da1daade8 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_link.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_link.svg new file mode 100644 index 0000000000..6e3ec1e453 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_photo.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_photo.svg new file mode 100644 index 0000000000..3197ae8bb6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_photo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction.svg new file mode 100644 index 0000000000..62ee67166c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction_filled.svg new file mode 100644 index 0000000000..0475962f63 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_add_reaction_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_all_inclusive.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_all_inclusive.svg new file mode 100644 index 0000000000..4675bb6642 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_all_inclusive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_back_ios_new.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_back_ios_new.svg new file mode 100644 index 0000000000..6940e4d004 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_back_ios_new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_downward.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_downward.svg new file mode 100644 index 0000000000..c09c1c4d66 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_downward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_forward_ios.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_forward_ios.svg new file mode 100644 index 0000000000..dd07f2bad9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_forward_ios.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_upward.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_upward.svg new file mode 100644 index 0000000000..88b20124f3 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrow_upward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_article.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_article.svg new file mode 100644 index 0000000000..05d4d6fe6e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_article.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled.svg new file mode 100644 index 0000000000..5ff6754f22 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled_500.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled_500.svg new file mode 100644 index 0000000000..04ef1d379f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_attach_file_filled_500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backspace.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backspace.svg new file mode 100644 index 0000000000..5bb12b42ca --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backspace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backup.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backup.svg new file mode 100644 index 0000000000..5d4b0c0dc6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_backup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_2_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_2_bar.svg new file mode 100644 index 0000000000..fcdb3dfd50 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_2_bar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_3_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_3_bar.svg new file mode 100644 index 0000000000..819fe590c9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_battery_3_bar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt.svg new file mode 100644 index 0000000000..4c686c282a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt_filled.svg new file mode 100644 index 0000000000..012a8e2a45 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_bolt_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cable.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cable.svg new file mode 100644 index 0000000000..1ca40515b7 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cable.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call.svg new file mode 100644 index 0000000000..19c840a5cf --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_500.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_500.svg new file mode 100644 index 0000000000..f2e1e9af6b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end.svg new file mode 100644 index 0000000000..0f21f36e83 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end_filled.svg new file mode 100644 index 0000000000..ceb32f98f5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_end_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_filled.svg new file mode 100644 index 0000000000..c0277fd5b6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_call_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_camera_enhance.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_camera_enhance.svg new file mode 100644 index 0000000000..b07fbd7a87 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_camera_enhance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cancel_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cancel_filled.svg new file mode 100644 index 0000000000..44e901ff3c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_cancel_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chat.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chat.svg new file mode 100644 index 0000000000..c263166229 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check.svg new file mode 100644 index 0000000000..e3d6eab069 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_circle_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_circle_filled.svg new file mode 100644 index 0000000000..42f1a37725 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_circle_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_filled.svg new file mode 100644 index 0000000000..e3d6eab069 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_check_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right.svg new file mode 100644 index 0000000000..ac6025580b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle.svg new file mode 100644 index 0000000000..d0da456188 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle_filled.svg new file mode 100644 index 0000000000..e8eebbdc7c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_circle_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_close.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_close.svg new file mode 100644 index 0000000000..f3803e3cac --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_code.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_code.svg new file mode 100644 index 0000000000..8554e557b0 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_copy.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_copy.svg new file mode 100644 index 0000000000..2f4b964368 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_paste.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_paste.svg new file mode 100644 index 0000000000..84a0be536b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_content_paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_database.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_database.svg new file mode 100644 index 0000000000..8b47047b60 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_database.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete.svg new file mode 100644 index 0000000000..1709888116 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever.svg new file mode 100644 index 0000000000..519fbc87fb --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever_filled.svg new file mode 100644 index 0000000000..c8c1d4cea5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_delete_forever_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_dns.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_dns.svg new file mode 100644 index 0000000000..c1056cefc6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_dns.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_do_not_disturb_on.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_do_not_disturb_on.svg new file mode 100644 index 0000000000..9a0d038ba5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_do_not_disturb_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_done_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_done_filled.svg new file mode 100644 index 0000000000..e3d6eab069 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_done_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_download.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_download.svg new file mode 100644 index 0000000000..8d62bebda6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft.svg new file mode 100644 index 0000000000..bbe311364f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft_filled.svg new file mode 100644 index 0000000000..06140a055d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_draft_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_drive_folder_upload.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_drive_folder_upload.svg new file mode 100644 index 0000000000..ec3d03510e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_drive_folder_upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit.svg new file mode 100644 index 0000000000..400707272e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_filled.svg new file mode 100644 index 0000000000..e87e2eccaf --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_note.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_note.svg new file mode 100644 index 0000000000..0c66d1bc4d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_edit_note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_electrical_services.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_electrical_services.svg new file mode 100644 index 0000000000..e6ab5bb608 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_electrical_services.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error.svg new file mode 100644 index 0000000000..60296ca034 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error_filled.svg new file mode 100644 index 0000000000..6aaa01f0d3 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_error_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_less.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_less.svg new file mode 100644 index 0000000000..23a6402630 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_less.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_more.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_more.svg new file mode 100644 index 0000000000..77becd0856 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_expand_more.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_filter_list.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_filter_list.svg new file mode 100644 index 0000000000..a54ee0dc55 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_filter_list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flag.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flag.svg new file mode 100644 index 0000000000..35dd4ac780 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flip_camera_android_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flip_camera_android_filled.svg new file mode 100644 index 0000000000..da9d686ce9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_flip_camera_android_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_folder_open.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_folder_open.svg new file mode 100644 index 0000000000..6503f06c47 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_folder_open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_github.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_github.svg new file mode 100644 index 0000000000..70baacb727 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_group.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_group.svg new file mode 100644 index 0000000000..74d6cdcc02 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help.svg new file mode 100644 index 0000000000..3bf2406ab8 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_help.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_image.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_image.svg new file mode 100644 index 0000000000..408668d204 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_info.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_info.svg new file mode 100644 index 0000000000..aa3e5a2f4e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_inventory_2.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_inventory_2.svg new file mode 100644 index 0000000000..c7e8aa21c1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_inventory_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ios_share.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ios_share.svg new file mode 100644 index 0000000000..099b5149bf --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ios_share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard.svg new file mode 100644 index 0000000000..35689927b1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_arrow_down.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_arrow_down.svg new file mode 100644 index 0000000000..c92d244c17 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_arrow_down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice.svg new file mode 100644 index 0000000000..a938a4250f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice_filled.svg new file mode 100644 index 0000000000..bd28745400 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_keyboard_voice_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_light_mode.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_light_mode.svg new file mode 100644 index 0000000000..858ee788cf --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_link.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_link.svg new file mode 100644 index 0000000000..b8063c1c8c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock.svg new file mode 100644 index 0000000000..2bc91dde71 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_filled.svg new file mode 100644 index 0000000000..396e11fac6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_open.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_open.svg new file mode 100644 index 0000000000..bf6b7b47b4 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_lock_open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_login.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_login.svg new file mode 100644 index 0000000000..be56f0f451 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_logout.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_logout.svg new file mode 100644 index 0000000000..5808094655 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_logout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mail.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mail.svg new file mode 100644 index 0000000000..0a4b8adbd8 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_manage_accounts.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_manage_accounts.svg new file mode 100644 index 0000000000..e1cc6816b1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_manage_accounts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_maps_ugc.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_maps_ugc.svg new file mode 100644 index 0000000000..469d44a2de --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_maps_ugc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mark_chat_unread.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mark_chat_unread.svg new file mode 100644 index 0000000000..5e1e746ee9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mark_chat_unread.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_menu.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_menu.svg new file mode 100644 index 0000000000..a192e32f34 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic.svg new file mode 100644 index 0000000000..a938a4250f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_filled.svg new file mode 100644 index 0000000000..bd28745400 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_off.svg new file mode 100644 index 0000000000..1ea755eb4e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_mic_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_horiz.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_horiz.svg new file mode 100644 index 0000000000..cc4f97431d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_horiz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_vert.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_vert.svg new file mode 100644 index 0000000000..9a9c7d193b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_more_vert.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_note_add.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_note_add.svg new file mode 100644 index 0000000000..8459292f6e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_note_add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications.svg new file mode 100644 index 0000000000..bcba2ae944 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off.svg new file mode 100644 index 0000000000..556013c364 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off_filled.svg new file mode 100644 index 0000000000..647ad7dd3d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_notifications_off_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_open_in_new.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_open_in_new.svg new file mode 100644 index 0000000000..9669ee635e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_open_in_new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_outline_terminal.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_outline_terminal.svg new file mode 100644 index 0000000000..07f8078e0c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_outline_terminal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pause_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pause_filled.svg new file mode 100644 index 0000000000..eaa4573780 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pause_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending.svg new file mode 100644 index 0000000000..90b9dc7204 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending_filled.svg new file mode 100644 index 0000000000..00fe0d41a7 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_pending_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person.svg new file mode 100644 index 0000000000..0830a9963b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add.svg new file mode 100644 index 0000000000..4b2a249f23 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add_500.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add_500.svg new file mode 100644 index 0000000000..179dce95fb --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_add_500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_phone_in_talk_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_phone_in_talk_filled.svg new file mode 100644 index 0000000000..b43c7d9c15 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_phone_in_talk_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_photo_camera.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_photo_camera.svg new file mode 100644 index 0000000000..aa99ac888a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_photo_camera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_play_arrow_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_play_arrow_filled.svg new file mode 100644 index 0000000000..6b3ed2a581 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_play_arrow_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_power_settings_new.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_power_settings_new.svg new file mode 100644 index 0000000000..0af51ad2ab --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_power_settings_new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_priority_high.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_priority_high.svg new file mode 100644 index 0000000000..42b93fba83 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_priority_high.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_qr_code.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_qr_code.svg new file mode 100644 index 0000000000..d7f8763c87 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_qr_code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_repeat_one.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_repeat_one.svg new file mode 100644 index 0000000000..d37aa28022 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_repeat_one.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_replay.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_replay.svg new file mode 100644 index 0000000000..9f8c033f89 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_replay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_reply.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_reply.svg new file mode 100644 index 0000000000..7298dc984e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_reply.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_report_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_report_filled.svg new file mode 100644 index 0000000000..914c74a40a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_report_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_restart_alt.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_restart_alt.svg new file mode 100644 index 0000000000..a28c95673e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_restart_alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ring_volume.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ring_volume.svg new file mode 100644 index 0000000000..92bc814040 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_ring_volume.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_safety_divider.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_safety_divider.svg new file mode 100644 index 0000000000..5517bcd740 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_safety_divider.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search.svg new file mode 100644 index 0000000000..8a74c6d43f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search_500.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search_500.svg new file mode 100644 index 0000000000..18e56def19 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_search_500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_security.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_security.svg new file mode 100644 index 0000000000..13b5c1914e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_security.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings.svg new file mode 100644 index 0000000000..04b250537d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_backup_restore.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_backup_restore.svg new file mode 100644 index 0000000000..a3cf4db7e1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_backup_restore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_ethernet.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_ethernet.svg new file mode 100644 index 0000000000..828c7b8a8b --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_ethernet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_phone.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_phone.svg new file mode 100644 index 0000000000..7280127ceb --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_settings_phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share.svg new file mode 100644 index 0000000000..f24d145a50 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share_filled.svg new file mode 100644 index 0000000000..16b4c0ecf2 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_share_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_shield.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_shield.svg new file mode 100644 index 0000000000..ca1ed6828c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_smart_display.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_smart_display.svg new file mode 100644 index 0000000000..195c3b2bea --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_smart_display.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star.svg new file mode 100644 index 0000000000..2a2733830a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_filled.svg new file mode 100644 index 0000000000..bf9bd2b4b5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_filled.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_off.svg new file mode 100644 index 0000000000..d17a1e37d9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_star_off.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_start.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_start.svg new file mode 100644 index 0000000000..42983718ac --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_start.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_stop_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_stop_filled.svg new file mode 100644 index 0000000000..0e8823dab5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_stop_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_supervised_user_circle_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_supervised_user_circle_filled.svg new file mode 100644 index 0000000000..ecfb7002a1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_supervised_user_circle_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle.svg new file mode 100644 index 0000000000..0b842e8716 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle_filled.svg new file mode 100644 index 0000000000..3509f870de --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_swap_horizontal_circle_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_tag.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_tag.svg new file mode 100644 index 0000000000..4b7e39b8ec --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_task.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_task.svg new file mode 100644 index 0000000000..eab8e8f09d --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_task.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy.svg new file mode 100644 index 0000000000..24267d0fa8 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy_filled.svg new file mode 100644 index 0000000000..401e9affac --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_theater_comedy_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer.svg new file mode 100644 index 0000000000..e530ef1e83 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer_filled.svg new file mode 100644 index 0000000000..4e0a99775a --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_timer_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_toggle_on.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_toggle_on.svg new file mode 100644 index 0000000000..de240dce5f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_toggle_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_translate.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_translate.svg new file mode 100644 index 0000000000..8ad343c088 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_translate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_travel_explore.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_travel_explore.svg new file mode 100644 index 0000000000..023ce42a26 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_travel_explore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_upload_file.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_upload_file.svg new file mode 100644 index 0000000000..1840509fb1 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_upload_file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_verified_user.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_verified_user.svg new file mode 100644 index 0000000000..cd6e89db86 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_verified_user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam.svg new file mode 100644 index 0000000000..9a9edf61ce --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_filled.svg new file mode 100644 index 0000000000..0606c6a06f --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_off.svg new file mode 100644 index 0000000000..77c85ed987 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_videocam_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility.svg new file mode 100644 index 0000000000..50095bc6e5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_filled.svg new file mode 100644 index 0000000000..2bc6fbd9a5 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off.svg new file mode 100644 index 0000000000..459ea40242 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off_filled.svg new file mode 100644 index 0000000000..7269dffdd3 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_visibility_off_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_down.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_down.svg new file mode 100644 index 0000000000..44b8f89e91 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_up.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_up.svg new file mode 100644 index 0000000000..8d9f2ebecf --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_volume_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_filled.svg new file mode 100644 index 0000000000..adb8814e12 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_off_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_off_filled.svg new file mode 100644 index 0000000000..6ae367024e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_vpn_key_off_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_warning_filled.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_warning_filled.svg new file mode 100644 index 0000000000..673b7453f6 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_warning_filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_wifi_tethering.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_wifi_tethering.svg new file mode 100644 index 0000000000..f6007d3f02 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_wifi_tethering.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/icon_foreground_common@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/icon_foreground_common@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab60a329304d88d8aff82cc1bebd6b07fcaf320 GIT binary patch literal 25226 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 B{Br;R literal 0 HcmV?d00001 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/logo_light@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/logo_light@4x.png new file mode 100644 index 0000000000000000000000000000000000000000..98c1f500e95f8885f6c0f97961adeec539322a48 GIT binary patch literal 23606 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 HMMnJ(-+x5# literal 0 HcmV?d00001 diff --git a/apps/multiplatform/android/src/main/res/drawable-hdpi/privacy.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@1.5x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-hdpi/privacy.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@1.5x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-mdpi/privacy.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@1x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-mdpi/privacy.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@1x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xhdpi/privacy.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@2x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xhdpi/privacy.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@2x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxhdpi/privacy.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@3x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxhdpi/privacy.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@3x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxxhdpi/privacy.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@4x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxxhdpi/privacy.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/privacy@4x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-hdpi/shield.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/shield@1.5x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-hdpi/shield.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/shield@1.5x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-mdpi/shield.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/shield@1x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-mdpi/shield.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/shield@1x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xhdpi/shield.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/shield@2x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xhdpi/shield.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/shield@2x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxhdpi/shield.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/shield@3x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxhdpi/shield.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/shield@3x.png diff --git a/apps/multiplatform/android/src/main/res/drawable-xxxhdpi/shield.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/shield@4x.png similarity index 100% rename from apps/multiplatform/android/src/main/res/drawable-xxxhdpi/shield.png rename to apps/multiplatform/common/src/commonMain/resources/MR/images/shield@4x.png diff --git a/apps/multiplatform/common/src/commonMain/resources/distribute/SimpleX.desktop b/apps/multiplatform/common/src/commonMain/resources/distribute/SimpleX.desktop new file mode 100644 index 0000000000..bcfe0c0801 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/distribute/SimpleX.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Type=Application +Name=SimpleX Chat +Comment=Private and secure open-source messenger - no user IDs (not even random numbers). +Exec=simplex +Icon=simplex.png +Categories=Messenger; diff --git a/apps/multiplatform/common/src/commonMain/resources/distribute/simplex.png b/apps/multiplatform/common/src/commonMain/resources/distribute/simplex.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab60a329304d88d8aff82cc1bebd6b07fcaf320 GIT binary patch literal 25226 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 Date: Wed, 5 Jul 2023 15:47:39 +0300 Subject: [PATCH 2/4] multiplatform: FWheelPicker dependency from source (#2659) * multiplatform: FWheelPicker dependency from source * EOLs --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- apps/multiplatform/common/build.gradle.kts | 4 - .../chat/simplex/common/other/FWheelPicker.kt | 314 ++++++++++++++++++ .../common/other/FWheelPickerDefault.kt | 104 ++++++ .../simplex/common/other/FWheelPickerState.kt | 223 +++++++++++++ 4 files changed, 641 insertions(+), 4 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt diff --git a/apps/multiplatform/common/build.gradle.kts b/apps/multiplatform/common/build.gradle.kts index 880dbf729b..092f87690b 100644 --- a/apps/multiplatform/common/build.gradle.kts +++ b/apps/multiplatform/common/build.gradle.kts @@ -96,10 +96,6 @@ kotlin { api("androidx.camera:camera-lifecycle:${camerax_version}") api("androidx.camera:camera-view:${camerax_version}") - // LALAL REPLACE IT WITH SOURCE - // Wheel picker - api("com.github.zj565061763:compose-wheel-picker:1.0.0-alpha10") - // LALAL REMOVE api("org.jsoup:jsoup:1.13.1") api("com.godaddy.android.colorpicker:compose-color-picker-jvm:0.7.0") diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt new file mode 100644 index 0000000000..3cad946de2 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt @@ -0,0 +1,314 @@ +package com.sd.lib.compose.wheel_picker + +import androidx.compose.animation.core.DecayAnimationSpec +import androidx.compose.animation.core.calculateTargetValue +import androidx.compose.animation.core.exponentialDecay +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.Velocity +import androidx.compose.ui.unit.dp +import kotlin.math.absoluteValue + +interface FWheelPickerContentScope { + val state: FWheelPickerState +} + +interface FWheelPickerContentWrapperScope { + val state: FWheelPickerState + + @Composable + fun content(index: Int) +} + +// LALAL: make separate repo for this + +@Composable +fun FVerticalWheelPicker( + count: Int, + state: FWheelPickerState = rememberFWheelPickerState(), + modifier: Modifier = Modifier, + key: ((index: Int) -> Any)? = null, + itemHeight: Dp = 35.dp, + unfocusedCount: Int = 1, + userScrollEnabled: Boolean = true, + reverseLayout: Boolean = false, + debug: Boolean = false, + focus: @Composable () -> Unit = { FWheelPickerFocusVertical() }, + contentWrapper: @Composable FWheelPickerContentWrapperScope.(index: Int) -> Unit = DefaultWheelPickerContentWrapper, + content: @Composable FWheelPickerContentScope.(index: Int) -> Unit, +) { + WheelPicker( + isVertical = true, + count = count, + state = state, + modifier = modifier, + key = key, + itemSize = itemHeight, + unfocusedCount = unfocusedCount, + userScrollEnabled = userScrollEnabled, + reverseLayout = reverseLayout, + debug = debug, + focus = focus, + contentWrapper = contentWrapper, + content = content, + ) +} + +@Composable +fun FHorizontalWheelPicker( + count: Int, + state: FWheelPickerState = rememberFWheelPickerState(), + modifier: Modifier = Modifier, + key: ((index: Int) -> Any)? = null, + itemWidth: Dp = 35.dp, + unfocusedCount: Int = 1, + userScrollEnabled: Boolean = true, + reverseLayout: Boolean = false, + debug: Boolean = false, + focus: @Composable () -> Unit = { FWheelPickerFocusHorizontal() }, + contentWrapper: @Composable FWheelPickerContentWrapperScope.(index: Int) -> Unit = DefaultWheelPickerContentWrapper, + content: @Composable FWheelPickerContentScope.(index: Int) -> Unit, +) { + WheelPicker( + isVertical = false, + count = count, + state = state, + modifier = modifier, + key = key, + itemSize = itemWidth, + unfocusedCount = unfocusedCount, + userScrollEnabled = userScrollEnabled, + reverseLayout = reverseLayout, + debug = debug, + focus = focus, + contentWrapper = contentWrapper, + content = content, + ) +} + +@Composable +private fun WheelPicker( + isVertical: Boolean, + count: Int, + state: FWheelPickerState, + modifier: Modifier, + key: ((index: Int) -> Any)?, + itemSize: Dp, + unfocusedCount: Int, + userScrollEnabled: Boolean, + reverseLayout: Boolean, + debug: Boolean, + focus: @Composable () -> Unit, + contentWrapper: @Composable FWheelPickerContentWrapperScope.(index: Int) -> Unit, + content: @Composable FWheelPickerContentScope.(index: Int) -> Unit, +) { + require(count >= 0) { "require count >= 0" } + require(unfocusedCount >= 1) { "require unfocusedCount >= 1" } + + state.debug = debug + LaunchedEffect(state, count) { + state.notifyCountChanged(count) + } + + val nestedScrollConnection = remember(state) { + WheelPickerNestedScrollConnection(state) + }.apply { + this.isVertical = isVertical + this.itemSizePx = with(LocalDensity.current) { itemSize.roundToPx() } + this.reverseLayout = reverseLayout + } + + val totalSize = remember(itemSize, unfocusedCount) { + itemSize * (unfocusedCount * 2 + 1) + } + + val contentWrapperScope = remember(state) { + val contentScope = WheelPickerContentScopeImpl(state) + FWheelPickerContentWrapperScopeImpl(contentScope) + }.apply { + this.content = content + } + + Box( + modifier = modifier + .nestedScroll(nestedScrollConnection) + .run { + if (totalSize > 0.dp) { + if (isVertical) { + height(totalSize).widthIn(40.dp) + } else { + width(totalSize).heightIn(40.dp) + } + } else { + this + } + }, + contentAlignment = Alignment.Center, + ) { + + val lazyListScope: LazyListScope.() -> Unit = { + repeat(unfocusedCount) { + item { + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) + } + } + + items( + count = count, + key = key, + ) { index -> + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) { + contentWrapperScope.contentWrapper(index) + } + } + + repeat(unfocusedCount) { + item { + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) + } + } + } + + if (isVertical) { + LazyColumn( + state = state.lazyListState, + horizontalAlignment = Alignment.CenterHorizontally, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled, + modifier = Modifier.matchParentSize(), + content = lazyListScope, + ) + } else { + LazyRow( + state = state.lazyListState, + verticalAlignment = Alignment.CenterVertically, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled, + modifier = Modifier.matchParentSize(), + content = lazyListScope, + ) + } + + ItemSizeBox( + modifier = Modifier.align(Alignment.Center), + isVertical = isVertical, + itemSize = itemSize, + ) { + focus() + } + } +} + +@Composable +private fun ItemSizeBox( + modifier: Modifier = Modifier, + isVertical: Boolean, + itemSize: Dp, + content: @Composable () -> Unit = { }, +) { + Box( + modifier + .run { + if (isVertical) { + height(itemSize) + } else { + width(itemSize) + } + }, + contentAlignment = Alignment.Center, + ) { + content() + } +} + +private class WheelPickerNestedScrollConnection( + private val state: FWheelPickerState, +) : NestedScrollConnection { + var isVertical: Boolean? = null + var itemSizePx: Int? = null + var reverseLayout: Boolean? = null + + override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset { + state.synchronizeCurrentIndexSnapshot() + return super.onPostScroll(consumed, available, source) + } + + override suspend fun onPreFling(available: Velocity): Velocity { + val currentIndex = state.synchronizeCurrentIndexSnapshot() + return if (currentIndex >= 0) { + val flingItemCount = available.flingItemCount( + isVertical = isVertical!!, + itemSize = itemSizePx!!, + decay = exponentialDecay(2f), + reverseLayout = reverseLayout!!, + ) + + if (flingItemCount.absoluteValue > 0) { + state.animateScrollToIndex(currentIndex - flingItemCount) + } else { + state.animateScrollToIndex(currentIndex) + } + available + } else { + super.onPreFling(available) + } + } +} + +private fun Velocity.flingItemCount( + isVertical: Boolean, + itemSize: Int, + decay: DecayAnimationSpec, + reverseLayout: Boolean, +): Int { + if (itemSize <= 0) return 0 + val velocity = if (isVertical) y else x + val targetValue = decay.calculateTargetValue(0f, velocity) + val flingItemCount = (targetValue / itemSize).toInt() + return if (reverseLayout) -flingItemCount else flingItemCount +} + +private class WheelPickerContentScopeImpl( + override val state: FWheelPickerState, +) : FWheelPickerContentScope + +private class FWheelPickerContentWrapperScopeImpl( + private val contentScope: FWheelPickerContentScope +) : FWheelPickerContentWrapperScope { + lateinit var content: @Composable FWheelPickerContentScope.(index: Int) -> Unit + + override val state: FWheelPickerState get() = contentScope.state + + @Composable + override fun content(index: Int) { + contentScope.content(index) + } +} + +internal inline fun logMsg(debug: Boolean, block: () -> String) { + if (debug) { + println("FWheelPicker" + block()) + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt new file mode 100644 index 0000000000..ed2533b488 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt @@ -0,0 +1,104 @@ +package com.sd.lib.compose.wheel_picker + +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * The default implementation of focus view in vertical. + */ +@Composable +fun FWheelPickerFocusVertical( + modifier: Modifier = Modifier, + dividerSize: Dp = 1.dp, + dividerColor: Color = DefaultDividerColor, +) { + Box( + modifier = modifier.fillMaxSize() + ) { + Box( + modifier = Modifier + .background(dividerColor) + .height(dividerSize) + .fillMaxWidth() + .align(Alignment.TopCenter), + ) + Box( + modifier = Modifier + .background(dividerColor) + .height(dividerSize) + .fillMaxWidth() + .align(Alignment.BottomCenter), + ) + } +} + +/** + * The default implementation of focus view in horizontal. + */ +@Composable +fun FWheelPickerFocusHorizontal( + modifier: Modifier = Modifier, + dividerSize: Dp = 1.dp, + dividerColor: Color = DefaultDividerColor, +) { + Box( + modifier = modifier.fillMaxSize() + ) { + Box( + modifier = Modifier + .background(dividerColor) + .width(dividerSize) + .fillMaxHeight() + .align(Alignment.CenterStart), + ) + Box( + modifier = Modifier + .background(dividerColor) + .width(dividerSize) + .fillMaxHeight() + .align(Alignment.CenterEnd), + ) + } +} + +/** + * Default divider color. + */ +private val DefaultDividerColor: Color + @Composable + get() = (if (isSystemInDarkTheme()) { + Color.White + } else { + Color.Black + }).copy(alpha = 0.2f) + +/** + * Default content wrapper. + */ +val DefaultWheelPickerContentWrapper: @Composable FWheelPickerContentWrapperScope.(index: Int) -> Unit + get() = { index -> + val isFocus = index == state.currentIndexSnapshot + val targetAlpha = if (isFocus) 1.0f else 0.3f + val targetScale = if (isFocus) 1.0f else 0.8f + val animateScale by animateFloatAsState(targetScale) + Box( + modifier = Modifier + .graphicsLayer { + this.alpha = targetAlpha + this.scaleX = animateScale + this.scaleY = animateScale + } + ) { + content(index) + } + } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt new file mode 100644 index 0000000000..154a91b705 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt @@ -0,0 +1,223 @@ +package com.sd.lib.compose.wheel_picker + +import androidx.compose.foundation.MutatePriority +import androidx.compose.foundation.gestures.ScrollScope +import androidx.compose.foundation.gestures.ScrollableState +import androidx.compose.foundation.interaction.InteractionSource +import androidx.compose.foundation.lazy.LazyListItemInfo +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.Saver +import androidx.compose.runtime.saveable.listSaver +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume +import kotlin.math.absoluteValue + +@Composable +fun rememberFWheelPickerState( + initialIndex: Int = 0, +): FWheelPickerState = rememberSaveable(saver = FWheelPickerState.Saver) { + FWheelPickerState( + initialIndex = initialIndex, + ) +} + +class FWheelPickerState( + initialIndex: Int = 0, +) : ScrollableState { + + internal var debug = false + internal val lazyListState = LazyListState() + + private var _currentIndex by mutableStateOf(-1) + private var _currentIndexSnapshot by mutableStateOf(-1) + + private var _pendingIndex: Int? = initialIndex + set(value) { + field = value + if (value == null) resumeAwaitScroll() + } + private var _pendingIndexContinuation: Continuation? = null + + private var _count = 0 + set(value) { + field = value.coerceAtLeast(0) + } + + /** + * Index of picker when it is idle. + * + * Note that this property is observable and if you use it in the composable function + * it will be recomposed on every change. + */ + val currentIndex: Int + get() = _currentIndex + + /** + * Index of picker when it is idle or drag but not fling. + * + * Note that this property is observable and if you use it in the composable function + * it will be recomposed on every change. + */ + val currentIndexSnapshot: Int + get() = _currentIndexSnapshot + + val interactionSource: InteractionSource + get() = lazyListState.interactionSource + + val hasPendingScroll: Boolean + get() = _pendingIndex != null + + suspend fun animateScrollToIndex( + index: Int, + ) { + logMsg(debug) { "animateScrollToIndex index:$index" } + + val safeIndex = index.coerceAtLeast(0) + lazyListState.animateScrollToItem(safeIndex) + synchronizeCurrentIndex() + } + + suspend fun scrollToIndex( + index: Int, + pending: Boolean = true, + ) { + logMsg(debug) { "scrollToIndex index:$index pending:$pending" } + + val safeIndex = index.coerceAtLeast(0) + lazyListState.scrollToItem(safeIndex) + synchronizeCurrentIndex() + + if (pending) { + awaitScroll(safeIndex) + } + } + + private suspend fun awaitScroll(index: Int) { + if (_currentIndex == index) return + logMsg(debug) { "awaitScroll index $index start" } + + // Resume last continuation before suspend. + resumeAwaitScroll() + + _pendingIndex = index + suspendCancellableCoroutine { + _pendingIndexContinuation = it + it.invokeOnCancellation { + logMsg(debug) { "awaitScroll index $index canceled" } + _pendingIndexContinuation = null + _pendingIndex = null + + } + } + + logMsg(debug) { "awaitScroll index $index finish" } + } + + private fun resumeAwaitScroll() { + _pendingIndexContinuation?.let { + logMsg(debug) { "resumeAwaitScroll pendingIndex:$_pendingIndex" } + it.resume(Unit) + _pendingIndexContinuation = null + } + } + + internal suspend fun notifyCountChanged(count: Int) { + logMsg(debug) { "notifyCountChanged count:$count currentIndex:$_currentIndex pendingIndex:$_pendingIndex" } + + _count = count + + val maxIndex = count - 1 + if (_currentIndex > maxIndex) { + setCurrentIndexInternal(maxIndex) + } else { + _pendingIndex?.let { pendingIndex -> + if (count > pendingIndex) { + scrollToIndex(pendingIndex, pending = false) + } + } + if (_currentIndex < 0) { + synchronizeCurrentIndex() + } + } + } + + private fun synchronizeCurrentIndex() { + logMsg(debug) { "synchronizeCurrentIndex" } + val index = synchronizeCurrentIndexSnapshot() + setCurrentIndexInternal(index) + } + + private fun setCurrentIndexInternal(index: Int) { + val safeIndex = index.coerceAtLeast(-1) + if (_currentIndex != safeIndex) { + logMsg(debug) { "Current index changed $safeIndex" } + _currentIndex = safeIndex + _currentIndexSnapshot = safeIndex + if (_pendingIndex == safeIndex) { + _pendingIndex = null + } + } + } + + internal fun synchronizeCurrentIndexSnapshot(): Int { + return (mostStartItemInfo()?.index ?: -1).also { + _currentIndexSnapshot = it + } + } + + /** + * The item closest to the viewport start. + */ + private fun mostStartItemInfo(): LazyListItemInfo? { + if (_count <= 0) return null + + val layoutInfo = lazyListState.layoutInfo + val listInfo = layoutInfo.visibleItemsInfo + + if (listInfo.isEmpty()) return null + if (listInfo.size == 1) return listInfo.first() + + val firstItem = listInfo.first() + val firstOffsetDelta = (firstItem.offset - layoutInfo.viewportStartOffset).absoluteValue + return if (firstOffsetDelta < firstItem.size / 2) { + firstItem + } else { + listInfo[1] + } + } + + override val isScrollInProgress: Boolean + get() = lazyListState.isScrollInProgress + + override suspend fun scroll( + scrollPriority: MutatePriority, + block: suspend ScrollScope.() -> Unit, + ) { + lazyListState.scroll(scrollPriority, block) + } + + override fun dispatchRawDelta(delta: Float): Float { + return lazyListState.dispatchRawDelta(delta) + } + + companion object { + val Saver: Saver = listSaver( + save = { + listOf( + it.currentIndex, + ) + }, + restore = { + FWheelPickerState( + initialIndex = it[0] as Int, + ) + } + ) + } +} From c329bf4ea1e6f2ef0501532abc1d70dd7f34f6ca Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:21:53 +0100 Subject: [PATCH 3/4] multiplatform: move dependency, reference (#2662) --- .../simplex/common/other/{ => wheel-picker}/FWheelPicker.kt | 2 ++ .../common/other/{ => wheel-picker}/FWheelPickerDefault.kt | 0 .../common/other/{ => wheel-picker}/FWheelPickerState.kt | 0 3 files changed, 2 insertions(+) rename apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/{ => wheel-picker}/FWheelPicker.kt (99%) rename apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/{ => wheel-picker}/FWheelPickerDefault.kt (100%) rename apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/{ => wheel-picker}/FWheelPickerState.kt (100%) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPicker.kt similarity index 99% rename from apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt rename to apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPicker.kt index 3cad946de2..a1e0b15e33 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPicker.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPicker.kt @@ -1,3 +1,5 @@ +// Fork of https://github.com/zj565061763/compose-wheel-picker to make multi-platform + package com.sd.lib.compose.wheel_picker import androidx.compose.animation.core.DecayAnimationSpec diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt similarity index 100% rename from apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerDefault.kt rename to apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerDefault.kt diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerState.kt similarity index 100% rename from apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/FWheelPickerState.kt rename to apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/other/wheel-picker/FWheelPickerState.kt From ae17566a9458d02c307c5d457901dc4cc8407008 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 5 Jul 2023 19:44:21 +0400 Subject: [PATCH 4/4] core: ratchet synchronization (#2653) --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat.hs | 120 +++++++++++----- src/Simplex/Chat/Controller.hs | 18 +++ src/Simplex/Chat/Messages/CIContent.hs | 37 +++-- src/Simplex/Chat/Store/Direct.hs | 3 - src/Simplex/Chat/View.hs | 34 ++++- stack.yaml | 2 +- tests/ChatTests/Direct.hs | 137 ++++++++++++++---- tests/ChatTests/Groups.hs | 188 ++++++++++++++++++------- 10 files changed, 411 insertions(+), 132 deletions(-) diff --git a/cabal.project b/cabal.project index e2edbe83eb..e7686237fe 100644 --- a/cabal.project +++ b/cabal.project @@ -7,7 +7,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: fe22d9b299f106fc4a3d167e90499ddb4d3bfa26 + tag: f2657f9c0b954f952aaf381bb9b55ac34ea59ed7 source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 772ef9d864..f7b224524b 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."fe22d9b299f106fc4a3d167e90499ddb4d3bfa26" = "1hk6cb7bh5nn3cj6wb38ap2kyg16ajff6mk5xj6vpjh5dgpp8hkb"; + "https://github.com/simplex-chat/simplexmq.git"."f2657f9c0b954f952aaf381bb9b55ac34ea59ed7" = "04qhadd0shs4hj5b62i78jhnq5c620b72naqavqirvjc7pymyq5g"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb"; "https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd"; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index a42bb561dc..af0f8e31a5 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -1134,6 +1134,19 @@ processChatCommand = \case connectionStats <- withAgent $ \a -> abortConnectionSwitch a connId pure $ CRGroupMemberSwitchAborted user g m connectionStats _ -> throwChatError CEGroupMemberNotActive + APISyncContactRatchet contactId force -> withUser $ \user -> do + ct <- withStore $ \db -> getContact db user contactId + cStats@ConnectionStats {ratchetSyncState = rss} <- withAgent $ \a -> synchronizeRatchet a (contactConnId ct) force + createInternalChatItem user (CDDirectSnd ct) (CISndConnEvent $ SCERatchetSync rss Nothing) Nothing + pure $ CRContactRatchetSyncStarted user ct cStats + APISyncGroupMemberRatchet gId gMemberId force -> withUser $ \user -> do + (g, m) <- withStore $ \db -> (,) <$> getGroupInfo db user gId <*> getGroupMember db user gId gMemberId + case memberConnId m of + Just connId -> do + cStats@ConnectionStats {ratchetSyncState = rss} <- withAgent $ \a -> synchronizeRatchet a connId force + createInternalChatItem user (CDGroupSnd g) (CISndConnEvent . SCERatchetSync rss . Just $ groupMemberRef m) Nothing + pure $ CRGroupMemberRatchetSyncStarted user g m cStats + _ -> throwChatError CEGroupMemberNotActive APIGetContactCode contactId -> withUser $ \user -> do ct@Contact {activeConn = conn@Connection {connId}} <- withStore $ \db -> getContact db user contactId code <- getConnectionCode (contactConnId ct) @@ -1196,6 +1209,8 @@ processChatCommand = \case SwitchGroupMember gName mName -> withMemberName gName mName APISwitchGroupMember AbortSwitchContact cName -> withContactName cName APIAbortSwitchContact AbortSwitchGroupMember gName mName -> withMemberName gName mName APIAbortSwitchGroupMember + SyncContactRatchet cName force -> withContactName cName $ \ctId -> APISyncContactRatchet ctId force + SyncGroupMemberRatchet gName mName force -> withMemberName gName mName $ \gId mId -> APISyncGroupMemberRatchet gId mId force GetContactCode cName -> withContactName cName APIGetContactCode GetGroupMemberCode gName mName -> withMemberName gName mName APIGetGroupMemberCode VerifyContact cName code -> withContactName cName (`APIVerifyContact` code) @@ -2716,7 +2731,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do _ -> Nothing processDirectMessage :: ACommand 'Agent e -> ConnectionEntity -> Connection -> Maybe Contact -> m () - processDirectMessage agentMsg connEntity conn@Connection {connId, viaUserContactLink, groupLinkId, customUserProfileId} = \case + processDirectMessage agentMsg connEntity conn@Connection {connId, viaUserContactLink, groupLinkId, customUserProfileId, connectionCode} = \case Nothing -> case agentMsg of CONF confId _ connInfo -> do -- [incognito] send saved profile @@ -2849,6 +2864,36 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do when (phase `elem` [SPStarted, SPCompleted]) $ case qd of QDRcv -> createInternalChatItem user (CDDirectSnd ct) (CISndConnEvent $ SCESwitchQueue phase Nothing) Nothing QDSnd -> createInternalChatItem user (CDDirectRcv ct) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing + RSYNC rss cryptoErr_ cStats -> + case (rss, connectionCode, cryptoErr_) of + (RSRequired, _, Just cryptoErr) -> processErr cryptoErr + (RSAllowed, _, Just cryptoErr) -> processErr cryptoErr + (RSAgreed, Just _, _) -> do + withStore' $ \db -> setConnectionVerified db user connId Nothing + let ct' = ct {activeConn = conn {connectionCode = Nothing}} :: Contact + ratchetSyncEventItem ct' + toView $ CRContactVerificationReset user ct' + createInternalChatItem user (CDDirectRcv ct') (CIRcvConnEvent RCEVerificationCodeReset) Nothing + _ -> ratchetSyncEventItem ct + where + processErr cryptoErr = do + let e@(mde, n) = agentMsgDecryptError cryptoErr + ci_ <- withStore $ \db -> + getDirectChatItemsLast db user contactId 1 "" + >>= liftIO + . mapM (\(ci, content') -> updateDirectChatItem' db user contactId ci content' False Nothing) + . (mdeUpdatedCI e <=< headMaybe) + case ci_ of + Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTDirect SMDRcv (DirectChat ct) ci) + _ -> do + toView $ CRContactRatchetSync user ct (RatchetSyncProgress rss cStats) + createInternalChatItem user (CDDirectRcv ct) (CIRcvDecryptionError mde n) Nothing + headMaybe = \case + x : _ -> Just x + _ -> Nothing + ratchetSyncEventItem ct' = do + toView $ CRContactRatchetSync user ct' (RatchetSyncProgress rss cStats) + createInternalChatItem user (CDDirectRcv ct') (CIRcvConnEvent $ RCERatchetSync rss) Nothing OK -> -- [async agent commands] continuation on receiving OK withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} -> @@ -2863,24 +2908,11 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do ERR err -> do toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity) when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure () - forM_ (agentMsgDecryptError err) $ \e@(mde, n) -> do - ci_ <- withStore $ \db -> - getDirectChatItemsLast db user contactId 1 "" - >>= liftIO - . mapM (\(ci, content') -> updateDirectChatItem' db user contactId ci content' False Nothing) - . (mdeUpdatedCI e <=< headMaybe) - case ci_ of - Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTDirect SMDRcv (DirectChat ct) ci) - _ -> createInternalChatItem user (CDDirectRcv ct) (CIRcvDecryptionError mde n) Nothing - where - headMaybe = \case - x : _ -> Just x - _ -> Nothing -- TODO add debugging output _ -> pure () processGroupMessage :: ACommand 'Agent e -> ConnectionEntity -> Connection -> GroupInfo -> GroupMember -> m () - processGroupMessage agentMsg connEntity conn@Connection {connId} gInfo@GroupInfo {groupId, localDisplayName = gName, groupProfile, membership, chatSettings} m = case agentMsg of + processGroupMessage agentMsg connEntity conn@Connection {connId, connectionCode} gInfo@GroupInfo {groupId, localDisplayName = gName, groupProfile, membership, chatSettings} m = case agentMsg of INV (ACR _ cReq) -> withCompletedCommand conn agentMsg $ \CommandData {cmdFunction} -> case cReq of @@ -3028,6 +3060,33 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do when (phase `elem` [SPStarted, SPCompleted]) $ case qd of QDRcv -> createInternalChatItem user (CDGroupSnd gInfo) (CISndConnEvent . SCESwitchQueue phase . Just $ groupMemberRef m) Nothing QDSnd -> createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvConnEvent $ RCESwitchQueue phase) Nothing + RSYNC rss cryptoErr_ cStats -> + case (rss, connectionCode, cryptoErr_) of + (RSRequired, _, Just cryptoErr) -> processErr cryptoErr + (RSAllowed, _, Just cryptoErr) -> processErr cryptoErr + (RSAgreed, Just _, _) -> do + withStore' $ \db -> setConnectionVerified db user connId Nothing + let m' = m {activeConn = Just (conn {connectionCode = Nothing} :: Connection)} :: GroupMember + ratchetSyncEventItem m' + toView $ CRGroupMemberVerificationReset user gInfo m' + createInternalChatItem user (CDGroupRcv gInfo m') (CIRcvConnEvent RCEVerificationCodeReset) Nothing + _ -> ratchetSyncEventItem m + where + processErr cryptoErr = do + let e@(mde, n) = agentMsgDecryptError cryptoErr + ci_ <- withStore $ \db -> + getGroupMemberChatItemLast db user groupId (groupMemberId' m) + >>= liftIO + . mapM (\(ci, content') -> updateGroupChatItem db user groupId ci content' False Nothing) + . mdeUpdatedCI e + case ci_ of + Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTGroup SMDRcv (GroupChat gInfo) ci) + _ -> do + toView $ CRGroupMemberRatchetSync user gInfo m (RatchetSyncProgress rss cStats) + createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvDecryptionError mde n) Nothing + ratchetSyncEventItem m' = do + toView $ CRGroupMemberRatchetSync user gInfo m' (RatchetSyncProgress rss cStats) + createInternalChatItem user (CDGroupRcv gInfo m') (CIRcvConnEvent $ RCERatchetSync rss) Nothing OK -> -- [async agent commands] continuation on receiving OK withCompletedCommand conn agentMsg $ \CommandData {cmdFunction, cmdId} -> @@ -3038,35 +3097,24 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do ERR err -> do toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity) when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure () - forM_ (agentMsgDecryptError err) $ \e@(mde, n) -> do - ci_ <- withStore $ \db -> - getGroupMemberChatItemLast db user groupId (groupMemberId' m) - >>= liftIO - . mapM (\(ci, content') -> updateGroupChatItem db user groupId ci content' False Nothing) - . mdeUpdatedCI e - case ci_ of - Just ci -> toView $ CRChatItemUpdated user (AChatItem SCTGroup SMDRcv (GroupChat gInfo) ci) - _ -> createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvDecryptionError mde n) Nothing -- TODO add debugging output _ -> pure () - agentMsgDecryptError :: AgentErrorType -> Maybe (MsgDecryptError, Word32) + agentMsgDecryptError :: AgentCryptoError -> (MsgDecryptError, Word32) agentMsgDecryptError = \case - AGENT (A_CRYPTO RATCHET_HEADER) -> Just (MDERatchetHeader, 1) - AGENT (A_CRYPTO (RATCHET_SKIPPED n)) -> Just (MDETooManySkipped, n) - -- we are not treating this as decryption error, as in many cases it happens as the result of duplicate or redundant delivery, - -- and we don't have a way to differentiate. - -- we could store the hashes of past messages in the agent, or delaying message deletion after ACK - -- A_DUPLICATE -> Nothing - -- earlier messages may be received in case of redundant delivery, and do not necessarily indicate an error - -- AGENT (A_CRYPTO (RATCHET_EARLIER n)) -> Nothing - _ -> Nothing + DECRYPT_AES -> (MDEOther, 1) + DECRYPT_CB -> (MDEOther, 1) + RATCHET_HEADER -> (MDERatchetHeader, 1) + RATCHET_EARLIER _ -> (MDERatchetEarlier, 1) + RATCHET_SKIPPED n -> (MDETooManySkipped, n) mdeUpdatedCI :: (MsgDecryptError, Word32) -> CChatItem c -> Maybe (ChatItem c 'MDRcv, CIContent 'MDRcv) mdeUpdatedCI (mde', n') (CChatItem _ ci@ChatItem {content = CIRcvDecryptionError mde n}) | mde == mde' = case mde of MDERatchetHeader -> r (n + n') MDETooManySkipped -> r n' -- the numbers are not added as sequential MDETooManySkipped will have it incremented by 1 + MDERatchetEarlier -> r (n + n') + MDEOther -> r (n + n') | otherwise = Nothing where r n'' = Just (ci, CIRcvDecryptionError mde n'') @@ -4919,10 +4967,14 @@ chatCommandP = "/_switch @" *> (APISwitchContact <$> A.decimal), "/_abort switch #" *> (APIAbortSwitchGroupMember <$> A.decimal <* A.space <*> A.decimal), "/_abort switch @" *> (APIAbortSwitchContact <$> A.decimal), + "/_sync #" *> (APISyncGroupMemberRatchet <$> A.decimal <* A.space <*> A.decimal <*> (" force=on" $> True <|> pure False)), + "/_sync @" *> (APISyncContactRatchet <$> A.decimal <*> (" force=on" $> True <|> pure False)), "/switch #" *> (SwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName), "/switch " *> char_ '@' *> (SwitchContact <$> displayName), "/abort switch #" *> (AbortSwitchGroupMember <$> displayName <* A.space <* char_ '@' <*> displayName), "/abort switch " *> char_ '@' *> (AbortSwitchContact <$> displayName), + "/sync #" *> (SyncGroupMemberRatchet <$> displayName <* A.space <* char_ '@' <*> displayName <*> (" force=on" $> True <|> pure False)), + "/sync " *> char_ '@' *> (SyncContactRatchet <$> displayName <*> (" force=on" $> True <|> pure False)), "/_get code @" *> (APIGetContactCode <$> A.decimal), "/_get code #" *> (APIGetGroupMemberCode <$> A.decimal <* A.space <*> A.decimal), "/_verify code @" *> (APIVerifyContact <$> A.decimal <*> optional (A.space *> textP)), diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 08127bc66d..9784180e27 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -287,6 +287,8 @@ data ChatCommand | APISwitchGroupMember GroupId GroupMemberId | APIAbortSwitchContact ContactId | APIAbortSwitchGroupMember GroupId GroupMemberId + | APISyncContactRatchet ContactId Bool + | APISyncGroupMemberRatchet GroupId GroupMemberId Bool | APIGetContactCode ContactId | APIGetGroupMemberCode GroupId GroupMemberId | APIVerifyContact ContactId (Maybe Text) @@ -300,6 +302,8 @@ data ChatCommand | SwitchGroupMember GroupName ContactName | AbortSwitchContact ContactName | AbortSwitchGroupMember GroupName ContactName + | SyncContactRatchet ContactName Bool + | SyncGroupMemberRatchet GroupName ContactName Bool | GetContactCode ContactName | GetGroupMemberCode GroupName ContactName | VerifyContact ContactName (Maybe Text) @@ -415,6 +419,12 @@ data ChatResponse | CRGroupMemberSwitchAborted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats} | CRContactSwitch {user :: User, contact :: Contact, switchProgress :: SwitchProgress} | CRGroupMemberSwitch {user :: User, groupInfo :: GroupInfo, member :: GroupMember, switchProgress :: SwitchProgress} + | CRContactRatchetSyncStarted {user :: User, contact :: Contact, connectionStats :: ConnectionStats} + | CRGroupMemberRatchetSyncStarted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats} + | CRContactRatchetSync {user :: User, contact :: Contact, ratchetSyncProgress :: RatchetSyncProgress} + | CRGroupMemberRatchetSync {user :: User, groupInfo :: GroupInfo, member :: GroupMember, ratchetSyncProgress :: RatchetSyncProgress} + | CRContactVerificationReset {user :: User, contact :: Contact} + | CRGroupMemberVerificationReset {user :: User, groupInfo :: GroupInfo, member :: GroupMember} | CRContactCode {user :: User, contact :: Contact, connectionCode :: Text} | CRGroupMemberCode {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionCode :: Text} | CRConnectionVerified {user :: User, verified :: Bool, expectedCode :: Text} @@ -719,6 +729,14 @@ data SwitchProgress = SwitchProgress instance ToJSON SwitchProgress where toEncoding = J.genericToEncoding J.defaultOptions +data RatchetSyncProgress = RatchetSyncProgress + { ratchetSyncStatus :: RatchetSyncState, + connectionStats :: ConnectionStats + } + deriving (Show, Generic) + +instance ToJSON RatchetSyncProgress where toEncoding = J.genericToEncoding J.defaultOptions + data ParsedServerAddress = ParsedServerAddress { serverAddress :: Maybe ServerAddress, parseError :: String diff --git a/src/Simplex/Chat/Messages/CIContent.hs b/src/Simplex/Chat/Messages/CIContent.hs index 030f28074a..40b139783b 100644 --- a/src/Simplex/Chat/Messages/CIContent.hs +++ b/src/Simplex/Chat/Messages/CIContent.hs @@ -29,7 +29,7 @@ import Database.SQLite.Simple.ToField (ToField (..)) import GHC.Generics (Generic) import Simplex.Chat.Protocol import Simplex.Chat.Types -import Simplex.Messaging.Agent.Protocol (MsgErrorType (..), SwitchPhase (..)) +import Simplex.Messaging.Agent.Protocol (MsgErrorType (..), RatchetSyncState (..), SwitchPhase (..)) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (dropPrefix, enumJSON, fstToLower, singleFieldJSON, sumTypeJSON) import Simplex.Messaging.Util (safeDecodeUtf8, tshow) @@ -157,7 +157,7 @@ ciMsgContent = \case CIRcvMsgContent mc -> Just mc _ -> Nothing -data MsgDecryptError = MDERatchetHeader | MDETooManySkipped +data MsgDecryptError = MDERatchetHeader | MDETooManySkipped | MDERatchetEarlier | MDEOther deriving (Eq, Show, Generic) instance ToJSON MsgDecryptError where @@ -253,10 +253,15 @@ instance ToJSON DBSndGroupEvent where toJSON (SGE v) = J.genericToJSON (singleFieldJSON $ dropPrefix "SGE") v toEncoding (SGE v) = J.genericToEncoding (singleFieldJSON $ dropPrefix "SGE") v -data RcvConnEvent = RCESwitchQueue {phase :: SwitchPhase} +data RcvConnEvent + = RCESwitchQueue {phase :: SwitchPhase} + | RCERatchetSync {syncStatus :: RatchetSyncState} + | RCEVerificationCodeReset deriving (Show, Generic) -data SndConnEvent = SCESwitchQueue {phase :: SwitchPhase, member :: Maybe GroupMemberRef} +data SndConnEvent + = SCESwitchQueue {phase :: SwitchPhase, member :: Maybe GroupMemberRef} + | SCERatchetSync {syncStatus :: RatchetSyncState, member :: Maybe GroupMemberRef} deriving (Show, Generic) instance FromJSON RcvConnEvent where @@ -387,6 +392,16 @@ rcvConnEventToText = \case SPConfirmed -> "confirmed changing address for you..." SPSecured -> "secured new address for you..." SPCompleted -> "changed address for you" + RCERatchetSync syncStatus -> ratchetSyncStatusToText syncStatus + RCEVerificationCodeReset -> "security code changed" + +ratchetSyncStatusToText :: RatchetSyncState -> Text +ratchetSyncStatusToText = \case + RSOk -> "connection synchronized" + RSAllowed -> "decryption error (connection may be out of sync), synchronization allowed" + RSRequired -> "decryption error (connection out of sync), synchronization required" + RSStarted -> "connection synchronization started" + RSAgreed -> "connection synchronization agreed" sndConnEventToText :: SndConnEvent -> Text sndConnEventToText = \case @@ -395,6 +410,7 @@ sndConnEventToText = \case SPConfirmed -> "confirmed changing address" <> forMember m <> "..." SPSecured -> "secured new address" <> forMember m <> "..." SPCompleted -> "you changed address" <> forMember m + SCERatchetSync syncStatus m -> ratchetSyncStatusToText syncStatus <> forMember m where forMember member_ = maybe "" (\GroupMemberRef {profile = Profile {displayName}} -> " for " <> displayName) member_ @@ -413,11 +429,16 @@ msgIntegrityError = \case msgDecryptErrorText :: MsgDecryptError -> Word32 -> Text msgDecryptErrorText err n = - "decryption error, possibly due to the device change (" <> errName <> if n == 1 then ")" else ", " <> tshow n <> " messages)" + "decryption error, possibly due to the device change" + <> maybe "" (\ed -> " (" <> ed <> ")") errDesc where - errName = case err of - MDERatchetHeader -> "header" - MDETooManySkipped -> "too many skipped messages" + errDesc = case err of + MDERatchetHeader -> Just $ "header" <> counter + MDETooManySkipped -> Just $ "too many skipped messages" <> counter + MDERatchetEarlier -> Just $ "earlier message" <> counter + MDEOther -> counter_ + counter_ = if n == 1 then Nothing else Just $ tshow n <> " messages" + counter = maybe "" (", " <>) counter_ msgDirToModeratedContent_ :: SMsgDirection d -> CIContent d msgDirToModeratedContent_ = \case diff --git a/src/Simplex/Chat/Store/Direct.hs b/src/Simplex/Chat/Store/Direct.hs index 2f3344bb66..845167bdd3 100644 --- a/src/Simplex/Chat/Store/Direct.hs +++ b/src/Simplex/Chat/Store/Direct.hs @@ -627,9 +627,6 @@ getContactConnections db userId Contact {contactId} = connections [] = throwError $ SEContactNotFound contactId connections rows = pure $ map toConnection rows - - - getConnectionById :: DB.Connection -> User -> Int64 -> ExceptT StoreError IO Connection getConnectionById db User {userId} connId = ExceptT $ do firstRow toConnection (SEConnectionNotFoundById connId) $ diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index e67746a2c8..8328b1507d 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -28,7 +28,6 @@ import Data.Time (LocalTime (..), TimeOfDay (..), TimeZone (..), utcToLocalTime) import Data.Time.Calendar (addDays) import Data.Time.Clock (UTCTime) import Data.Time.Format (defaultTimeLocale, formatTime) -import Data.Word (Word32) import GHC.Generics (Generic) import qualified Network.HTTP.Types as Q import Numeric (showFFloat) @@ -86,6 +85,12 @@ responseToView user_ ChatConfig {logLevel, showReactions, testView} liveItems ts CRGroupMemberSwitchAborted {} -> ["switch aborted"] CRContactSwitch u ct progress -> ttyUser u $ viewContactSwitch ct progress CRGroupMemberSwitch u g m progress -> ttyUser u $ viewGroupMemberSwitch g m progress + CRContactRatchetSyncStarted {} -> ["connection synchronization started"] + CRGroupMemberRatchetSyncStarted {} -> ["connection synchronization started"] + CRContactRatchetSync u ct progress -> ttyUser u $ viewContactRatchetSync ct progress + CRGroupMemberRatchetSync u g m progress -> ttyUser u $ viewGroupMemberRatchetSync g m progress + CRContactVerificationReset u ct -> ttyUser u $ viewContactVerificationReset ct + CRGroupMemberVerificationReset u g m -> ttyUser u $ viewGroupMemberVerificationReset g m CRConnectionVerified u verified code -> ttyUser u [plain $ if verified then "connection verified" else "connection not verified, current code is " <> code] CRContactCode u ct code -> ttyUser u $ viewContactCode ct code testView CRGroupMemberCode u g m code -> ttyUser u $ viewGroupMemberCode g m code testView @@ -385,7 +390,6 @@ viewChatItem chat ci@ChatItem {chatDir, meta = meta, content, quotedItem, file} CIDirectRcv -> case content of CIRcvMsgContent mc -> withRcvFile from $ rcvMsg from quote mc CIRcvIntegrityError err -> viewRcvIntegrityError from err ts tz meta - CIRcvDecryptionError err n -> viewRcvDecryptionError from err n ts tz meta CIRcvGroupEvent {} -> showRcvItemProhibited from _ -> showRcvItem from where @@ -402,7 +406,6 @@ viewChatItem chat ci@ChatItem {chatDir, meta = meta, content, quotedItem, file} CIGroupRcv m -> case content of CIRcvMsgContent mc -> withRcvFile from $ rcvMsg from quote mc CIRcvIntegrityError err -> viewRcvIntegrityError from err ts tz meta - CIRcvDecryptionError err n -> viewRcvDecryptionError from err n ts tz meta CIRcvGroupInvitation {} -> showRcvItemProhibited from CIRcvModerated {} -> receivedWithTime_ ts tz (ttyFromGroup g m) quote meta [plainContent content] False _ -> showRcvItem from @@ -587,9 +590,6 @@ msgPreview = msgPlain . preview . msgContentText viewRcvIntegrityError :: StyledString -> MsgErrorType -> CurrentTime -> TimeZone -> CIMeta c 'MDRcv -> [StyledString] viewRcvIntegrityError from msgErr ts tz meta = receivedWithTime_ ts tz from [] meta (viewMsgIntegrityError msgErr) False -viewRcvDecryptionError :: StyledString -> MsgDecryptError -> Word32 -> CurrentTime -> TimeZone -> CIMeta c 'MDRcv -> [StyledString] -viewRcvDecryptionError from err n ts tz meta = receivedWithTime_ ts tz from [] meta [ttyError $ msgDecryptErrorText err n] False - viewMsgIntegrityError :: MsgErrorType -> [StyledString] viewMsgIntegrityError err = [ttyError $ msgIntegrityError err] @@ -968,6 +968,28 @@ viewGroupMemberSwitch g m (SwitchProgress qd phase _) = case qd of QDRcv -> [ttyGroup' g <> ": you " <> viewSwitchPhase phase <> " for " <> ttyMember m] QDSnd -> [ttyGroup' g <> ": " <> ttyMember m <> " " <> viewSwitchPhase phase <> " for you"] +viewContactRatchetSync :: Contact -> RatchetSyncProgress -> [StyledString] +viewContactRatchetSync ct@Contact {localDisplayName = c} RatchetSyncProgress {ratchetSyncStatus = rss} = + [ttyContact' ct <> ": " <> (plain . ratchetSyncStatusToText) rss] + <> help + where + help = ["use " <> highlight ("/sync " <> c) <> " to synchronize" | rss `elem` [RSAllowed, RSRequired]] + +viewGroupMemberRatchetSync :: GroupInfo -> GroupMember -> RatchetSyncProgress -> [StyledString] +viewGroupMemberRatchetSync g m@GroupMember {localDisplayName = n} RatchetSyncProgress {ratchetSyncStatus = rss} = + [ttyGroup' g <> " " <> ttyMember m <> ": " <> (plain . ratchetSyncStatusToText) rss] + <> help + where + help = ["use " <> highlight ("/sync #" <> groupName' g <> " " <> n) <> " to synchronize" | rss `elem` [RSAllowed, RSRequired]] + +viewContactVerificationReset :: Contact -> [StyledString] +viewContactVerificationReset ct = + [ttyContact' ct <> ": security code changed"] + +viewGroupMemberVerificationReset :: GroupInfo -> GroupMember -> [StyledString] +viewGroupMemberVerificationReset g m = + [ttyGroup' g <> " " <> ttyMember m <> ": security code changed"] + viewContactCode :: Contact -> Text -> Bool -> [StyledString] viewContactCode ct@Contact {localDisplayName = c} = viewSecurityCode (ttyContact' ct) ("/verify " <> c <> " ") diff --git a/stack.yaml b/stack.yaml index 07fe72bfaa..f0cc34fadd 100644 --- a/stack.yaml +++ b/stack.yaml @@ -49,7 +49,7 @@ extra-deps: # - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561 # - ../simplexmq - github: simplex-chat/simplexmq - commit: fe22d9b299f106fc4a3d167e90499ddb4d3bfa26 + commit: f2657f9c0b954f952aaf381bb9b55ac34ea59ed7 - github: kazu-yamamoto/http2 commit: b5a1b7200cf5bc7044af34ba325284271f6dff25 # - ../direct-sqlcipher diff --git a/tests/ChatTests/Direct.hs b/tests/ChatTests/Direct.hs index 941fa2aff2..beba5aeeaa 100644 --- a/tests/ChatTests/Direct.hs +++ b/tests/ChatTests/Direct.hs @@ -86,7 +86,9 @@ chatDirectTests = do it "mark contact verified" testMarkContactVerified it "mark group member verified" testMarkGroupMemberVerified describe "message errors" $ do - xit "show message decryption error and update count" testMsgDecryptError + it "show message decryption error" testMsgDecryptError + it "should report ratchet de-synchronization, synchronize ratchets" testSyncRatchet + it "synchronize ratchets, reset connection code" testSyncRatchetCodeReset describe "message reactions" $ do it "set message reactions" testSetMessageReactions @@ -1995,43 +1997,124 @@ testMsgDecryptError tmp = bob <# "alice> hi" bob #> "@alice hey" alice <# "bob> hey" - copyDb "bob" "bob_old" - withTestChat tmp "bob" $ \bob -> do - bob <## "1 contacts connected (use /cs for the list)" - alice #> "@bob hello" - bob <# "alice> hello" - bob #> "@alice hello too" - alice <# "bob> hello too" - withTestChat tmp "bob_old" $ \bob -> do - bob <## "1 contacts connected (use /cs for the list)" - alice #> "@bob 1" - bob <# "alice> decryption error, possibly due to the device change (header)" - alice #> "@bob 2" - alice #> "@bob 3" - (bob "/tail @alice 1" - bob <# "alice> decryption error, possibly due to the device change (header, 3 messages)" - bob #> "@alice 1" - alice <# "bob> decryption error, possibly due to the device change (header)" - bob #> "@alice 2" - bob #> "@alice 3" - (alice "/tail @bob 1" - alice <# "bob> decryption error, possibly due to the device change (header, 3 messages)" - alice #> "@bob 4" - bob <# "alice> decryption error, possibly due to the device change (header)" + setupDesynchronizedRatchet tmp alice withTestChat tmp "bob" $ \bob -> do bob <## "1 contacts connected (use /cs for the list)" alice #> "@bob hello again" - bob <# "alice> skipped message ID 5..8" + bob <# "alice> skipped message ID 5..7" bob <# "alice> hello again" bob #> "@alice received!" alice <# "bob> received!" + +setupDesynchronizedRatchet :: HasCallStack => FilePath -> TestCC -> IO () +setupDesynchronizedRatchet tmp alice = do + copyDb "bob" "bob_old" + withTestChat tmp "bob" $ \bob -> do + bob <## "1 contacts connected (use /cs for the list)" + alice #> "@bob hello" + bob <# "alice> hello" + bob #> "@alice hello too" + alice <# "bob> hello too" + withTestChat tmp "bob_old" $ \bob -> do + bob <## "1 contacts connected (use /cs for the list)" + bob ##> "/sync alice" + bob <## "error: command is prohibited" + alice #> "@bob 1" + bob <## "alice: decryption error (connection out of sync), synchronization required" + bob <## "use /sync alice to synchronize" + alice #> "@bob 2" + alice #> "@bob 3" + (bob "/tail @alice 1" + bob <# "alice> decryption error, possibly due to the device change (header, 3 messages)" + bob ##> "@alice 1" + bob <## "error: command is prohibited" + (alice from) (chatStoreFile $ tmp to) copyFile (agentStoreFile $ tmp from) (agentStoreFile $ tmp to) +testSyncRatchet :: HasCallStack => FilePath -> IO () +testSyncRatchet tmp = + withNewTestChat tmp "alice" aliceProfile $ \alice -> do + withNewTestChat tmp "bob" bobProfile $ \bob -> do + connectUsers alice bob + alice #> "@bob hi" + bob <# "alice> hi" + bob #> "@alice hey" + alice <# "bob> hey" + setupDesynchronizedRatchet tmp alice + withTestChat tmp "bob_old" $ \bob -> do + bob <## "1 contacts connected (use /cs for the list)" + bob ##> "/sync alice" + bob <## "connection synchronization started" + alice <## "bob: connection synchronization agreed" + bob <## "alice: connection synchronization agreed" + alice <## "bob: connection synchronized" + bob <## "alice: connection synchronized" + + bob #$> ("/_get chat @2 count=3", chat, [(1, "connection synchronization started"), (0, "connection synchronization agreed"), (0, "connection synchronized")]) + alice #$> ("/_get chat @2 count=2", chat, [(0, "connection synchronization agreed"), (0, "connection synchronized")]) + + alice #> "@bob hello again" + bob <# "alice> hello again" + bob #> "@alice received!" + alice <# "bob> received!" + +testSyncRatchetCodeReset :: HasCallStack => FilePath -> IO () +testSyncRatchetCodeReset tmp = + withNewTestChat tmp "alice" aliceProfile $ \alice -> do + withNewTestChat tmp "bob" bobProfile $ \bob -> do + connectUsers alice bob + alice #> "@bob hi" + bob <# "alice> hi" + bob #> "@alice hey" + alice <# "bob> hey" + -- connection not verified + bob ##> "/i alice" + aliceInfo bob + bob <## "connection not verified, use /code command to see security code" + -- verify connection + alice ##> "/code bob" + bCode <- getTermLine alice + bob ##> ("/verify alice " <> bCode) + bob <## "connection verified" + -- connection verified + bob ##> "/i alice" + aliceInfo bob + bob <## "connection verified" + setupDesynchronizedRatchet tmp alice + withTestChat tmp "bob_old" $ \bob -> do + bob <## "1 contacts connected (use /cs for the list)" + bob ##> "/sync alice" + bob <## "connection synchronization started" + alice <## "bob: connection synchronization agreed" + bob <## "alice: connection synchronization agreed" + bob <## "alice: security code changed" + alice <## "bob: connection synchronized" + bob <## "alice: connection synchronized" + + bob #$> ("/_get chat @2 count=4", chat, [(1, "connection synchronization started"), (0, "connection synchronization agreed"), (0, "security code changed"), (0, "connection synchronized")]) + alice #$> ("/_get chat @2 count=2", chat, [(0, "connection synchronization agreed"), (0, "connection synchronized")]) + + -- connection not verified + bob ##> "/i alice" + aliceInfo bob + bob <## "connection not verified, use /code command to see security code" + + alice #> "@bob hello again" + bob <# "alice> hello again" + bob #> "@alice received!" + alice <# "bob> received!" + where + aliceInfo :: HasCallStack => TestCC -> IO () + aliceInfo bob = do + bob <## "contact ID: 2" + bob <## "receiving messages via: localhost" + bob <## "sending messages via: localhost" + bob <## "you've shared main profile with this contact" + testSetMessageReactions :: HasCallStack => FilePath -> IO () testSetMessageReactions = testChat2 aliceProfile bobProfile $ diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 1e724ce007..1c36f7e1dc 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -56,7 +56,9 @@ chatGroupTests = do it "group link member role" testGroupLinkMemberRole it "leaving and deleting the group joined via link should NOT delete previously existing direct contacts" testGroupLinkLeaveDelete describe "group message errors" $ do - xit "show message decryption error and update count" testGroupMsgDecryptError + it "show message decryption error" testGroupMsgDecryptError + it "should report ratchet de-synchronization, synchronize ratchets" testGroupSyncRatchet + it "synchronize ratchets, reset connection code" testGroupSyncRatchetCodeReset describe "message reactions" $ do it "set group message reactions" testSetGroupMessageReactions @@ -2200,68 +2202,152 @@ testGroupMsgDecryptError tmp = [bob, cath] *<# "#team alice> hi" bob #> "#team hey" [alice, cath] *<# "#team bob> hey" - copyDb "bob" "bob_old" - withTestChat tmp "bob" $ \bob -> do - bob <## "2 contacts connected (use /cs for the list)" - bob <## "#team: connected to server(s)" - alice #> "#team hello" - [bob, cath] *<# "#team alice> hello" - bob #> "#team hello too" - [alice, cath] *<# "#team bob> hello too" - withTestChat tmp "bob_old" $ \bob -> do - bob <## "2 contacts connected (use /cs for the list)" - bob <## "#team: connected to server(s)" - alice #> "#team 1" - bob <# "#team alice> decryption error, possibly due to the device change (header)" - cath <# "#team alice> 1" - alice #> "#team 2" - cath <# "#team alice> 2" - alice #> "#team 3" - cath <# "#team alice> 3" - (bob "/tail #team 1" - bob <# "#team alice> decryption error, possibly due to the device change (header, 3 messages)" - bob #> "#team 1" - alice <# "#team bob> decryption error, possibly due to the device change (header)" - -- cath <# "#team bob> 1" - bob #> "#team 2" - cath <# "#team bob> incorrect message hash" - cath <# "#team bob> 2" - bob #> "#team 3" - cath <# "#team bob> 3" - (alice "/tail #team 1" - alice <# "#team bob> decryption error, possibly due to the device change (header, 3 messages)" - alice #> "#team 4" - (bob 4" - bob ##> "/tail #team 4" - bob - <##? [ "#team alice> decryption error, possibly due to the device change (header, 4 messages)", - "#team 1", - "#team 2", - "#team 3" - ] + setupDesynchronizedRatchet tmp alice cath withTestChat tmp "bob" $ \bob -> do bob <## "2 contacts connected (use /cs for the list)" bob <## "#team: connected to server(s)" alice #> "#team hello again" - bob <# "#team alice> skipped message ID 8..11" + bob <# "#team alice> skipped message ID 8..10" [bob, cath] *<# "#team alice> hello again" bob #> "#team received!" alice <# "#team bob> received!" - bob #> "#team 4" - alice <# "#team bob> 4" - bob #> "#team 5" - cath <# "#team bob> incorrect message hash" - [alice, cath] *<# "#team bob> 5" - bob #> "#team 6" - [alice, cath] *<# "#team bob> 6" + cath <# "#team bob> received!" + +setupDesynchronizedRatchet :: HasCallStack => FilePath -> TestCC -> TestCC -> IO () +setupDesynchronizedRatchet tmp alice cath = do + copyDb "bob" "bob_old" + withTestChat tmp "bob" $ \bob -> do + bob <## "2 contacts connected (use /cs for the list)" + bob <## "#team: connected to server(s)" + alice #> "#team hello" + [bob, cath] *<# "#team alice> hello" + bob #> "#team hello too" + [alice, cath] *<# "#team bob> hello too" + withTestChat tmp "bob_old" $ \bob -> do + bob <## "2 contacts connected (use /cs for the list)" + bob <## "#team: connected to server(s)" + bob ##> "/sync #team alice" + bob <## "error: command is prohibited" + alice #> "#team 1" + bob <## "#team alice: decryption error (connection out of sync), synchronization required" + bob <## "use /sync #team alice to synchronize" + cath <# "#team alice> 1" + alice #> "#team 2" + cath <# "#team alice> 2" + alice #> "#team 3" + cath <# "#team alice> 3" + (bob "/tail #team 1" + bob <# "#team alice> decryption error, possibly due to the device change (header, 3 messages)" where copyDb from to = do copyFile (chatStoreFile $ tmp from) (chatStoreFile $ tmp to) copyFile (agentStoreFile $ tmp from) (agentStoreFile $ tmp to) +testGroupSyncRatchet :: HasCallStack => FilePath -> IO () +testGroupSyncRatchet tmp = + withNewTestChat tmp "alice" aliceProfile $ \alice -> do + withNewTestChat tmp "cath" cathProfile $ \cath -> do + withNewTestChat tmp "bob" bobProfile $ \bob -> do + createGroup3 "team" alice bob cath + alice #> "#team hi" + [bob, cath] *<# "#team alice> hi" + bob #> "#team hey" + [alice, cath] *<# "#team bob> hey" + setupDesynchronizedRatchet tmp alice cath + withTestChat tmp "bob_old" $ \bob -> do + bob <## "2 contacts connected (use /cs for the list)" + bob <## "#team: connected to server(s)" + -- cath and bob are not fully de-synchronized + bob `send` "#team 1" + bob <## "error: command is prohibited" -- silence? + bob <# "#team 1" + (alice "#team 1" + [alice, bob] *<# "#team cath> 1" + bob `send` "#team 2" + bob <## "error: command is prohibited" + bob <# "#team 2" + cath <# "#team bob> incorrect message hash" + cath <# "#team bob> 2" + bob `send` "#team 3" + bob <## "error: command is prohibited" + bob <# "#team 3" + cath <# "#team bob> 3" + -- synchronize bob and alice + bob ##> "/sync #team alice" + bob <## "connection synchronization started" + alice <## "#team bob: connection synchronization agreed" + bob <## "#team alice: connection synchronization agreed" + alice <## "#team bob: connection synchronized" + bob <## "#team alice: connection synchronized" + + bob #$> ("/_get chat #1 count=3", chat, [(1, "connection synchronization started for alice"), (0, "connection synchronization agreed"), (0, "connection synchronized")]) + alice #$> ("/_get chat #1 count=2", chat, [(0, "connection synchronization agreed"), (0, "connection synchronized")]) + + alice #> "#team hello again" + [bob, cath] *<# "#team alice> hello again" + bob #> "#team received!" + alice <# "#team bob> received!" + cath <# "#team bob> received!" + +testGroupSyncRatchetCodeReset :: HasCallStack => FilePath -> IO () +testGroupSyncRatchetCodeReset tmp = + withNewTestChat tmp "alice" aliceProfile $ \alice -> do + withNewTestChat tmp "cath" cathProfile $ \cath -> do + withNewTestChat tmp "bob" bobProfile $ \bob -> do + createGroup3 "team" alice bob cath + alice #> "#team hi" + [bob, cath] *<# "#team alice> hi" + bob #> "#team hey" + [alice, cath] *<# "#team bob> hey" + -- connection not verified + bob ##> "/i #team alice" + aliceInfo bob + bob <## "connection not verified, use /code command to see security code" + -- verify connection + alice ##> "/code #team bob" + bCode <- getTermLine alice + bob ##> ("/verify #team alice " <> bCode) + bob <## "connection verified" + -- connection verified + bob ##> "/i #team alice" + aliceInfo bob + bob <## "connection verified" + setupDesynchronizedRatchet tmp alice cath + withTestChat tmp "bob_old" $ \bob -> do + bob <## "2 contacts connected (use /cs for the list)" + bob <## "#team: connected to server(s)" + bob ##> "/sync #team alice" + bob <## "connection synchronization started" + alice <## "#team bob: connection synchronization agreed" + bob <## "#team alice: connection synchronization agreed" + bob <## "#team alice: security code changed" + alice <## "#team bob: connection synchronized" + bob <## "#team alice: connection synchronized" + + bob #$> ("/_get chat #1 count=4", chat, [(1, "connection synchronization started for alice"), (0, "connection synchronization agreed"), (0, "security code changed"), (0, "connection synchronized")]) + alice #$> ("/_get chat #1 count=2", chat, [(0, "connection synchronization agreed"), (0, "connection synchronized")]) + + -- connection not verified + bob ##> "/i #team alice" + aliceInfo bob + bob <## "connection not verified, use /code command to see security code" + + alice #> "#team hello again" + [bob, cath] *<# "#team alice> hello again" + bob #> "#team received!" + alice <# "#team bob> received!" + (cath TestCC -> IO () + aliceInfo bob = do + bob <## "group ID: 1" + bob <## "member ID: 1" + bob <## "receiving messages via: localhost" + bob <## "sending messages via: localhost" + testSetGroupMessageReactions :: HasCallStack => FilePath -> IO () testSetGroupMessageReactions = testChat3 aliceProfile bobProfile cathProfile $