├── .github ├── dependabot.yaml └── workflows │ ├── dart.yml │ └── manual-build.yml ├── .gitignore ├── .metadata ├── .vscode ├── launch.json └── settings.json ├── AppImageBuilder.yml ├── LICENSE ├── README.md ├── agen.sh ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutter_app │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties └── settings.gradle ├── assets ├── captcha.html ├── fonts │ └── iconfont.ttf ├── icons │ ├── macos_app_icon.png │ └── windows_app_icon.png └── images │ ├── about_logo.png │ ├── account.svg │ ├── add_sticker.svg │ ├── app_button.svg │ ├── attachment_download.svg │ ├── audio.svg │ ├── audio_play.svg │ ├── audio_stop.svg │ ├── bg_snapshot.svg │ ├── bot.svg │ ├── bot_fill.svg │ ├── chat.svg │ ├── chat_background.png │ ├── chat_backup.svg │ ├── chat_pin.svg │ ├── chat_small.svg │ ├── checked.svg │ ├── circle.svg │ ├── circle_add.svg │ ├── circle_remove.svg │ ├── close_oval.svg │ ├── close_oval_record.svg │ ├── collapse.svg │ ├── collection_placeholder.svg │ ├── contact.svg │ ├── context_menu_copy.svg │ ├── context_menu_create_conversation.svg │ ├── context_menu_create_group.svg │ ├── context_menu_delete.svg │ ├── context_menu_forward.svg │ ├── context_menu_link.svg │ ├── context_menu_search_user.svg │ ├── copy.svg │ ├── delete.svg │ ├── delete_account.svg │ ├── delivered.svg │ ├── device_transfer.svg │ ├── disappearing_message.svg │ ├── download.svg │ ├── edit_image.svg │ ├── edit_image_clip.svg │ ├── edit_image_draw.svg │ ├── edit_image_erase.svg │ ├── edit_image_flip.svg │ ├── edit_image_redo.svg │ ├── edit_image_rotate.svg │ ├── edit_image_undo.svg │ ├── ellipsis.svg │ ├── emoji_animal.svg │ ├── emoji_face.svg │ ├── emoji_flags.svg │ ├── emoji_food.svg │ ├── emoji_objects.svg │ ├── emoji_recent.svg │ ├── emoji_sports.svg │ ├── emoji_sticker.svg │ ├── emoji_symbol.svg │ ├── emoji_travel.svg │ ├── empty_file.svg │ ├── empty_image.svg │ ├── exclamation_mark.svg │ ├── expanded.svg │ ├── expiring.svg │ ├── expiring_dark.svg │ ├── external_link.svg │ ├── failed.svg │ ├── file.svg │ ├── file_preview_files.svg │ ├── file_preview_images.svg │ ├── file_preview_zip.svg │ ├── filter_unseen.svg │ ├── gif_sticker.svg │ ├── group.svg │ ├── ic_about.svg │ ├── ic_add.svg │ ├── ic_appearance.svg │ ├── ic_arrow_right.svg │ ├── ic_back.svg │ ├── ic_backup.svg │ ├── ic_close.svg │ ├── ic_close_big.svg │ ├── ic_file.svg │ ├── ic_forward.svg │ ├── ic_notification.svg │ ├── ic_profile.svg │ ├── ic_retry.svg │ ├── ic_screen.svg │ ├── ic_search.svg │ ├── ic_search_small.svg │ ├── ic_send.svg │ ├── ic_sign_out.svg │ ├── ic_sticker.svg │ ├── ic_storage_usage.svg │ ├── image.svg │ ├── information.svg │ ├── inscription_placeholder.svg │ ├── invite_copy.svg │ ├── invite_refresh.svg │ ├── invite_share.svg │ ├── jump_current_arrow.svg │ ├── link_send.svg │ ├── live.svg │ ├── location.svg │ ├── location_mark.svg │ ├── lock.svg │ ├── logo.png │ ├── message_pin.svg │ ├── message_representative.svg │ ├── message_secret.svg │ ├── message_transcript_forward.svg │ ├── microphone.svg │ ├── mute.svg │ ├── next.svg │ ├── no_result.svg │ ├── notify_icon.ico │ ├── personal_sticker.svg │ ├── pin.svg │ ├── pin_arrow.svg │ ├── plan_basic.png │ ├── plan_premium.gif │ ├── plan_standard.png │ ├── play.svg │ ├── player_pause.svg │ ├── player_play.svg │ ├── post_detail.svg │ ├── prev.svg │ ├── proxy.svg │ ├── read.svg │ ├── recall.svg │ ├── recent_sticker.svg │ ├── record_preview_play.svg │ ├── record_preview_stop.svg │ ├── record_retry.svg │ ├── record_stop.svg │ ├── rotato.svg │ ├── selected.svg │ ├── sent.svg │ ├── setting.svg │ ├── share.svg │ ├── shield.svg │ ├── slide_contacts.svg │ ├── small_close.svg │ ├── snapshot_done.svg │ ├── sticker.svg │ ├── sticker_gif.svg │ ├── sticker_store.svg │ ├── sticker_store_red_dot.svg │ ├── strangers.svg │ ├── successful.svg │ ├── text_bg.png │ ├── transfer.svg │ ├── transfer_from_phone.svg │ ├── transfer_to_phone.svg │ ├── triangle_warning.svg │ ├── upload.svg │ ├── user_search.svg │ ├── verified.svg │ ├── video.svg │ ├── video_call.svg │ ├── video_message.svg │ ├── warning.svg │ ├── web_view_refresh.svg │ ├── zoom_in.svg │ └── zoom_out.svg ├── build.yaml ├── db_generate.sh ├── dist ├── appdmg.json ├── bg.png ├── deb │ ├── DEBIAN │ │ └── control │ └── usr │ │ └── share │ │ ├── applications │ │ └── mixin_desktop.desktop │ │ └── icons │ │ └── hicolor │ │ ├── 128x128 │ │ └── apps │ │ │ └── mixin_desktop.png │ │ └── 256x256 │ │ └── apps │ │ └── mixin_desktop.png ├── exe │ └── ChineseSimplified.isl ├── linux_deb.sh ├── linux_snap_prepare.sh ├── mac_app_icon.png ├── macos.sh ├── screenshots │ ├── linux_1.png │ ├── linux_2.png │ ├── linux_3.png │ └── linux_4.png ├── snap │ └── snap │ │ ├── gui │ │ ├── mixin-desktop.desktop │ │ └── mixin-desktop.png │ │ └── snapcraft.yaml └── win.sh ├── flow.dio ├── fonts ├── Noto-COLRv1.ttf └── mixin_font.otf ├── generate.sh ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── ephemeral │ │ ├── flutter_lldb_helper.py │ │ └── flutter_lldbinit ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── 1024.png │ │ ├── 20.png │ │ ├── 20@2x-1.png │ │ ├── 20@2x.png │ │ ├── 20@3x.png │ │ ├── 29-1.png │ │ ├── 29.png │ │ ├── 29@2x-1.png │ │ ├── 29@2x.png │ │ ├── 29@3x.png │ │ ├── 40.png │ │ ├── 40@2x-1.png │ │ ├── 40@2x.png │ │ ├── 40@3x.png │ │ ├── 60@2x.png │ │ ├── 60@3x.png │ │ ├── 76.png │ │ ├── 76@2x.png │ │ ├── 83.5@2x.png │ │ └── Contents.json │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── Runner-Bridging-Header.h │ └── mixin.caf ├── lib ├── account │ ├── account_key_value.dart │ ├── account_server.dart │ ├── notification_service.dart │ ├── scam_warning_key_value.dart │ ├── security_key_value.dart │ ├── send_message_helper.dart │ ├── session_key_value.dart │ └── show_pin_message_key_value.dart ├── api │ ├── giphy_api.dart │ └── giphy_vo │ │ ├── giphy_gif.dart │ │ ├── giphy_gif.g.dart │ │ ├── giphy_image.dart │ │ ├── giphy_image.g.dart │ │ ├── giphy_image_set.dart │ │ ├── giphy_image_set.g.dart │ │ ├── giphy_result_data.dart │ │ └── giphy_result_data.g.dart ├── app.dart ├── blaze │ ├── blaze.dart │ ├── blaze_message.dart │ ├── blaze_message.g.dart │ ├── blaze_message_param.dart │ ├── blaze_message_param.g.dart │ ├── blaze_message_param_session.dart │ ├── blaze_message_param_session.g.dart │ ├── blaze_signal_key_message.dart │ ├── blaze_signal_key_message.g.dart │ └── vo │ │ ├── message_result.dart │ │ ├── one_time_pre_key.dart │ │ ├── one_time_pre_key.g.dart │ │ ├── pin_message_minimal.dart │ │ ├── pin_message_minimal.g.dart │ │ ├── pin_message_payload.dart │ │ ├── pin_message_payload.g.dart │ │ ├── plain_json_message.dart │ │ ├── plain_json_message.g.dart │ │ ├── recall_message.dart │ │ ├── recall_message.g.dart │ │ ├── sender_key_status.dart │ │ ├── signal_key.dart │ │ ├── signal_key.g.dart │ │ ├── signed_pre_key.dart │ │ ├── signed_pre_key.g.dart │ │ ├── snapshot_message.dart │ │ ├── snapshot_message.g.dart │ │ ├── system_circle_message.dart │ │ ├── system_circle_message.g.dart │ │ ├── system_conversation_message.dart │ │ ├── system_conversation_message.g.dart │ │ ├── system_session_message.dart │ │ ├── system_session_message.g.dart │ │ ├── system_user_message.dart │ │ ├── system_user_message.g.dart │ │ ├── transcript_minimal.dart │ │ └── transcript_minimal.g.dart ├── bloc │ ├── bloc_converter.dart │ ├── custom_bloc_observer.dart │ ├── paging │ │ ├── load_more_paging_state.dart │ │ └── paging_bloc.dart │ ├── simple_cubit.dart │ ├── stream_cubit.dart │ └── subscribe_mixin.dart ├── constants │ ├── brightness_theme_data.dart │ ├── constants.dart │ ├── env.dart │ ├── icon_fonts.dart │ └── resources.dart ├── crypto │ ├── attachment │ │ └── crypto_attachment.dart │ ├── crypto_key_value.dart │ ├── encrypted │ │ └── encrypted_protocol.dart │ ├── privacy_key_value.dart │ ├── signal │ │ ├── dao │ │ │ ├── identity_dao.dart │ │ │ ├── identity_dao.g.dart │ │ │ ├── pre_key_dao.dart │ │ │ ├── pre_key_dao.g.dart │ │ │ ├── ratchet_sender_key_dao.dart │ │ │ ├── ratchet_sender_key_dao.g.dart │ │ │ ├── sender_key_dao.dart │ │ │ ├── sender_key_dao.g.dart │ │ │ ├── session_dao.dart │ │ │ ├── session_dao.g.dart │ │ │ ├── signed_pre_key_dao.dart │ │ │ └── signed_pre_key_dao.g.dart │ │ ├── encrypt_result.dart │ │ ├── identity_extension.dart │ │ ├── identity_key_util.dart │ │ ├── moor │ │ │ ├── dao │ │ │ │ ├── identity.drift │ │ │ │ ├── pre_key.drift │ │ │ │ ├── ratchet_sender_key.drift │ │ │ │ ├── sender_key.drift │ │ │ │ ├── session.drift │ │ │ │ └── signed_pre_key.drift │ │ │ └── signal.drift │ │ ├── pre_key_util.dart │ │ ├── ratchet_status.dart │ │ ├── signal_database.dart │ │ ├── signal_database.g.dart │ │ ├── signal_key_request.dart │ │ ├── signal_key_request.g.dart │ │ ├── signal_key_util.dart │ │ ├── signal_protocol.dart │ │ └── storage │ │ │ ├── mixin_identity_key_store.dart │ │ │ ├── mixin_prekey_store.dart │ │ │ ├── mixin_sender_key_store.dart │ │ │ ├── mixin_session_store.dart │ │ │ └── mixin_signal_protocol_store.dart │ └── uuid │ │ └── uuid.dart ├── db │ ├── converter │ │ ├── conversation_category_type_converter.dart │ │ ├── conversation_status_type_converter.dart │ │ ├── media_status_type_converter.dart │ │ ├── membership_converter.dart │ │ ├── message_status_type_converter.dart │ │ ├── millis_date_converter.dart │ │ ├── participant_role_converter.dart │ │ ├── property_group_converter.dart │ │ ├── safe_deposit_type_converter.dart │ │ ├── safe_withdrawal_type_converter.dart │ │ ├── user_relationship_converter.dart │ │ └── utc_value_serializer.dart │ ├── custom_sqlite3_database.dart │ ├── dao │ │ ├── address_dao.dart │ │ ├── address_dao.g.dart │ │ ├── app_dao.dart │ │ ├── app_dao.g.dart │ │ ├── asset_dao.dart │ │ ├── asset_dao.g.dart │ │ ├── chain_dao.dart │ │ ├── chain_dao.g.dart │ │ ├── circle_conversation_dao.dart │ │ ├── circle_conversation_dao.g.dart │ │ ├── circle_dao.dart │ │ ├── circle_dao.g.dart │ │ ├── conversation_dao.dart │ │ ├── conversation_dao.g.dart │ │ ├── expired_message_dao.dart │ │ ├── expired_message_dao.g.dart │ │ ├── favorite_app_dao.dart │ │ ├── favorite_app_dao.g.dart │ │ ├── fiat_dao.dart │ │ ├── fiat_dao.g.dart │ │ ├── flood_message_dao.dart │ │ ├── flood_message_dao.g.dart │ │ ├── hyperlink_dao.dart │ │ ├── hyperlink_dao.g.dart │ │ ├── inscription_collection_dao.dart │ │ ├── inscription_collection_dao.g.dart │ │ ├── inscription_item_dao.dart │ │ ├── inscription_item_dao.g.dart │ │ ├── job_dao.dart │ │ ├── job_dao.g.dart │ │ ├── message_dao.dart │ │ ├── message_dao.g.dart │ │ ├── message_history_dao.dart │ │ ├── message_history_dao.g.dart │ │ ├── message_mention_dao.dart │ │ ├── message_mention_dao.g.dart │ │ ├── offset_dao.dart │ │ ├── offset_dao.g.dart │ │ ├── participant_dao.dart │ │ ├── participant_dao.g.dart │ │ ├── participant_session_dao.dart │ │ ├── participant_session_dao.g.dart │ │ ├── pin_message_dao.dart │ │ ├── pin_message_dao.g.dart │ │ ├── property_dao.dart │ │ ├── property_dao.g.dart │ │ ├── resend_session_message_dao.dart │ │ ├── resend_session_message_dao.g.dart │ │ ├── safe_snapshot_dao.dart │ │ ├── safe_snapshot_dao.g.dart │ │ ├── sent_session_sender_key_dao.dart │ │ ├── sent_session_sender_key_dao.g.dart │ │ ├── snapshot_dao.dart │ │ ├── snapshot_dao.g.dart │ │ ├── sticker_album_dao.dart │ │ ├── sticker_album_dao.g.dart │ │ ├── sticker_dao.dart │ │ ├── sticker_dao.g.dart │ │ ├── sticker_relationship_dao.dart │ │ ├── sticker_relationship_dao.g.dart │ │ ├── token_dao.dart │ │ ├── token_dao.g.dart │ │ ├── transcript_message_dao.dart │ │ ├── transcript_message_dao.g.dart │ │ ├── user_dao.dart │ │ └── user_dao.g.dart │ ├── database.dart │ ├── database_event_bus.dart │ ├── event.dart │ ├── extension │ │ ├── app.dart │ │ ├── conversation.dart │ │ ├── db.dart │ │ ├── job.dart │ │ ├── message.dart │ │ ├── message_category.dart │ │ └── user.dart │ ├── fts_database.dart │ ├── fts_database.g.dart │ ├── mixin_database.dart │ ├── mixin_database.g.dart │ ├── moor │ │ ├── dao │ │ │ ├── asset.drift │ │ │ ├── chain.drift │ │ │ ├── circle.drift │ │ │ ├── circle_conversation.drift │ │ │ ├── common.drift │ │ │ ├── conversation.drift │ │ │ ├── expired_message.drift │ │ │ ├── favorite_app.drift │ │ │ ├── flood.drift │ │ │ ├── inscription_collection.drift │ │ │ ├── inscription_item.drift │ │ │ ├── message.drift │ │ │ ├── participant.drift │ │ │ ├── participant_session.drift │ │ │ ├── pin_message.drift │ │ │ ├── property.drift │ │ │ ├── safe_snapshot.drift │ │ │ ├── snapshot.drift │ │ │ ├── sticker.drift │ │ │ ├── sticker_album.drift │ │ │ ├── sticker_relationship.drift │ │ │ ├── token.drift │ │ │ ├── transcript_message.drift │ │ │ └── user.drift │ │ ├── fts.drift │ │ └── mixin.drift │ ├── util │ │ ├── open_database.dart │ │ ├── property_storage.dart │ │ └── util.dart │ └── vo │ │ ├── inscription.dart │ │ └── inscription.g.dart ├── enum │ ├── encrypt_category.dart │ ├── media_status.dart │ ├── message_action.dart │ ├── message_category.dart │ ├── property_group.dart │ ├── system_circle_action.dart │ ├── system_session_action.dart │ └── system_user_action.dart ├── generated │ ├── intl │ │ ├── messages_all.dart │ │ ├── messages_en.dart │ │ ├── messages_es.dart │ │ ├── messages_in.dart │ │ ├── messages_ja.dart │ │ ├── messages_ms.dart │ │ ├── messages_ru.dart │ │ ├── messages_zh-HK.dart │ │ ├── messages_zh-TW.dart │ │ └── messages_zh.dart │ └── l10n.dart ├── l10n │ ├── intl_en.arb │ ├── intl_es.arb │ ├── intl_in.arb │ ├── intl_ja.arb │ ├── intl_ms.arb │ ├── intl_ru.arb │ ├── intl_zh-HK.arb │ ├── intl_zh-TW.arb │ └── intl_zh.arb ├── main.dart ├── ui │ ├── home │ │ ├── bloc │ │ │ ├── blink_cubit.dart │ │ │ ├── conversation_list_bloc.dart │ │ │ ├── message_bloc.dart │ │ │ ├── search_message_cubit.dart │ │ │ └── subscriber_mixin.dart │ │ ├── chat │ │ │ ├── chat_bar.dart │ │ │ ├── chat_page.dart │ │ │ ├── files_preview.dart │ │ │ ├── image_caption_input.dart │ │ │ ├── image_editor.dart │ │ │ ├── input_container.dart │ │ │ ├── selection_bottom_bar.dart │ │ │ └── voice_recorder_bottom_bar.dart │ │ ├── chat_slide_page │ │ │ ├── chat_info_page.dart │ │ │ ├── circle_manager_page.dart │ │ │ ├── disappear_message_page.dart │ │ │ ├── group_invite │ │ │ │ └── group_invite_dialog.dart │ │ │ ├── group_participants_page.dart │ │ │ ├── groups_in_common_page.dart │ │ │ ├── pin_messages_page.dart │ │ │ ├── search_message_page.dart │ │ │ ├── share_media │ │ │ │ ├── file_page.dart │ │ │ │ ├── media_page.dart │ │ │ │ └── post_page.dart │ │ │ ├── shared_apps_page.dart │ │ │ └── shared_media_page.dart │ │ ├── command_palette_wrapper.dart │ │ ├── conversation │ │ │ ├── audio_player_bar.dart │ │ │ ├── conversation_hotkey.dart │ │ │ ├── conversation_list.dart │ │ │ ├── conversation_page.dart │ │ │ ├── menu_wrapper.dart │ │ │ ├── network_status.dart │ │ │ ├── search_list.dart │ │ │ └── unseen_conversation_list.dart │ │ ├── home.dart │ │ ├── hook │ │ │ └── pin_message.dart │ │ ├── intent.dart │ │ ├── route │ │ │ └── responsive_navigator.dart │ │ └── slide_page.dart │ ├── landing │ │ ├── bloc │ │ │ ├── landing_cubit.dart │ │ │ └── landing_state.dart │ │ ├── landing.dart │ │ ├── landing_failed.dart │ │ ├── landing_mobile.dart │ │ └── landing_qrcode.dart │ ├── provider │ │ ├── abstract_responsive_navigator.dart │ │ ├── account_server_provider.dart │ │ ├── conversation_provider.dart │ │ ├── conversation_unseen_filter_enabled.dart │ │ ├── database_provider.dart │ │ ├── is_bot_group_provider.dart │ │ ├── keyword_provider.dart │ │ ├── mention_cache_provider.dart │ │ ├── mention_provider.dart │ │ ├── message_selection_provider.dart │ │ ├── minute_timer_provider.dart │ │ ├── multi_auth_provider.dart │ │ ├── pending_jump_message_provider.dart │ │ ├── quote_message_provider.dart │ │ ├── recall_message_reedit_provider.dart │ │ ├── recent_conversation_provider.dart │ │ ├── responsive_navigator_provider.dart │ │ ├── search_mao_user_provider.dart │ │ ├── setting_provider.dart │ │ ├── slide_category_provider.dart │ │ ├── transfer_provider.dart │ │ ├── unseen_conversations_provider.dart │ │ └── user_cache_provider.dart │ └── setting │ │ ├── about_page.dart │ │ ├── account_delete_page.dart │ │ ├── account_page.dart │ │ ├── appearance_page.dart │ │ ├── backup_page.dart │ │ ├── edit_profile_page.dart │ │ ├── log_page.dart │ │ ├── notification_page.dart │ │ ├── proxy_page.dart │ │ ├── security_page.dart │ │ ├── setting_page.dart │ │ ├── storage_page.dart │ │ ├── storage_usage_detail_page.dart │ │ └── storage_usage_list_page.dart ├── utils │ ├── action_utils.dart │ ├── app_lifecycle.dart │ ├── attachment │ │ ├── attachment_download_job.dart │ │ ├── attachment_upload_job.dart │ │ ├── attachment_util.dart │ │ └── download_key_value.dart │ ├── audio_message_player │ │ ├── audio_message_player.dart │ │ ├── audio_message_service.dart │ │ └── ogg_opus_audio_player.dart │ ├── authentication.dart │ ├── auto_update_checker.dart │ ├── cache_client.dart │ ├── color_utils.dart │ ├── context_menu_image.dart │ ├── crypto │ │ ├── aes.dart │ │ ├── hmac.dart │ │ └── web_crypto.dart │ ├── crypto_util.dart │ ├── datetime_format_utils.dart │ ├── device_transfer │ │ ├── cipher.dart │ │ ├── device_transfer_dialog.dart │ │ ├── device_transfer_receiver.dart │ │ ├── device_transfer_sender.dart │ │ ├── device_transfer_widget.dart │ │ ├── json_transfer_data.dart │ │ ├── json_transfer_data.g.dart │ │ ├── socket_wrapper.dart │ │ ├── speed_calculator.dart │ │ ├── transfer_data_app.dart │ │ ├── transfer_data_app.g.dart │ │ ├── transfer_data_asset.dart │ │ ├── transfer_data_asset.g.dart │ │ ├── transfer_data_command.dart │ │ ├── transfer_data_command.g.dart │ │ ├── transfer_data_conversation.dart │ │ ├── transfer_data_conversation.g.dart │ │ ├── transfer_data_expired_message.dart │ │ ├── transfer_data_expired_message.g.dart │ │ ├── transfer_data_message.dart │ │ ├── transfer_data_message.g.dart │ │ ├── transfer_data_participant.dart │ │ ├── transfer_data_participant.g.dart │ │ ├── transfer_data_pin_message.dart │ │ ├── transfer_data_pin_message.g.dart │ │ ├── transfer_data_safe_snapshot.dart │ │ ├── transfer_data_safe_snapshot.g.dart │ │ ├── transfer_data_snapshot.dart │ │ ├── transfer_data_snapshot.g.dart │ │ ├── transfer_data_sticker.dart │ │ ├── transfer_data_sticker.g.dart │ │ ├── transfer_data_token.dart │ │ ├── transfer_data_token.g.dart │ │ ├── transfer_data_transcript_message.dart │ │ ├── transfer_data_transcript_message.g.dart │ │ ├── transfer_data_user.dart │ │ ├── transfer_data_user.g.dart │ │ └── transfer_protocol.dart │ ├── double_tap_util.dart │ ├── emoji.dart │ ├── event_bus.dart │ ├── extension │ │ ├── extension.dart │ │ └── src │ │ │ ├── db.dart │ │ │ ├── duration.dart │ │ │ ├── errors.dart │ │ │ ├── file.dart │ │ │ ├── image.dart │ │ │ ├── info.dart │ │ │ ├── iterable.dart │ │ │ ├── key_event.dart │ │ │ ├── markdown.dart │ │ │ ├── number.dart │ │ │ ├── platforms.dart │ │ │ ├── provider.dart │ │ │ ├── regexp.dart │ │ │ ├── stream.dart │ │ │ ├── string.dart │ │ │ └── ui.dart │ ├── file.dart │ ├── hive_key_values.dart │ ├── hook.dart │ ├── hydrated_bloc.dart │ ├── image.dart │ ├── load_balancer_utils.dart │ ├── local_notification_center.dart │ ├── logger.dart │ ├── message_optimize.dart │ ├── mixin_api_client.dart │ ├── platform.dart │ ├── property │ │ └── setting_property.dart │ ├── proxy.dart │ ├── proxy.g.dart │ ├── reg_exp_utils.dart │ ├── rivepod.dart │ ├── sort.dart │ ├── synchronized.dart │ ├── system │ │ ├── audio_session.dart │ │ ├── clipboard.dart │ │ ├── memory.dart │ │ ├── package_info.dart │ │ ├── system_fonts.dart │ │ ├── system_utils.dart │ │ ├── text_input.dart │ │ ├── tray.dart │ │ └── windows.dart │ ├── uri_utils.dart │ ├── video.dart │ └── web_view │ │ ├── web_view_desktop.dart │ │ ├── web_view_interface.dart │ │ └── web_view_mobile.dart ├── widgets │ ├── action_button.dart │ ├── actions │ │ ├── actions.dart │ │ ├── command_palette_action.dart │ │ ├── create_circle_action.dart │ │ ├── create_conversation_action.dart │ │ └── create_group_conversation_action.dart │ ├── animated_visibility.dart │ ├── app_bar.dart │ ├── auth.dart │ ├── automatic_keep_alive_client_widget.dart │ ├── avatar_view │ │ └── avatar_view.dart │ ├── az_selection.dart │ ├── brightness_observer.dart │ ├── buttons.dart │ ├── cache_lottie.dart │ ├── cell.dart │ ├── clamping_custom_scroll_view │ │ ├── clamping_custom_scroll_view.dart │ │ └── clamping_viewport.dart │ ├── conversation │ │ ├── badges_widget.dart │ │ ├── conversation_dialog.dart │ │ └── mute_dialog.dart │ ├── dash_path_border.dart │ ├── dialog.dart │ ├── disable.dart │ ├── empty.dart │ ├── focus_helper.dart │ ├── full_screen_portal.dart │ ├── high_light_text.dart │ ├── hover_overlay.dart │ ├── image.dart │ ├── interactive_decorated_box.dart │ ├── markdown.dart │ ├── mention_panel.dart │ ├── menu.dart │ ├── message │ │ ├── item │ │ │ ├── action │ │ │ │ ├── action_data.dart │ │ │ │ ├── action_data.g.dart │ │ │ │ └── action_message.dart │ │ │ ├── action_card │ │ │ │ ├── action_card_data.dart │ │ │ │ ├── action_card_data.g.dart │ │ │ │ ├── action_message.dart │ │ │ │ └── actions_card.dart │ │ │ ├── audio_message.dart │ │ │ ├── contact_message_widget.dart │ │ │ ├── file_message.dart │ │ │ ├── image │ │ │ │ ├── image_message.dart │ │ │ │ ├── image_preview_page.dart │ │ │ │ └── preview_image_widget.dart │ │ │ ├── location │ │ │ │ ├── location_message_widget.dart │ │ │ │ ├── location_payload.dart │ │ │ │ └── location_payload.g.dart │ │ │ ├── pin_message.dart │ │ │ ├── post_message.dart │ │ │ ├── quote_message.dart │ │ │ ├── recall_message.dart │ │ │ ├── secret_message.dart │ │ │ ├── sticker_message.dart │ │ │ ├── stranger_message.dart │ │ │ ├── system_message.dart │ │ │ ├── text │ │ │ │ ├── selectable.dart │ │ │ │ └── text_message.dart │ │ │ ├── transcript_message.dart │ │ │ ├── transfer │ │ │ │ ├── inscription_message │ │ │ │ │ ├── colored_hash_widget.dart │ │ │ │ │ ├── inscription_content.dart │ │ │ │ │ ├── inscription_dialog.dart │ │ │ │ │ └── inscription_message.dart │ │ │ │ ├── safe_transfer_dialog.dart │ │ │ │ ├── safe_transfer_message.dart │ │ │ │ ├── transfer_message.dart │ │ │ │ └── transfer_page.dart │ │ │ ├── unknown_message.dart │ │ │ ├── video │ │ │ │ ├── progress_bar.dart │ │ │ │ ├── slider.dart │ │ │ │ ├── video_message.dart │ │ │ │ └── video_preview_page.dart │ │ │ └── waiting_message.dart │ │ ├── message.dart │ │ ├── message_bubble.dart │ │ ├── message_datetime_and_status.dart │ │ ├── message_day_time.dart │ │ ├── message_layout.dart │ │ ├── message_name.dart │ │ ├── message_style.dart │ │ └── send_message_dialog │ │ │ ├── attachment_extra.dart │ │ │ ├── attachment_extra.g.dart │ │ │ ├── send_image_data.dart │ │ │ ├── send_image_data.g.dart │ │ │ └── send_message_dialog.dart │ ├── message_status_icon.dart │ ├── mixin_image.dart │ ├── more_extended_text.dart │ ├── payment │ │ └── multisigs_payment_dialog.dart │ ├── pin_bubble.dart │ ├── portal_providers.dart │ ├── protocol_handler.dart │ ├── qr_code.dart │ ├── radio.dart │ ├── search_bar.dart │ ├── search_text_field.dart │ ├── select_item.dart │ ├── status.dart │ ├── sticker_page │ │ ├── add_sticker_dialog.dart │ │ ├── bloc │ │ │ └── cubit │ │ │ │ ├── sticker_albums_cubit.dart │ │ │ │ └── sticker_cubit.dart │ │ ├── emoji_page.dart │ │ ├── giphy_page.dart │ │ ├── sticker_album_page.dart │ │ ├── sticker_item.dart │ │ ├── sticker_page.dart │ │ └── sticker_store.dart │ ├── toast.dart │ ├── unknown_mixin_url_dialog.dart │ ├── unread_text.dart │ ├── user │ │ ├── captcha_web_view_dialog.dart │ │ ├── change_number_dialog.dart │ │ ├── phone_number_input.dart │ │ ├── pin_verification_dialog.dart │ │ ├── user_dialog.dart │ │ └── verification_dialog.dart │ ├── user_selector │ │ ├── bloc │ │ │ ├── conversation_filter_cubit.dart │ │ │ └── conversation_filter_state.dart │ │ └── conversation_selector.dart │ ├── waveform_widget.dart │ ├── web_view_navigation_bar.dart │ └── window │ │ ├── menus.dart │ │ ├── move_window.dart │ │ └── window_shortcuts.dart └── workers │ ├── decrypt_message.dart │ ├── device_transfer.dart │ ├── injector.dart │ ├── isolate_event.dart │ ├── job │ ├── ack_job.dart │ ├── base_migration_job.dart │ ├── cleanup_quote_content_job.dart │ ├── delete_old_fts_record_job.dart │ ├── flood_job.dart │ ├── migrate_fts_job.dart │ ├── sending_job.dart │ ├── session_ack_job.dart │ ├── sync_inscription_message_job.dart │ ├── update_asset_job.dart │ ├── update_sticker_job.dart │ └── update_token_job.dart │ ├── job_queue.dart │ ├── message_worker_isolate.dart │ └── sender.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon-128.png │ │ ├── icon-128@2x.png │ │ ├── icon-16.png │ │ ├── icon-16@2x.png │ │ ├── icon-256.png │ │ ├── icon-256@2x.png │ │ ├── icon-32.png │ │ ├── icon-32@2x.png │ │ ├── icon-512.png │ │ └── icon-512@2x.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ ├── PlatformMenuPlugin.swift │ ├── Release.entitlements │ ├── mixin.caf │ └── zh-Hans.lproj │ └── MainMenu.strings ├── pubspec.lock ├── pubspec.yaml ├── test ├── crypto │ └── encrypt_test.dart ├── db │ ├── database_fts5_search_test.dart │ └── property_storage_test.dart ├── regex_test.dart ├── utils │ ├── device_transfer_test.dart │ ├── emoji_test.dart │ ├── event_bus_test.dart │ ├── iterable_extension_test.dart │ ├── number_test.dart │ ├── stream_extension_test.dart │ ├── string_extension_test.dart │ ├── transfer_cipher_test.dart │ └── transfer_protocol_test.dart ├── uuid_test.dart └── widgets │ ├── image_editor_test.dart │ └── message │ ├── action_card_test.dart │ ├── inscription_content_test.dart │ └── video_message_test.dart ├── third_party ├── README.md └── system_tray │ ├── .clang-format │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ ├── src │ │ ├── app_window.dart │ │ ├── menu_item.dart │ │ └── tray.dart │ └── system_tray.dart │ ├── pubspec.lock │ ├── pubspec.yaml │ ├── test │ └── system_tray_test.dart │ └── windows │ ├── .gitignore │ ├── CMakeLists.txt │ ├── app_window.cpp │ ├── app_window.h │ ├── include │ └── system_tray │ │ └── system_tray_plugin.h │ ├── system_tray_plugin.cpp │ ├── tray.cpp │ └── tray.h ├── web └── index.html ├── windows ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── libs │ └── vclibs │ │ ├── msvcp140.dll │ │ ├── vcruntime140.dll │ │ └── vcruntime140_1.dll └── runner │ ├── CMakeLists.txt │ ├── Runner.rc │ ├── flutter_window.cpp │ ├── flutter_window.h │ ├── main.cpp │ ├── raw_hwnd_plugin.cpp │ ├── raw_hwnd_plugin.h │ ├── resource.h │ ├── resources │ └── app_icon.ico │ ├── runner.exe.manifest │ ├── utils.cpp │ ├── utils.h │ ├── win32_window.cpp │ └── win32_window.h └── windows_inno_setup.iss /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | enable-beta-ecosystems: true 3 | updates: 4 | - package-ecosystem: "pub" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "debug", 6 | "request": "launch", 7 | "type": "dart", 8 | "flutterMode": "debug", 9 | "args": ["--no-sound-null-safety"] 10 | }, 11 | { 12 | "name": "profile", 13 | "request": "launch", 14 | "type": "dart", 15 | "flutterMode": "profile" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "svg.preview.background": "black" 3 | } -------------------------------------------------------------------------------- /agen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! command -v agen &>/dev/null; then 4 | echo "agen not found, active assets_generator..." 5 | dart pub global activate assets_generator 6 | if ! command -v agen &>/dev/null; then 7 | echo "install assets_generator failed" 8 | exit 1 9 | else 10 | echo "install assets_generator success" 11 | fi 12 | fi 13 | 14 | agen --no-watch -t d -r lcc -o lib/constants -c Resources 15 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_app 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/fonts/iconfont.ttf -------------------------------------------------------------------------------- /assets/icons/macos_app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/icons/macos_app_icon.png -------------------------------------------------------------------------------- /assets/icons/windows_app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/icons/windows_app_icon.png -------------------------------------------------------------------------------- /assets/images/about_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/about_logo.png -------------------------------------------------------------------------------- /assets/images/account.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/add_sticker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/attachment_download.svg: -------------------------------------------------------------------------------- 1 | 3 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /assets/images/audio_play.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/audio_stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/bot_fill.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/chat_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/chat_background.png -------------------------------------------------------------------------------- /assets/images/checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/circle.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/circle_add.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /assets/images/circle_remove.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/close_oval_record.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/collapse.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /assets/images/context_menu_copy.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/context_menu_delete.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/images/copy.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /assets/images/delete.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /assets/images/delivered.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/edit_image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/edit_image_clip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/edit_image_draw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/edit_image_flip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/edit_image_redo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/edit_image_rotate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/edit_image_undo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/ellipsis.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/emoji_face.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/emoji_flags.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/emoji_objects.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/emoji_recent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/emoji_sports.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/emoji_sticker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/emoji_symbol.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/emoji_travel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/empty_image.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/exclamation_mark.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /assets/images/expanded.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /assets/images/expiring.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/external_link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/images/failed.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /assets/images/file_preview_files.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/file_preview_images.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/filter_unseen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/ic_about.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /assets/images/ic_add.svg: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/ic_arrow_right.svg: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/ic_back.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/ic_close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/ic_close_big.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/ic_file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/ic_forward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/ic_screen.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/ic_search.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/ic_search_small.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/ic_send.svg: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/ic_sign_out.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /assets/images/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /assets/images/information.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/invite_copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/invite_refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/invite_share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/jump_current_arrow.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/link_send.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/images/live.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /assets/images/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/message_pin.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/message_secret.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/message_transcript_forward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/microphone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/next.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/notify_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/notify_icon.ico -------------------------------------------------------------------------------- /assets/images/personal_sticker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/pin_arrow.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /assets/images/plan_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/plan_basic.png -------------------------------------------------------------------------------- /assets/images/plan_premium.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/plan_premium.gif -------------------------------------------------------------------------------- /assets/images/plan_standard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/plan_standard.png -------------------------------------------------------------------------------- /assets/images/play.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /assets/images/player_pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/player_play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/post_detail.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/prev.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /assets/images/proxy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/read.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/recall.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /assets/images/recent_sticker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/record_retry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/record_stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/rotato.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/selected.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/sent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/small_close.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/snapshot_done.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/images/successful.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /assets/images/text_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/assets/images/text_bg.png -------------------------------------------------------------------------------- /assets/images/triangle_warning.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /assets/images/upload.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/user_search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/images/video.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | -------------------------------------------------------------------------------- /assets/images/video_message.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/images/web_view_refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/zoom_out.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | builders: 4 | drift_dev: 5 | options: 6 | mutable_classes: false 7 | apply_converters_on_variables: true 8 | generate_values_in_copy_with: true 9 | override_hash_and_equals_in_result_sets: true 10 | scoped_dart_components: true 11 | fatal_warnings: true 12 | sqlite_modules: 13 | - fts5 14 | - moor_ffi 15 | json_serializable: 16 | options: 17 | explicit_to_json: true 18 | -------------------------------------------------------------------------------- /db_generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dart run build_runner build --delete-conflicting-outputs 3 | -------------------------------------------------------------------------------- /dist/appdmg.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Mixin Desktop", 3 | "background": "bg.png", 4 | "window": { 5 | "size": {"width": 670, "height": 398} 6 | }, 7 | "contents": [ 8 | { "x": 441, "y": 203, "type": "link", "path": "/Applications" }, 9 | { "x": 229, "y": 203, "type": "file", "path": "Mixin.app" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /dist/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/bg.png -------------------------------------------------------------------------------- /dist/deb/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Section: x11 2 | Priority: optional 3 | Version: 0.37.1 4 | Homepage: https://mixin.one/messenger 5 | Package: mixin-desktop 6 | Maintainer: Mixin Team 7 | Architecture: amd64 8 | Depends: libgtk-3-0 (>= 3.10.0), libsdl2-2.0-0, libwebkit2gtk-4.1-0, libopus0 9 | Description: Mixin messenger desktop 10 | -------------------------------------------------------------------------------- /dist/deb/usr/share/applications/mixin_desktop.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Mixin Messenger 4 | Comment=An encrypted messenger with Signal protocol and cryptocurrency wallet 5 | GenericName=Internet Messenger 6 | Categories=InstantMessaging 7 | Version=1.0 8 | Exec=mixin_desktop %u 9 | Terminal=false 10 | Icon=mixin_desktop 11 | MimeType=x-scheme-handler/mixin; -------------------------------------------------------------------------------- /dist/deb/usr/share/icons/hicolor/128x128/apps/mixin_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/deb/usr/share/icons/hicolor/128x128/apps/mixin_desktop.png -------------------------------------------------------------------------------- /dist/deb/usr/share/icons/hicolor/256x256/apps/mixin_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/deb/usr/share/icons/hicolor/256x256/apps/mixin_desktop.png -------------------------------------------------------------------------------- /dist/linux_snap_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | app_name="mixin_desktop" 4 | current_dir=$(dirname "$0") 5 | 6 | project_dir="${current_dir}/.." 7 | package_dir="${current_dir}/snap/mixin_desktop" 8 | 9 | snap_craft_file="${current_dir}/snap/snap/snapcraft.yaml" 10 | 11 | rm -rf "${package_dir}" 12 | 13 | # read version from pubspec.yaml 14 | version=$(cat "${project_dir}/pubspec.yaml" | grep "^version:" | awk '{print $2}' | tr -d '"') 15 | version=$(echo "${version}" | sed 's/+.*//') 16 | 17 | # check version only contains numbers and dots 18 | if ! [[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 19 | echo "Error: Invalid version format: ${version}" 20 | exit 1 21 | fi 22 | 23 | # update snapcraft file version 24 | sed -i "s/version:.*/version: ${version}/g" "${snap_craft_file}" 25 | 26 | # copy bundle to snap 27 | cp -fr "$project_dir/build/linux/x64/release/bundle/." "$package_dir" -------------------------------------------------------------------------------- /dist/mac_app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/mac_app_icon.png -------------------------------------------------------------------------------- /dist/macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | appdmg ./appdmg.json ./mixin.dmg 4 | -------------------------------------------------------------------------------- /dist/screenshots/linux_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/screenshots/linux_1.png -------------------------------------------------------------------------------- /dist/screenshots/linux_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/screenshots/linux_2.png -------------------------------------------------------------------------------- /dist/screenshots/linux_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/screenshots/linux_3.png -------------------------------------------------------------------------------- /dist/screenshots/linux_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/screenshots/linux_4.png -------------------------------------------------------------------------------- /dist/snap/snap/gui/mixin-desktop.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Mixin Desktop 4 | Comment=Mixin Messenger 5 | GenericName=Internet Messenger 6 | Categories=InstantMessaging 7 | Version=1.0 8 | Exec=mixin-desktop %u 9 | Terminal=false 10 | Icon=${SNAP}/meta/gui/mixin-desktop.png 11 | MimeType=x-scheme-handler/mixin; 12 | -------------------------------------------------------------------------------- /dist/snap/snap/gui/mixin-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/dist/snap/snap/gui/mixin-desktop.png -------------------------------------------------------------------------------- /dist/snap/snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: mixin-desktop 2 | version: 0.37.8 3 | summary: Mixin Desktop 4 | description: Mixin Messenger 5 | license: GPL-3.0 6 | 7 | confinement: strict 8 | base: core24 9 | grade: stable 10 | 11 | slots: 12 | dbus-mixin: 13 | interface: dbus 14 | bus: session 15 | name: one.mixin.messenger 16 | 17 | apps: 18 | mixin-desktop: 19 | command: mixin_desktop 20 | extensions: 21 | - gnome 22 | plugs: 23 | - network 24 | - audio-playback 25 | - audio-record 26 | - alsa 27 | - pulseaudio 28 | - home 29 | - removable-media 30 | slots: 31 | - dbus-mixin 32 | 33 | parts: 34 | mixin-desktop: 35 | source: ./mixin_desktop 36 | plugin: dump 37 | stage-packages: 38 | - libsdl2-2.0-0 39 | - libgtk-3-0 40 | - libwebkit2gtk-4.1-0 41 | - libopus0 -------------------------------------------------------------------------------- /dist/win.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | flutter build windows 3 | flutter pub run msix:create 4 | -------------------------------------------------------------------------------- /fonts/Noto-COLRv1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/fonts/Noto-COLRv1.ttf -------------------------------------------------------------------------------- /fonts/mixin_font.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/fonts/mixin_font.otf -------------------------------------------------------------------------------- /generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dart run build_runner build 3 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 3 | #include "Generated.xcconfig" 4 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 3 | #include "Generated.xcconfig" 4 | -------------------------------------------------------------------------------- /ios/Flutter/ephemeral/flutter_lldbinit: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | command script import --relative-to-command-file flutter_lldb_helper.py 6 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | if #available(iOS 10.0, *) { 12 | UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate 13 | } 14 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/20@2x-1.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/29-1.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/29@2x-1.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/40@2x-1.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/AppIcon.appiconset/83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/Runner/mixin.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/ios/Runner/mixin.caf -------------------------------------------------------------------------------- /lib/api/giphy_vo/giphy_gif.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | import 'giphy_image_set.dart'; 5 | 6 | part 'giphy_gif.g.dart'; 7 | 8 | @JsonSerializable() 9 | class GiphyGif with EquatableMixin { 10 | GiphyGif({required this.id, required this.type, required this.images}); 11 | 12 | factory GiphyGif.fromJson(Map json) => 13 | _$GiphyGifFromJson(json); 14 | 15 | final String id; 16 | 17 | final String type; 18 | 19 | final GiphyImageSet images; 20 | 21 | @override 22 | List get props => [id, type, images]; 23 | 24 | Map toJson() => _$GiphyGifToJson(this); 25 | } 26 | -------------------------------------------------------------------------------- /lib/api/giphy_vo/giphy_gif.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'giphy_gif.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | GiphyGif _$GiphyGifFromJson(Map json) => GiphyGif( 10 | id: json['id'] as String, 11 | type: json['type'] as String, 12 | images: GiphyImageSet.fromJson(json['images'] as Map), 13 | ); 14 | 15 | Map _$GiphyGifToJson(GiphyGif instance) => { 16 | 'id': instance.id, 17 | 'type': instance.type, 18 | 'images': instance.images.toJson(), 19 | }; 20 | -------------------------------------------------------------------------------- /lib/blaze/blaze_signal_key_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'blaze_signal_key_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BlazeSignalKeyMessage _$BlazeSignalKeyMessageFromJson( 10 | Map json, 11 | ) => BlazeSignalKeyMessage( 12 | json['message_id'] as String, 13 | json['recipient_id'] as String, 14 | json['data'] as String, 15 | json['session_id'] as String?, 16 | ); 17 | 18 | Map _$BlazeSignalKeyMessageToJson( 19 | BlazeSignalKeyMessage instance, 20 | ) => { 21 | 'message_id': instance.messageId, 22 | 'recipient_id': instance.recipientId, 23 | 'data': instance.data, 24 | 'session_id': instance.sessionId, 25 | }; 26 | -------------------------------------------------------------------------------- /lib/blaze/vo/message_result.dart: -------------------------------------------------------------------------------- 1 | class MessageResult { 2 | MessageResult(this.success, this.retry, [this.errorCode]); 3 | 4 | final bool success; 5 | final bool retry; 6 | final int? errorCode; 7 | } 8 | -------------------------------------------------------------------------------- /lib/blaze/vo/one_time_pre_key.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'one_time_pre_key.g.dart'; 5 | 6 | @JsonSerializable() 7 | class OneTimePreKey with EquatableMixin { 8 | OneTimePreKey(this.keyId, this.pubKey); 9 | 10 | factory OneTimePreKey.fromJson(Map json) => 11 | _$OneTimePreKeyFromJson(json); 12 | 13 | @JsonKey(name: 'key_id') 14 | final int keyId; 15 | @JsonKey(name: 'pub_key') 16 | final String? pubKey; 17 | 18 | Map toJson() => _$OneTimePreKeyToJson(this); 19 | 20 | @override 21 | List get props => [keyId, pubKey]; 22 | } 23 | -------------------------------------------------------------------------------- /lib/blaze/vo/one_time_pre_key.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'one_time_pre_key.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | OneTimePreKey _$OneTimePreKeyFromJson(Map json) => 10 | OneTimePreKey((json['key_id'] as num).toInt(), json['pub_key'] as String?); 11 | 12 | Map _$OneTimePreKeyToJson(OneTimePreKey instance) => 13 | {'key_id': instance.keyId, 'pub_key': instance.pubKey}; 14 | -------------------------------------------------------------------------------- /lib/blaze/vo/pin_message_minimal.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pin_message_minimal.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PinMessageMinimal _$PinMessageMinimalFromJson(Map json) => 10 | PinMessageMinimal( 11 | messageId: json['message_id'] as String, 12 | type: json['category'] as String, 13 | content: json['content'] as String?, 14 | ); 15 | 16 | Map _$PinMessageMinimalToJson(PinMessageMinimal instance) => 17 | { 18 | 'message_id': instance.messageId, 19 | 'category': instance.type, 20 | 'content': instance.content, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/blaze/vo/pin_message_payload.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'pin_message_payload.g.dart'; 4 | 5 | @JsonSerializable() 6 | class PinMessagePayload { 7 | PinMessagePayload({required this.action, required this.messageIds}); 8 | 9 | factory PinMessagePayload.fromJson(Map json) => 10 | _$PinMessagePayloadFromJson(json); 11 | 12 | @JsonKey(name: 'action') 13 | final PinMessagePayloadAction? action; 14 | @JsonKey(name: 'message_ids') 15 | final List messageIds; 16 | 17 | Map toJson() => _$PinMessagePayloadToJson(this); 18 | } 19 | 20 | enum PinMessagePayloadAction { 21 | @JsonValue('PIN') 22 | pin, 23 | @JsonValue('UNPIN') 24 | unpin, 25 | } 26 | -------------------------------------------------------------------------------- /lib/blaze/vo/recall_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'recall_message.g.dart'; 4 | 5 | @JsonSerializable() 6 | class RecallMessage { 7 | RecallMessage(this.messageId); 8 | 9 | factory RecallMessage.fromJson(Map json) => 10 | _$RecallMessageFromJson(json); 11 | 12 | @JsonKey(name: 'message_id') 13 | String messageId; 14 | 15 | Map toJson() => _$RecallMessageToJson(this); 16 | } 17 | -------------------------------------------------------------------------------- /lib/blaze/vo/recall_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'recall_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | RecallMessage _$RecallMessageFromJson(Map json) => 10 | RecallMessage(json['message_id'] as String); 11 | 12 | Map _$RecallMessageToJson(RecallMessage instance) => 13 | {'message_id': instance.messageId}; 14 | -------------------------------------------------------------------------------- /lib/blaze/vo/sender_key_status.dart: -------------------------------------------------------------------------------- 1 | enum SenderKeyStatus { unknown, sent } 2 | -------------------------------------------------------------------------------- /lib/blaze/vo/signed_pre_key.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | import 'one_time_pre_key.dart'; 5 | 6 | part 'signed_pre_key.g.dart'; 7 | 8 | @JsonSerializable() 9 | class SignedPreKey extends OneTimePreKey with EquatableMixin { 10 | SignedPreKey(super.keyId, super.pubKey, this.signature); 11 | 12 | factory SignedPreKey.fromJson(Map json) => 13 | _$SignedPreKeyFromJson(json); 14 | 15 | @JsonKey(name: 'signature') 16 | final String signature; 17 | 18 | @override 19 | Map toJson() => _$SignedPreKeyToJson(this); 20 | 21 | @override 22 | List get props => [keyId, pubKey, signature]; 23 | } 24 | -------------------------------------------------------------------------------- /lib/blaze/vo/signed_pre_key.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'signed_pre_key.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SignedPreKey _$SignedPreKeyFromJson(Map json) => SignedPreKey( 10 | (json['key_id'] as num).toInt(), 11 | json['pub_key'] as String?, 12 | json['signature'] as String, 13 | ); 14 | 15 | Map _$SignedPreKeyToJson(SignedPreKey instance) => 16 | { 17 | 'key_id': instance.keyId, 18 | 'pub_key': instance.pubKey, 19 | 'signature': instance.signature, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/blaze/vo/system_circle_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import '../../enum/system_circle_action.dart'; 4 | 5 | part 'system_circle_message.g.dart'; 6 | 7 | @JsonSerializable() 8 | class SystemCircleMessage { 9 | SystemCircleMessage( 10 | this.action, 11 | this.circleId, 12 | this.userId, 13 | this.conversationId, 14 | ); 15 | 16 | factory SystemCircleMessage.fromJson(Map json) => 17 | _$SystemCircleMessageFromJson(json); 18 | 19 | @JsonKey(name: 'action') 20 | SystemCircleAction action; 21 | @JsonKey(name: 'circle_id') 22 | String circleId; 23 | @JsonKey(name: 'conversation_id') 24 | String? conversationId; 25 | @JsonKey(name: 'user_id') 26 | String? userId; 27 | 28 | Map toJson() => _$SystemCircleMessageToJson(this); 29 | } 30 | -------------------------------------------------------------------------------- /lib/blaze/vo/system_session_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import '../../enum/system_user_action.dart'; 4 | 5 | part 'system_session_message.g.dart'; 6 | 7 | @JsonSerializable() 8 | class SystemSessionMessage { 9 | SystemSessionMessage(this.action, this.userId); 10 | 11 | factory SystemSessionMessage.fromJson(Map json) => 12 | _$SystemSessionMessageFromJson(json); 13 | 14 | @JsonKey(name: 'action') 15 | SystemUserAction action; 16 | @JsonKey(name: 'user_id') 17 | String userId; 18 | @JsonKey(name: 'session_id') 19 | String? sessionId; 20 | 21 | Map toJson() => _$SystemSessionMessageToJson(this); 22 | } 23 | -------------------------------------------------------------------------------- /lib/blaze/vo/system_session_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'system_session_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SystemSessionMessage _$SystemSessionMessageFromJson( 10 | Map json, 11 | ) => SystemSessionMessage( 12 | $enumDecode(_$SystemUserActionEnumMap, json['action']), 13 | json['user_id'] as String, 14 | )..sessionId = json['session_id'] as String?; 15 | 16 | Map _$SystemSessionMessageToJson( 17 | SystemSessionMessage instance, 18 | ) => { 19 | 'action': _$SystemUserActionEnumMap[instance.action]!, 20 | 'user_id': instance.userId, 21 | 'session_id': instance.sessionId, 22 | }; 23 | 24 | const _$SystemUserActionEnumMap = {SystemUserAction.update: 'UPDATE'}; 25 | -------------------------------------------------------------------------------- /lib/blaze/vo/system_user_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import '../../enum/system_user_action.dart'; 4 | 5 | part 'system_user_message.g.dart'; 6 | 7 | @JsonSerializable() 8 | class SystemUserMessage { 9 | SystemUserMessage(this.action, this.userId); 10 | 11 | factory SystemUserMessage.fromJson(Map json) => 12 | _$SystemUserMessageFromJson(json); 13 | 14 | @JsonKey(name: 'action') 15 | SystemUserAction action; 16 | @JsonKey(name: 'user_id') 17 | String userId; 18 | 19 | Map toJson() => _$SystemUserMessageToJson(this); 20 | } 21 | -------------------------------------------------------------------------------- /lib/blaze/vo/system_user_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'system_user_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SystemUserMessage _$SystemUserMessageFromJson(Map json) => 10 | SystemUserMessage( 11 | $enumDecode(_$SystemUserActionEnumMap, json['action']), 12 | json['user_id'] as String, 13 | ); 14 | 15 | Map _$SystemUserMessageToJson(SystemUserMessage instance) => 16 | { 17 | 'action': _$SystemUserActionEnumMap[instance.action]!, 18 | 'user_id': instance.userId, 19 | }; 20 | 21 | const _$SystemUserActionEnumMap = {SystemUserAction.update: 'UPDATE'}; 22 | -------------------------------------------------------------------------------- /lib/blaze/vo/transcript_minimal.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'transcript_minimal.g.dart'; 5 | 6 | @JsonSerializable() 7 | class TranscriptMinimal extends Equatable { 8 | const TranscriptMinimal({ 9 | required this.name, 10 | required this.category, 11 | this.content, 12 | }); 13 | 14 | factory TranscriptMinimal.fromJson(Map json) => 15 | _$TranscriptMinimalFromJson(json); 16 | 17 | final String name; 18 | final String category; 19 | final String? content; 20 | 21 | Map toJson() => _$TranscriptMinimalToJson(this); 22 | 23 | @override 24 | List get props => [name, category, content]; 25 | } 26 | -------------------------------------------------------------------------------- /lib/blaze/vo/transcript_minimal.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'transcript_minimal.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TranscriptMinimal _$TranscriptMinimalFromJson(Map json) => 10 | TranscriptMinimal( 11 | name: json['name'] as String, 12 | category: json['category'] as String, 13 | content: json['content'] as String?, 14 | ); 15 | 16 | Map _$TranscriptMinimalToJson(TranscriptMinimal instance) => 17 | { 18 | 'name': instance.name, 19 | 'category': instance.category, 20 | 'content': instance.content, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/bloc/custom_bloc_observer.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import '../utils/logger.dart'; 3 | 4 | class CustomBlocObserver extends BlocObserver { 5 | @override 6 | void onError(BlocBase bloc, Object error, StackTrace stackTrace) { 7 | super.onError(bloc, error, stackTrace); 8 | w('Bloc Error: bloc: $bloc, error: $error, stackTrace: $stackTrace'); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/bloc/simple_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | 3 | class SimpleCubit extends Cubit { 4 | SimpleCubit(super.state); 5 | 6 | @override 7 | void emit(State state) => super.emit(state); 8 | } 9 | -------------------------------------------------------------------------------- /lib/bloc/stream_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import 'subscribe_mixin.dart'; 3 | 4 | class StreamCubit extends Cubit with SubscribeMixin { 5 | StreamCubit(super.state, Stream stream) { 6 | addSubscription(stream.distinct().listen(emit)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/constants/env.dart: -------------------------------------------------------------------------------- 1 | import 'package:envied/envied.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | 4 | part 'env.g.dart'; 5 | 6 | class Env { 7 | static const String sentryDsn = 8 | kReleaseMode ? ProductEnv._sentryDsn ?? '' : ''; 9 | } 10 | 11 | @Envied(path: '.env', allowOptionalFields: true) 12 | abstract class ProductEnv { 13 | @EnviedField(varName: 'SENTRY_DSN') 14 | static const String? _sentryDsn = _ProductEnv._sentryDsn; 15 | } 16 | -------------------------------------------------------------------------------- /lib/crypto/privacy_key_value.dart: -------------------------------------------------------------------------------- 1 | import '../utils/hive_key_values.dart'; 2 | 3 | class PrivacyKeyValue extends HiveKeyValue { 4 | PrivacyKeyValue._() : super(_hivePrivacy); 5 | 6 | static PrivacyKeyValue? _instance; 7 | 8 | static PrivacyKeyValue get instance => _instance ??= PrivacyKeyValue._(); 9 | 10 | static const _hivePrivacy = 'privacy_box'; 11 | static const _hasSyncSession = 'has_sync_session'; 12 | static const _hasPushSignalKeys = 'has_push_signal_keys'; 13 | 14 | bool get hasSyncSession => box.get(_hasSyncSession, defaultValue: false)!; 15 | 16 | set hasSyncSession(bool value) => box.put(_hasSyncSession, value); 17 | 18 | bool get hasPushSignalKeys => 19 | box.get(_hasPushSignalKeys, defaultValue: false)!; 20 | 21 | set hasPushSignalKeys(bool value) => box.put(_hasPushSignalKeys, value); 22 | } 23 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/identity_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../signal_database.dart'; 4 | 5 | part 'identity_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class IdentityDao extends DatabaseAccessor 9 | with _$IdentityDaoMixin { 10 | IdentityDao(super.db); 11 | 12 | Future getIdentityByAddress(String address) async => 13 | (select(db.identities) 14 | ..where((tbl) => tbl.address.equals(address))).getSingleOrNull(); 15 | 16 | Future insert(IdentitiesCompanion identitiesCompanion) => into( 17 | db.identities, 18 | ).insert(identitiesCompanion, mode: InsertMode.insertOrReplace); 19 | 20 | Future deleteByAddress(String address) => 21 | (delete(db.identities)..where((tbl) => tbl.address.equals(address))).go(); 22 | 23 | Future getLocalIdentity() async => 24 | (select(db.identities) 25 | ..where((tbl) => tbl.address.equals('-1'))).getSingleOrNull(); 26 | } 27 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/identity_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'identity_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$IdentityDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/pre_key_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../signal_database.dart'; 4 | 5 | part 'pre_key_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class PreKeyDao extends DatabaseAccessor with _$PreKeyDaoMixin { 9 | PreKeyDao(super.db); 10 | 11 | Future getPreKeyById(int preKeyId) async => 12 | (select(db.prekeys) 13 | ..where((tbl) => tbl.prekeyId.equals(preKeyId))).getSingleOrNull(); 14 | 15 | Future deleteByPreKeyId(int preKeyId) => 16 | (delete(db.prekeys)..where((tbl) => tbl.prekeyId.equals(preKeyId))).go(); 17 | 18 | Future insert(Prekey preKey) => 19 | into(db.prekeys).insert(preKey, mode: InsertMode.insertOrReplace); 20 | 21 | Future insertList(List list) async => batch( 22 | (batch) => 23 | batch.insertAll(db.prekeys, list, mode: InsertMode.insertOrReplace), 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/pre_key_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pre_key_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$PreKeyDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/ratchet_sender_key_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'ratchet_sender_key_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$RatchetSenderKeyDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/sender_key_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../signal_database.dart'; 4 | 5 | part 'sender_key_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class SenderKeyDao extends DatabaseAccessor 9 | with _$SenderKeyDaoMixin { 10 | SenderKeyDao(super.db); 11 | 12 | Future getSenderKey(String groupId, String senderId) async => 13 | (select(db.senderKeys)..where( 14 | (tbl) => tbl.groupId.equals(groupId) & tbl.senderId.equals(senderId), 15 | )).getSingleOrNull(); 16 | 17 | Future> getSenderKeys() async => select(db.senderKeys).get(); 18 | 19 | Future insert(SenderKey senderKey) => 20 | into(db.senderKeys).insertOnConflictUpdate(senderKey); 21 | 22 | Future deleteByGroupIdAndSenderId(String groupId, String senderId) async => 23 | (delete(db.senderKeys)..where( 24 | (tbl) => tbl.groupId.equals(groupId) & tbl.senderId.equals(senderId), 25 | )).go(); 26 | } 27 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/sender_key_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'sender_key_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$SenderKeyDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/session_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'session_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$SessionDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/signed_pre_key_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../signal_database.dart'; 4 | 5 | part 'signed_pre_key_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class SignedPreKeyDao extends DatabaseAccessor 9 | with _$SignedPreKeyDaoMixin { 10 | SignedPreKeyDao(super.db); 11 | 12 | Future getSignedPreKey(int signedPreKeyId) async => 13 | (select( 14 | db.signedPrekeys, 15 | )..where((tbl) => tbl.prekeyId.equals(signedPreKeyId))).getSingleOrNull(); 16 | 17 | Future> getSignedPreKeyList() async => 18 | select(db.signedPrekeys).get(); 19 | 20 | Future deleteByPreKeyId(int signedPreKeyId) => 21 | (delete(db.signedPrekeys) 22 | ..where((tbl) => tbl.prekeyId.equals(signedPreKeyId))).go(); 23 | 24 | Future insert(SignedPrekeysCompanion signedPreKey) => into( 25 | db.signedPrekeys, 26 | ).insert(signedPreKey, mode: InsertMode.insertOrReplace); 27 | } 28 | -------------------------------------------------------------------------------- /lib/crypto/signal/dao/signed_pre_key_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'signed_pre_key_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$SignedPreKeyDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/encrypt_result.dart: -------------------------------------------------------------------------------- 1 | class EncryptResult { 2 | EncryptResult(this.result, this.err); 3 | 4 | final String? result; 5 | final bool err; 6 | } 7 | -------------------------------------------------------------------------------- /lib/crypto/signal/identity_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; 2 | 3 | import 'signal_database.dart'; 4 | 5 | extension IdentityExtension on Identity { 6 | IdentityKey getIdentityKey() => IdentityKey.fromBytes(publicKey, 0); 7 | 8 | IdentityKeyPair getIdentityKeyPair() => IdentityKeyPair( 9 | IdentityKey.fromBytes(publicKey, 0), 10 | Curve.decodePrivatePoint(privateKey!), 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/identity.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; 2 | 3 | -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/pre_key.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/ratchet_sender_key.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/sender_key.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/session.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; -------------------------------------------------------------------------------- /lib/crypto/signal/moor/dao/signed_pre_key.drift: -------------------------------------------------------------------------------- 1 | import '../signal.drift'; -------------------------------------------------------------------------------- /lib/crypto/signal/ratchet_status.dart: -------------------------------------------------------------------------------- 1 | enum RatchetStatus { requesting } 2 | -------------------------------------------------------------------------------- /lib/db/converter/conversation_category_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | 4 | class ConversationCategoryTypeConverter 5 | extends TypeConverter { 6 | const ConversationCategoryTypeConverter(); 7 | 8 | @override 9 | ConversationCategory? fromSql(String? fromDb) => 10 | const ConversationCategoryJsonConverter().fromJson(fromDb); 11 | 12 | @override 13 | String? toSql(ConversationCategory? value) => 14 | const ConversationCategoryJsonConverter().toJson(value); 15 | } 16 | -------------------------------------------------------------------------------- /lib/db/converter/conversation_status_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | 4 | class ConversationStatusTypeConverter 5 | extends TypeConverter { 6 | const ConversationStatusTypeConverter(); 7 | 8 | @override 9 | ConversationStatus fromSql(int fromDb) => 10 | const ConversationStatusJsonConverter().fromJson(fromDb); 11 | 12 | @override 13 | int toSql(ConversationStatus value) => 14 | const ConversationStatusJsonConverter().toJson(value)!; 15 | } 16 | -------------------------------------------------------------------------------- /lib/db/converter/media_status_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | import 'package:recase/recase.dart'; 4 | 5 | import '../../enum/media_status.dart'; 6 | 7 | class MediaStatusTypeConverter extends TypeConverter { 8 | const MediaStatusTypeConverter(); 9 | 10 | @override 11 | MediaStatus? fromSql(String? fromDb) => 12 | fromStringToEnum(MediaStatus.values, fromDb); 13 | 14 | @override 15 | String? toSql(MediaStatus? value) => enumConvertToString(value)?.constantCase; 16 | } 17 | -------------------------------------------------------------------------------- /lib/db/converter/membership_converter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:drift/drift.dart'; 4 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 5 | import 'package:mixin_logger/mixin_logger.dart'; 6 | 7 | class MembershipConverter extends TypeConverter { 8 | const MembershipConverter(); 9 | 10 | @override 11 | Membership? fromSql(String? fromDb) { 12 | if (fromDb == null) { 13 | return null; 14 | } 15 | try { 16 | final json = jsonDecode(fromDb) as Map; 17 | return Membership.fromJson(json); 18 | } catch (error, stackTrace) { 19 | e('failed to decode membership', error, stackTrace); 20 | return null; 21 | } 22 | } 23 | 24 | @override 25 | String? toSql(Membership? value) { 26 | if (value == null) { 27 | return null; 28 | } 29 | return jsonEncode(value.toJson()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/db/converter/message_status_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | import 'package:recase/recase.dart'; 4 | 5 | class MessageStatusTypeConverter extends TypeConverter { 6 | const MessageStatusTypeConverter(); 7 | 8 | @override 9 | MessageStatus fromSql(String fromDb) => 10 | fromStringToEnum(MessageStatus.values, fromDb) ?? MessageStatus.failed; 11 | 12 | @override 13 | String toSql(MessageStatus value) => enumConvertToString(value)!.constantCase; 14 | } 15 | -------------------------------------------------------------------------------- /lib/db/converter/millis_date_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | class MillisDateConverter extends TypeConverter { 4 | const MillisDateConverter(); 5 | 6 | @override 7 | DateTime fromSql(int fromDb) => 8 | DateTime.fromMillisecondsSinceEpoch(fromDb, isUtc: true); 9 | 10 | @override 11 | int toSql(DateTime value) => value.millisecondsSinceEpoch; 12 | } 13 | -------------------------------------------------------------------------------- /lib/db/converter/participant_role_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | 4 | class ParticipantRoleConverter 5 | extends TypeConverter { 6 | const ParticipantRoleConverter(); 7 | 8 | @override 9 | ParticipantRole? fromSql(String? fromDb) => 10 | const ParticipantRoleJsonConverter().fromJson(fromDb); 11 | 12 | @override 13 | String? toSql(ParticipantRole? value) => 14 | const ParticipantRoleJsonConverter().toJson(value); 15 | } 16 | -------------------------------------------------------------------------------- /lib/db/converter/property_group_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../../enum/property_group.dart'; 4 | 5 | class PropertyGroupConverter extends TypeConverter { 6 | const PropertyGroupConverter(); 7 | 8 | @override 9 | PropertyGroup fromSql(String fromDb) => PropertyGroup.values.byName(fromDb); 10 | 11 | @override 12 | String toSql(PropertyGroup value) => value.name; 13 | } 14 | -------------------------------------------------------------------------------- /lib/db/converter/safe_deposit_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:drift/drift.dart'; 4 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 5 | import 'package:mixin_logger/mixin_logger.dart'; 6 | 7 | class SafeDepositTypeConverter extends TypeConverter { 8 | const SafeDepositTypeConverter(); 9 | 10 | @override 11 | SafeDeposit? fromSql(String? fromDb) { 12 | if (fromDb == null) { 13 | return null; 14 | } 15 | try { 16 | final json = jsonDecode(fromDb) as Map; 17 | return SafeDeposit.fromJson(json); 18 | } catch (error, stackTrace) { 19 | e('failed to decode safe deposit', error, stackTrace); 20 | return null; 21 | } 22 | } 23 | 24 | @override 25 | String? toSql(SafeDeposit? value) { 26 | if (value == null) { 27 | return null; 28 | } 29 | return jsonEncode(value.toJson()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/db/converter/safe_withdrawal_type_converter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:drift/drift.dart'; 4 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 5 | import 'package:mixin_logger/mixin_logger.dart'; 6 | 7 | class SafeWithdrawalTypeConverter 8 | extends TypeConverter { 9 | const SafeWithdrawalTypeConverter(); 10 | 11 | @override 12 | SafeWithdrawal? fromSql(String? fromDb) { 13 | if (fromDb == null) { 14 | return null; 15 | } 16 | try { 17 | final json = jsonDecode(fromDb) as Map; 18 | return SafeWithdrawal.fromJson(json); 19 | } catch (error, stackTrace) { 20 | e('failed to decode safe withdrawal', error, stackTrace); 21 | return null; 22 | } 23 | } 24 | 25 | @override 26 | String? toSql(SafeWithdrawal? value) { 27 | if (value == null) { 28 | return null; 29 | } 30 | return jsonEncode(value.toJson()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/db/converter/user_relationship_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 3 | 4 | class UserRelationshipConverter 5 | extends TypeConverter { 6 | const UserRelationshipConverter(); 7 | 8 | @override 9 | UserRelationship? fromSql(String? fromDb) => 10 | const UserRelationshipJsonConverter().fromJson(fromDb); 11 | 12 | @override 13 | String? toSql(UserRelationship? value) => 14 | const UserRelationshipJsonConverter().toJson(value); 15 | } 16 | -------------------------------------------------------------------------------- /lib/db/dao/address_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../mixin_database.dart'; 4 | 5 | part 'address_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class AddressDao extends DatabaseAccessor 9 | with _$AddressDaoMixin { 10 | AddressDao(super.db); 11 | 12 | Future> getAll() => select(db.addresses).get(); 13 | 14 | Future insert(Address address) => 15 | into(db.addresses).insertOnConflictUpdate(address); 16 | 17 | Future deleteAddress(Address address) => delete(db.addresses).delete(address); 18 | } 19 | -------------------------------------------------------------------------------- /lib/db/dao/address_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'address_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$AddressDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/app_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'app_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$AppDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/chain_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart' as sdk; 3 | 4 | import '../mixin_database.dart'; 5 | 6 | part 'chain_dao.g.dart'; 7 | 8 | extension ChainConverter on sdk.Chain { 9 | ChainsCompanion get asChainsCompanion => ChainsCompanion.insert( 10 | chainId: chainId, 11 | name: name, 12 | symbol: symbol, 13 | iconUrl: iconUrl, 14 | threshold: threshold, 15 | ); 16 | } 17 | 18 | @DriftAccessor(include: {'../moor/dao/chain.drift'}) 19 | class ChainDao extends DatabaseAccessor with _$ChainDaoMixin { 20 | ChainDao(super.db); 21 | 22 | Future insertSdkChain(sdk.Chain chain) => 23 | into(db.chains).insertOnConflictUpdate(chain.asChainsCompanion); 24 | 25 | SimpleSelectStatement chain(String chainId) => 26 | select(db.chains) 27 | ..where((t) => t.chainId.equals(chainId)) 28 | ..limit(1); 29 | } 30 | -------------------------------------------------------------------------------- /lib/db/dao/fiat_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart' as sdk; 3 | 4 | import '../mixin_database.dart'; 5 | 6 | part 'fiat_dao.g.dart'; 7 | 8 | @DriftAccessor() 9 | class FiatDao extends DatabaseAccessor with _$FiatDaoMixin { 10 | FiatDao(super.db); 11 | 12 | Future insertAllSdkFiat(List fiats) async { 13 | await db.delete(db.fiats).go(); 14 | await db.batch((batch) { 15 | batch.insertAllOnConflictUpdate( 16 | db.fiats, 17 | fiats 18 | .map( 19 | (fiat) => FiatsCompanion.insert(code: fiat.code, rate: fiat.rate), 20 | ) 21 | .toList(), 22 | ); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/db/dao/fiat_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'fiat_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$FiatDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/hyperlink_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../mixin_database.dart'; 4 | 5 | part 'hyperlink_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class HyperlinkDao extends DatabaseAccessor 9 | with _$HyperlinkDaoMixin { 10 | HyperlinkDao(super.db); 11 | 12 | Future insert(Hyperlink hyperlink) => 13 | into(db.hyperlinks).insertOnConflictUpdate(hyperlink); 14 | 15 | Future deleteHyperlink(Hyperlink hyperlink) => 16 | delete(db.hyperlinks).delete(hyperlink); 17 | } 18 | -------------------------------------------------------------------------------- /lib/db/dao/hyperlink_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'hyperlink_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$HyperlinkDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/job_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'job_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$JobDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/message_history_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'message_history_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$MessageHistoryDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/message_mention_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'message_mention_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$MessageMentionDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/offset_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../../constants/constants.dart'; 4 | import '../mixin_database.dart'; 5 | 6 | part 'offset_dao.g.dart'; 7 | 8 | @DriftAccessor() 9 | class OffsetDao extends DatabaseAccessor with _$OffsetDaoMixin { 10 | OffsetDao(super.db); 11 | 12 | Future insert(Offset offset) => 13 | into(db.offsets).insertOnConflictUpdate(offset); 14 | 15 | Future deleteOffset(Offset offset) => delete(db.offsets).delete(offset); 16 | 17 | Selectable findStatusOffset() => (select(db.offsets) 18 | ..where((tbl) => tbl.key.equals(statusOffset))).map((row) => row.timestamp); 19 | } 20 | -------------------------------------------------------------------------------- /lib/db/dao/offset_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'offset_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$OffsetDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/resend_session_message_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'resend_session_message_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$ResendSessionMessageDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/dao/sent_session_sender_key_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | import '../mixin_database.dart'; 4 | 5 | part 'sent_session_sender_key_dao.g.dart'; 6 | 7 | @DriftAccessor() 8 | class SentSessionSenderKeyDao extends DatabaseAccessor 9 | with _$SentSessionSenderKeyDaoMixin { 10 | SentSessionSenderKeyDao(super.db); 11 | 12 | Future insert(SentSessionSenderKey key) => 13 | into(db.sentSessionSenderKeys).insertOnConflictUpdate(key); 14 | 15 | Future deleteSentSessionSenderKey(SentSessionSenderKey key) => 16 | delete(db.sentSessionSenderKeys).delete(key); 17 | } 18 | -------------------------------------------------------------------------------- /lib/db/dao/sent_session_sender_key_dao.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'sent_session_sender_key_dao.dart'; 4 | 5 | // ignore_for_file: type=lint 6 | mixin _$SentSessionSenderKeyDaoMixin on DatabaseAccessor {} 7 | -------------------------------------------------------------------------------- /lib/db/extension/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:mixin_logger/mixin_logger.dart'; 2 | 3 | import '../mixin_database.dart'; 4 | 5 | List? _parseFromString(String? content) { 6 | if (content == null) { 7 | return null; 8 | } 9 | try { 10 | var str = content.trim(); 11 | if (str.startsWith('[')) { 12 | str = str.substring(1); 13 | } 14 | if (str.endsWith(']')) { 15 | str = str.substring(0, str.length - 1); 16 | } 17 | return str 18 | .trim() 19 | .split(',') 20 | .map((e) => e.trim()) 21 | .where((element) => element.isNotEmpty) 22 | .toList(); 23 | } catch (error, stacktrace) { 24 | e('parseFromString error: $error, stacktrace: $stacktrace'); 25 | return null; 26 | } 27 | } 28 | 29 | extension AppExt on App { 30 | List? get capabilitiesList => _parseFromString(capabilities); 31 | 32 | List? get resourcePatternsList => _parseFromString(resourcePatterns); 33 | } 34 | -------------------------------------------------------------------------------- /lib/db/extension/db.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | extension InsertStatementExt on InsertStatement { 4 | Future simpleInsert( 5 | Insertable entity, { 6 | bool updateIfConflict = true, 7 | }) { 8 | if (updateIfConflict) { 9 | return insertOnConflictUpdate(entity); 10 | } else { 11 | return insert(entity, mode: InsertMode.insertOrIgnore); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/db/extension/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart' hide User; 2 | 3 | import '../mixin_database.dart'; 4 | 5 | extension UserExtension on User { 6 | static bool isBotIdentityNumber(String identityNumber) { 7 | final number = int.tryParse(identityNumber) ?? 0; 8 | return (number > 7000000000 && number < 8000000000) || number == 7000; 9 | } 10 | 11 | bool get isBot => UserExtension.isBotIdentityNumber(identityNumber); 12 | 13 | bool get isStranger => relationship == UserRelationship.stranger; 14 | } 15 | -------------------------------------------------------------------------------- /lib/db/moor/dao/asset.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | assetItem as AssetItem: 4 | SELECT asset.*, 5 | chain.symbol AS chainSymbol, 6 | chain.icon_url AS chainIconUrl, 7 | chain.name as chainName, 8 | chain.threshold as chainThreshold 9 | FROM assets asset 10 | LEFT JOIN chains chain ON asset.chain_id = chain.chain_id 11 | WHERE asset.asset_id = :assetId 12 | LIMIT 1; 13 | 14 | countAssets: 15 | SELECT COUNT(1) FROM assets; 16 | -------------------------------------------------------------------------------- /lib/db/moor/dao/chain.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | -------------------------------------------------------------------------------- /lib/db/moor/dao/circle_conversation.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | _deleteByCircleId: 4 | DELETE FROM circle_conversations WHERE circle_id = :circleId; 5 | 6 | _deleteByIds: 7 | DELETE FROM circle_conversations WHERE conversation_id = :conversationId AND circle_id = :circleId; 8 | -------------------------------------------------------------------------------- /lib/db/moor/dao/expired_message.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | getExpiredMessages: 4 | SELECT * FROM expired_messages WHERE expire_at <= :currentTime ORDER BY expire_at ASC; 5 | 6 | getFirstExpiredMessage: 7 | SELECT * FROM expired_messages WHERE expire_at IS NOT NULL ORDER BY expire_at ASC LIMIT 1; 8 | 9 | updateMessageExpireAt: 10 | UPDATE expired_messages SET expire_at = :expireAt WHERE message_id = :messageId AND (expire_at IS NULL || expire_at > :expireAt); 11 | 12 | _markExpiredMessageRead: 13 | UPDATE expired_messages SET expire_at = CAST((:currentTime + expire_in) AS INTEGER) WHERE (expire_at > (:currentTime + expire_in) OR expire_at IS NULL) AND $where; 14 | 15 | getExpiredMessageById: 16 | SELECT * FROM expired_messages WHERE message_id = :messageId; 17 | 18 | getAllExpiredMessages: 19 | SELECT * FROM expired_messages ORDER BY rowid ASC LIMIT :limit OFFSET :offset; 20 | 21 | countExpiredMessages: 22 | SELECT COUNT(1) FROM expired_messages; 23 | -------------------------------------------------------------------------------- /lib/db/moor/dao/favorite_app.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | _deleteFavoriteAppByUserId: 4 | DELETE FROM favorite_apps WHERE user_id = :userId; 5 | 6 | getFavoriteAppsByUserId: 7 | SELECT a.* FROM favorite_apps fa INNER JOIN apps a ON fa.app_id = a.app_id WHERE fa.user_id =:userId; 8 | -------------------------------------------------------------------------------- /lib/db/moor/dao/flood.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | _getLastBlazeMessageCreatedAt: 4 | SELECT created_at FROM flood_messages ORDER BY created_at DESC limit 1; 5 | -------------------------------------------------------------------------------- /lib/db/moor/dao/inscription_collection.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | -------------------------------------------------------------------------------- /lib/db/moor/dao/inscription_item.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | import '../../vo/inscription.dart'; 3 | 4 | inscriptionByHash WITH Inscription: 5 | SELECT i.collection_hash, i.inscription_hash, ic.name, i.sequence, i.content_type, 6 | i.content_url, ic.icon_url 7 | FROM inscription_items i 8 | LEFT JOIN 9 | inscription_collections ic on ic.collection_hash = i.collection_hash 10 | WHERE inscription_hash = :hash; -------------------------------------------------------------------------------- /lib/db/moor/dao/participant_session.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | participantSessionKeyWithoutSelf AS ParticipantSessionKey: 4 | SELECT conversation_id, user_id, session_id, public_key FROM participant_session WHERE conversation_id = :conversationId AND user_id != :userId LIMIT 1; 5 | 6 | otherParticipantSessionKey AS ParticipantSessionKey: 7 | SELECT conversation_id, user_id, session_id, public_key FROM participant_session WHERE conversation_id = :conversationId AND user_id == :userId AND session_id != :sessionId ORDER BY created_at DESC LIMIT 1; 8 | 9 | notSendSessionParticipants: 10 | SELECT p.* FROM participant_session p LEFT JOIN users u ON p.user_id = u.user_id WHERE p.conversation_id = :conversationId AND p.session_id != :sessionId AND u.app_id IS NULL AND p.sent_to_server IS NULL; 11 | -------------------------------------------------------------------------------- /lib/db/moor/dao/pin_message.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | pinMessageItem: 4 | SELECT 5 | message.content AS content, 6 | sender.full_name AS userFullName 7 | FROM messages message 8 | INNER JOIN pin_messages pinMessage ON :messageId = pinMessage.message_id 9 | INNER JOIN users sender ON message.user_id = sender.user_id 10 | WHERE message.conversation_id = :conversationId AND message.category = 'MESSAGE_PIN' AND message.quote_message_id = :messageId 11 | ORDER BY message.created_at DESC 12 | LIMIT 1; 13 | 14 | pinMessageIds: 15 | SELECT pinMessage.message_id FROM pin_messages pinMessage 16 | INNER JOIN messages message ON message.message_id = pinMessage.message_id 17 | WHERE pinMessage.conversation_id = :conversationId 18 | ORDER BY message.created_at DESC; 19 | 20 | countPinMessages: 21 | SELECT COUNT(1) FROM pin_messages; 22 | -------------------------------------------------------------------------------- /lib/db/moor/dao/property.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | -------------------------------------------------------------------------------- /lib/db/moor/dao/safe_snapshot.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | _snapshotItem AS SafeSnapshotItem: 4 | SELECT s.snapshot_id, s.type, s.asset_id, s.amount, s.created_at, s.opponent_id, s.trace_id, s.memo, s.confirmations, 5 | s.transaction_hash, s.opening_balance, s.closing_balance, u.avatar_url, u.full_name AS opponent_ful_name, 6 | t.symbol AS asset_symbol, t.confirmations AS asset_confirmations 7 | FROM safe_snapshots s 8 | LEFT JOIN users u ON u.user_id = s.opponent_id 9 | LEFT JOIN tokens t ON t.asset_id = s.asset_id 10 | WHERE $where 11 | ORDER BY $order 12 | LIMIT $limit; 13 | 14 | deletePendingSnapshotByHash: 15 | DELETE FROM safe_snapshots WHERE type = 'pending' AND deposit LIKE '%' || :transactionHash || '%' ESCAPE '\'; 16 | 17 | countSnapshots: 18 | SELECT COUNT(1) FROM safe_snapshots; 19 | -------------------------------------------------------------------------------- /lib/db/moor/dao/snapshot.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | snapshotItems(:currentFiat AS TEXT) AS SnapshotItem: 4 | SELECT 5 | snapshot.*, 6 | opponent.avatar_url, 7 | opponent.full_name AS opponent_ful_name, 8 | asset.price_usd, 9 | asset.chain_id, 10 | asset.symbol, 11 | asset.name AS symbolName, 12 | asset.tag, 13 | asset.confirmations AS asset_confirmations, 14 | asset.icon_url AS symbolIconUrl, 15 | chain.icon_url AS chainIconUrl, 16 | fiat.rate AS fiatRate 17 | FROM snapshots snapshot 18 | LEFT JOIN users opponent ON opponent.user_id = snapshot.opponent_id 19 | LEFT JOIN assets asset ON asset.asset_id = snapshot.asset_id 20 | LEFT JOIN chains chain ON asset.chain_id = chain.chain_id 21 | LEFT JOIN fiats fiat ON fiat.code = :currentFiat 22 | WHERE $where 23 | ORDER BY $order 24 | LIMIT $limit; 25 | 26 | 27 | countSnapshots: 28 | SELECT COUNT(1) FROM snapshots; -------------------------------------------------------------------------------- /lib/db/moor/dao/sticker.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | recentUsedStickers: 4 | SELECT * FROM stickers WHERE last_use_at > 0 ORDER BY last_use_at DESC LIMIT 20; 5 | 6 | _stickersByCategory: 7 | SELECT s.* 8 | FROM sticker_albums sa 9 | INNER JOIN sticker_relationships sr 10 | ON sr.album_id = sa.album_id 11 | INNER JOIN stickers s 12 | ON sr.sticker_id = s.sticker_id 13 | WHERE sa.category = :category 14 | ORDER BY s.created_at DESC; 15 | 16 | countStickers: 17 | SELECT COUNT(1) FROM stickers; 18 | -------------------------------------------------------------------------------- /lib/db/moor/dao/sticker_album.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | -------------------------------------------------------------------------------- /lib/db/moor/dao/sticker_relationship.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | stickerSystemAlbumId: 4 | SELECT sa.album_id FROM sticker_relationships sr INNER JOIN sticker_albums sa ON sr.album_id = sa.album_id WHERE sr.sticker_id = :stickerId AND sa.category = 'SYSTEM' LIMIT 1; 5 | 6 | stickerSystemAlbum: 7 | SELECT sa.* FROM sticker_relationships sr INNER JOIN sticker_albums sa ON sr.album_id = sa.album_id WHERE sr.sticker_id = :stickerId AND sa.category = 'SYSTEM' LIMIT 1; 8 | 9 | -------------------------------------------------------------------------------- /lib/db/moor/dao/token.drift: -------------------------------------------------------------------------------- 1 | import '../mixin.drift'; 2 | 3 | countAssets: 4 | SELECT COUNT(1) FROM tokens; 5 | -------------------------------------------------------------------------------- /lib/db/util/util.dart: -------------------------------------------------------------------------------- 1 | import 'package:drift/drift.dart'; 2 | 3 | final maxLimit = _MaxLimit(); 4 | 5 | class _MaxLimit extends Limit { 6 | _MaxLimit() : super(0, null); 7 | 8 | @override 9 | void writeInto(GenerationContext context) { 10 | // do nothing; 11 | } 12 | } 13 | 14 | const ignoreWhere = CustomExpression('true'); 15 | 16 | const ignoreOrderBy = OrderBy([]); 17 | -------------------------------------------------------------------------------- /lib/enum/media_status.dart: -------------------------------------------------------------------------------- 1 | import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; 2 | 3 | enum MediaStatus { pending, done, canceled, expired, read } 4 | 5 | class MediaStatusJsonConverter extends EnumJsonConverter { 6 | const MediaStatusJsonConverter(); 7 | 8 | @override 9 | List enumValues() => MediaStatus.values; 10 | } 11 | -------------------------------------------------------------------------------- /lib/enum/message_action.dart: -------------------------------------------------------------------------------- 1 | class MessageAction { 2 | static const String join = 'JOIN'; 3 | static const String exit = 'EXIT'; 4 | static const String add = 'ADD'; 5 | static const String remove = 'REMOVE'; 6 | static const String create = 'CREATE'; 7 | static const String update = 'UPDATE'; 8 | static const String role = 'ROLE'; 9 | static const String expire = 'EXPIRE'; 10 | } 11 | -------------------------------------------------------------------------------- /lib/enum/property_group.dart: -------------------------------------------------------------------------------- 1 | enum PropertyGroup { setting } 2 | -------------------------------------------------------------------------------- /lib/enum/system_circle_action.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | enum SystemCircleAction { 4 | @JsonValue('CREATE') 5 | create, 6 | @JsonValue('DELETE') 7 | delete, 8 | @JsonValue('UPDATE') 9 | update, 10 | @JsonValue('ADD') 11 | add, 12 | @JsonValue('REMOVE') 13 | remove, 14 | } 15 | -------------------------------------------------------------------------------- /lib/enum/system_session_action.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | enum SystemSessionAction { 4 | @JsonValue('PROVISION') 5 | provision, 6 | @JsonValue('DESTROY') 7 | destroy, 8 | } 9 | -------------------------------------------------------------------------------- /lib/enum/system_user_action.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | enum SystemUserAction { 4 | @JsonValue('UPDATE') 5 | update, 6 | } 7 | -------------------------------------------------------------------------------- /lib/ui/home/bloc/subscriber_mixin.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:hooks_riverpod/hooks_riverpod.dart'; 4 | 5 | mixin SubscriberMixin on StateNotifier { 6 | List subscriptions = []; 7 | 8 | void addSubscription(StreamSubscription? streamSubscription) => 9 | subscriptions.add(streamSubscription); 10 | 11 | @override 12 | void dispose() { 13 | subscriptions 14 | ..forEach((element) => element?.cancel()) 15 | ..clear(); 16 | super.dispose(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/ui/home/command_palette_wrapper.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | import '../../utils/platform.dart'; 5 | import '../../widgets/actions/actions.dart'; 6 | 7 | class CommandPaletteWrapper extends StatelessWidget { 8 | const CommandPaletteWrapper({required this.child, super.key}); 9 | 10 | final Widget child; 11 | 12 | @override 13 | Widget build(BuildContext context) => FocusableActionDetector( 14 | shortcuts: { 15 | SingleActivator( 16 | LogicalKeyboardKey.keyK, 17 | meta: kPlatformIsDarwin, 18 | control: !kPlatformIsDarwin, 19 | ): 20 | const ToggleCommandPaletteIntent(), 21 | }, 22 | child: child, 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/ui/home/intent.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class ListSelectionNextIntent extends Intent { 4 | const ListSelectionNextIntent(); 5 | } 6 | 7 | class ListSelectionPrevIntent extends Intent { 8 | const ListSelectionPrevIntent(); 9 | } 10 | 11 | class ListSelectionSelectedIntent extends Intent { 12 | const ListSelectionSelectedIntent(); 13 | } 14 | -------------------------------------------------------------------------------- /lib/ui/landing/bloc/landing_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | enum LandingStatus { needReload, provisioning, ready, init } 4 | 5 | class LandingState extends Equatable { 6 | const LandingState({ 7 | this.authUrl, 8 | this.status = LandingStatus.init, 9 | this.errorMessage, 10 | }); 11 | 12 | final String? authUrl; 13 | final LandingStatus status; 14 | 15 | final String? errorMessage; 16 | 17 | @override 18 | List get props => [authUrl, status, errorMessage]; 19 | 20 | LandingState needReload(String errorMessage) => LandingState( 21 | status: LandingStatus.needReload, 22 | errorMessage: errorMessage, 23 | authUrl: authUrl, 24 | ); 25 | 26 | LandingState copyWith({String? authUrl, LandingStatus? status}) => 27 | LandingState( 28 | authUrl: authUrl ?? this.authUrl, 29 | status: status ?? this.status, 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /lib/ui/provider/conversation_unseen_filter_enabled.dart: -------------------------------------------------------------------------------- 1 | import 'package:hooks_riverpod/hooks_riverpod.dart'; 2 | import '../../utils/rivepod.dart'; 3 | 4 | class ConversationUnseenFilterEnabledNotifier 5 | extends DistinctStateNotifier { 6 | ConversationUnseenFilterEnabledNotifier() : super(false); 7 | 8 | void toggle() => state = !state; 9 | 10 | void reset() => state = false; 11 | } 12 | 13 | final conversationUnseenFilterEnabledProvider = 14 | StateNotifierProvider( 15 | (ref) => ConversationUnseenFilterEnabledNotifier(), 16 | ); 17 | -------------------------------------------------------------------------------- /lib/ui/provider/keyword_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:hooks_riverpod/hooks_riverpod.dart'; 2 | 3 | final keywordProvider = StateProvider((ref) => ''); 4 | final trimmedKeywordProvider = keywordProvider.select((value) => value.trim()); 5 | final hasKeywordProvider = trimmedKeywordProvider.select( 6 | (value) => value.isNotEmpty, 7 | ); 8 | -------------------------------------------------------------------------------- /lib/ui/provider/pending_jump_message_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:hooks_riverpod/hooks_riverpod.dart'; 2 | 3 | import 'conversation_provider.dart'; 4 | 5 | final pendingJumpMessageProvider = StateProvider.autoDispose((ref) { 6 | final keepAlive = ref.keepAlive(); 7 | 8 | ref.listen(currentConversationIdProvider, (previous, next) { 9 | keepAlive.close(); 10 | ref.invalidateSelf(); 11 | }); 12 | 13 | return null; 14 | }); 15 | -------------------------------------------------------------------------------- /lib/ui/provider/recent_conversation_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:hooks_riverpod/hooks_riverpod.dart'; 4 | import '../../utils/rivepod.dart'; 5 | 6 | class RecentConversationIDsNotifier 7 | extends DistinctStateNotifier> { 8 | RecentConversationIDsNotifier() : super([]); 9 | 10 | void add(String conversationId) { 11 | final newList = 12 | ([...state] 13 | ..remove(conversationId) 14 | ..add(conversationId)); 15 | if (newList.isEmpty) return; 16 | 17 | state = newList.sublist(max(newList.length - 5, 0), newList.length); 18 | } 19 | 20 | List get reversedState => state.reversed.toList(); 21 | } 22 | 23 | final recentConversationIDsProvider = StateNotifierProvider.autoDispose< 24 | RecentConversationIDsNotifier, 25 | List 26 | >((ref) { 27 | ref.keepAlive(); 28 | return RecentConversationIDsNotifier(); 29 | }); 30 | -------------------------------------------------------------------------------- /lib/utils/action_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | import '../ui/provider/conversation_provider.dart'; 4 | import 'extension/extension.dart'; 5 | 6 | extension OpenUriExtension on BuildContext { 7 | bool openAction(String actionText) { 8 | if (actionText.startsWith('input:')) { 9 | final content = actionText.substring(6).trim(); 10 | final conversationItem = providerContainer.read(conversationProvider); 11 | if (content.isNotEmpty && conversationItem != null) { 12 | accountServer.sendTextMessage( 13 | content, 14 | conversationItem.encryptCategory, 15 | conversationId: conversationItem.conversationId, 16 | ); 17 | } 18 | 19 | return true; 20 | } 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/utils/app_lifecycle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | final _appObserver = _AppLifecycleObserver(); 4 | 5 | void initAppLifecycleObserver() { 6 | WidgetsFlutterBinding.ensureInitialized(); 7 | WidgetsBinding.instance.addObserver(_appObserver); 8 | } 9 | 10 | /// Check if app is on foreground. 11 | bool get isAppActive => _appObserver._isActive.value; 12 | 13 | ValueNotifier get appActiveListener => _appObserver._isActive; 14 | 15 | class _AppLifecycleObserver extends WidgetsBindingObserver { 16 | final _isActive = ValueNotifier(true); 17 | 18 | var _initialized = false; 19 | 20 | void initIfNeed() { 21 | if (_initialized) { 22 | return; 23 | } 24 | _initialized = true; 25 | WidgetsBinding.instance.addObserver(this); 26 | } 27 | 28 | @override 29 | void didChangeAppLifecycleState(AppLifecycleState state) { 30 | _isActive.value = state == AppLifecycleState.resumed; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/utils/attachment/download_key_value.dart: -------------------------------------------------------------------------------- 1 | import '../hive_key_values.dart'; 2 | 3 | class DownloadKeyValue extends HiveKeyValue { 4 | DownloadKeyValue._() : super(_hiveName); 5 | 6 | static DownloadKeyValue? _instance; 7 | 8 | static DownloadKeyValue get instance => _instance ??= DownloadKeyValue._(); 9 | 10 | static const _hiveName = 'download_box'; 11 | 12 | Iterable get messageIds => box.values; 13 | 14 | Future addMessageId(String messageId) => box.put(messageId, messageId); 15 | 16 | Future removeMessageId(String messageId) => box.delete(messageId); 17 | 18 | Future clear() => box.clear(); 19 | } 20 | -------------------------------------------------------------------------------- /lib/utils/auto_update_checker.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/utils/device_transfer/transfer_data_expired_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'transfer_data_expired_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TransferDataExpiredMessage _$TransferDataExpiredMessageFromJson( 10 | Map json, 11 | ) => TransferDataExpiredMessage( 12 | messageId: json['message_id'] as String, 13 | expireIn: (json['expire_in'] as num).toInt(), 14 | expireAt: (json['expire_at'] as num?)?.toInt(), 15 | ); 16 | 17 | Map _$TransferDataExpiredMessageToJson( 18 | TransferDataExpiredMessage instance, 19 | ) => { 20 | 'message_id': instance.messageId, 21 | 'expire_in': instance.expireIn, 22 | 'expire_at': instance.expireAt, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/utils/device_transfer/transfer_data_pin_message.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'transfer_data_pin_message.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TransferDataPinMessage _$TransferDataPinMessageFromJson( 10 | Map json, 11 | ) => TransferDataPinMessage( 12 | messageId: json['message_id'] as String, 13 | conversationId: json['conversation_id'] as String, 14 | createdAt: DateTime.parse(json['created_at'] as String), 15 | ); 16 | 17 | Map _$TransferDataPinMessageToJson( 18 | TransferDataPinMessage instance, 19 | ) => { 20 | 'message_id': instance.messageId, 21 | 'conversation_id': instance.conversationId, 22 | 'created_at': instance.createdAt.toIso8601String(), 23 | }; 24 | -------------------------------------------------------------------------------- /lib/utils/double_tap_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:ui'; 3 | 4 | Map _timers = {}; 5 | 6 | void doubleTap(String tag, Duration duration, VoidCallback onExecute) { 7 | final timer = _timers[tag]; 8 | 9 | if (duration == Duration.zero) { 10 | timer?.cancel(); 11 | _timers.remove(tag); 12 | onExecute(); 13 | } else { 14 | if (timer != null && timer.isActive) { 15 | onExecute(); 16 | } 17 | 18 | _timers.remove(tag); 19 | timer?.cancel(); 20 | 21 | _timers[tag] = Timer(duration, () { 22 | _timers.remove(tag); 23 | timer?.cancel(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/utils/extension/src/image.dart: -------------------------------------------------------------------------------- 1 | part of '../extension.dart'; 2 | 3 | extension ImageProviderExtension on ImageProvider { 4 | Future toImage({ 5 | ImageConfiguration configuration = ImageConfiguration.empty, 6 | }) { 7 | final completer = Completer(); 8 | late ImageStreamListener listener; 9 | final stream = resolve(configuration); 10 | listener = ImageStreamListener((ImageInfo frame, bool sync) { 11 | final image = frame.image; 12 | completer.complete(image); 13 | stream.removeListener(listener); 14 | }); 15 | stream.addListener(listener); 16 | return completer.future; 17 | } 18 | } 19 | 20 | extension ImageExtension on ui.Image { 21 | Future toBytes({ 22 | ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba, 23 | }) async => (await toByteData(format: format))?.buffer.asUint8List(); 24 | } 25 | -------------------------------------------------------------------------------- /lib/utils/extension/src/info.dart: -------------------------------------------------------------------------------- 1 | part of '../extension.dart'; 2 | 3 | extension PackageInfoExtension on PackageInfo { 4 | String get versionAndBuildNumber => 5 | '${this.version}${buildNumber.isEmpty ? '' : '($buildNumber)'}'; 6 | } 7 | -------------------------------------------------------------------------------- /lib/utils/extension/src/markdown.dart: -------------------------------------------------------------------------------- 1 | part of '../extension.dart'; 2 | 3 | extension MarkdownExtension on String { 4 | String postLengthOptimize([int target = 1024]) => 5 | length > target ? substring(0, target) : this; 6 | 7 | String postOptimize([int lines = 10]) => 8 | LineSplitter.split(this).take(lines).join('\r\n').postLengthOptimize(); 9 | 10 | String get postOptimizeMarkdown { 11 | final lines = const LineSplitter().convert(postOptimize()); 12 | final astNodes = Document().parseLines(lines); 13 | return astNodes 14 | .map((e) => e.textContent) 15 | .join() 16 | .replaceAll(RegExp(r'\s+'), ' '); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/utils/extension/src/platforms.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | extension PlatformContextExtension on BuildContext { 6 | bool get textFieldAutoGainFocus => 7 | Platform.isWindows || Platform.isMacOS || Platform.isLinux; 8 | } 9 | -------------------------------------------------------------------------------- /lib/utils/extension/src/regexp.dart: -------------------------------------------------------------------------------- 1 | part of '../extension.dart'; 2 | 3 | extension RegExpExtension on RegExp { 4 | Iterable allMatchesAndSort(String input, [int start = 0]) => 5 | allMatches(input, start).toList() 6 | ..sort((a, b) => b[0]!.length - a[0]!.length); 7 | } 8 | -------------------------------------------------------------------------------- /lib/utils/extension/src/ui.dart: -------------------------------------------------------------------------------- 1 | part of '../extension.dart'; 2 | 3 | extension TextRangeExtension on TextRange { 4 | bool get composed => start == end; 5 | } 6 | -------------------------------------------------------------------------------- /lib/utils/reg_exp_utils.dart: -------------------------------------------------------------------------------- 1 | final mentionRegExp = RegExp(r'@(\S*)$'); 2 | final mentionNumberRegExp = RegExp(r'@(\d{4,})'); 3 | final uriRegExp = RegExp( 4 | r'\b[a-zA-z+]+:(?://)?[\w-]+(?:\.[\w-]+)*(?:[\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?\b/?', 5 | ); 6 | final botNumberRegExp = RegExp(r'(? extends StateNotifier { 4 | DistinctStateNotifier(super.state); 5 | 6 | @override 7 | T get state => super.state; 8 | 9 | @override 10 | bool updateShouldNotify(T old, T current) => old != current; 11 | } 12 | -------------------------------------------------------------------------------- /lib/utils/sort.dart: -------------------------------------------------------------------------------- 1 | int Function(E a, E b) compareValuesBy(int Function(E) selector) => 2 | (E a, E b) => selector(a) - selector(b); 3 | -------------------------------------------------------------------------------- /lib/utils/synchronized.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | /// A single asynchronous lock implemented by future-chaining. 4 | class Lock { 5 | Future? _last; 6 | 7 | /// Waits for previous [synchronized]-calls on this [Lock] to complete, and 8 | /// then calls [block] before further [synchronized] calls are allowed. 9 | Future synchronized(FutureOr Function() block) { 10 | final previous = _last; 11 | // This completer may not be sync: It must complete just after 12 | // callBlockAndComplete completes. 13 | final blockCompleted = Completer(); 14 | _last = blockCompleted.future; 15 | 16 | Future callBlockAndComplete() => 17 | Future.sync(block).whenComplete(blockCompleted.complete); 18 | 19 | return previous != null 20 | ? previous.then((_) => callBlockAndComplete()) 21 | : callBlockAndComplete(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/utils/video.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:video_compress/video_compress.dart'; 4 | 5 | final IVideoCompress customVideoCompress = _CustomVideoCompress(); 6 | 7 | class _CustomVideoCompress extends IVideoCompress { 8 | _CustomVideoCompress() { 9 | if (RootIsolateToken.instance != null) { 10 | initProcessCallback(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/widgets/automatic_keep_alive_client_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class AutomaticKeepAliveClientWidget extends StatefulWidget { 4 | const AutomaticKeepAliveClientWidget({required this.child, super.key}); 5 | 6 | final Widget child; 7 | 8 | @override 9 | State createState() => 10 | _AutomaticKeepAliveClientWidgetState(); 11 | } 12 | 13 | class _AutomaticKeepAliveClientWidgetState 14 | extends State 15 | with AutomaticKeepAliveClientMixin { 16 | @override 17 | Widget build(BuildContext context) { 18 | super.build(context); 19 | return widget.child; 20 | } 21 | 22 | @override 23 | bool get wantKeepAlive => true; 24 | } 25 | -------------------------------------------------------------------------------- /lib/widgets/cache_lottie.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: implementation_imports 2 | 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:lottie/lottie.dart'; 5 | 6 | import '../utils/cache_client.dart'; 7 | import '../utils/proxy.dart'; 8 | 9 | const String cacheLottieFolderName = 'cache_lottie'; 10 | 11 | /// Cache Lottie to local storage 12 | @immutable 13 | class CachedNetworkLottie extends NetworkLottie { 14 | CachedNetworkLottie(super.url, {super.headers, this.proxyConfig}) 15 | : super(client: CacheClient(proxyConfig, cacheLottieFolderName)); 16 | 17 | final ProxyConfig? proxyConfig; 18 | } 19 | -------------------------------------------------------------------------------- /lib/widgets/disable.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class Disable extends StatelessWidget { 4 | const Disable({required this.child, super.key, this.disable = true}); 5 | 6 | final bool disable; 7 | final Widget child; 8 | 9 | @override 10 | Widget build(BuildContext context) => IgnorePointer( 11 | ignoring: disable, 12 | child: AnimatedOpacity( 13 | opacity: disable ? 0.4 : 1, 14 | duration: const Duration(milliseconds: 200), 15 | child: child, 16 | ), 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /lib/widgets/empty.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | import '../utils/extension/extension.dart'; 4 | 5 | class Empty extends StatelessWidget { 6 | const Empty({required this.text, super.key}); 7 | 8 | final String text; 9 | 10 | @override 11 | Widget build(BuildContext context) => Center( 12 | child: Text(text, style: TextStyle(color: context.theme.secondaryText)), 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/widgets/message/item/action/action_data.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'action_data.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ActionData _$ActionDataFromJson(Map json) => ActionData( 10 | json['label'] as String, 11 | json['color'] as String, 12 | json['action'] as String, 13 | ); 14 | 15 | Map _$ActionDataToJson(ActionData instance) => 16 | { 17 | 'label': instance.label, 18 | 'color': instance.color, 19 | 'action': instance.action, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/widgets/message/item/location/location_payload.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'location_payload.g.dart'; 5 | 6 | @JsonSerializable() 7 | class LocationPayload with EquatableMixin { 8 | LocationPayload({ 9 | required this.latitude, 10 | required this.longitude, 11 | this.name, 12 | this.address, 13 | this.venueType, 14 | }); 15 | 16 | factory LocationPayload.fromJson(Map json) => 17 | _$LocationPayloadFromJson(json); 18 | 19 | final double latitude; 20 | final double longitude; 21 | final String? name; 22 | final String? address; 23 | @JsonKey(name: 'venue_type') 24 | final String? venueType; 25 | 26 | Map toJson() => _$LocationPayloadToJson(this); 27 | 28 | @override 29 | List get props => [latitude, longitude, name, address, venueType]; 30 | } 31 | -------------------------------------------------------------------------------- /lib/widgets/message/send_message_dialog/attachment_extra.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'attachment_extra.g.dart'; 4 | 5 | @JsonSerializable() 6 | class AttachmentExtra { 7 | AttachmentExtra({ 8 | required this.attachmentId, 9 | this.messageId, 10 | this.shareable, 11 | this.createdAt, 12 | }); 13 | 14 | factory AttachmentExtra.fromJson(Map json) => 15 | _$AttachmentExtraFromJson(json); 16 | 17 | @JsonKey(name: 'attachment_id') 18 | String attachmentId; 19 | @JsonKey(name: 'message_id') 20 | String? messageId; 21 | @JsonKey(name: 'created_at') 22 | String? createdAt; 23 | 24 | bool? shareable; 25 | 26 | Map toJson() => _$AttachmentExtraToJson(this); 27 | } 28 | -------------------------------------------------------------------------------- /lib/widgets/message/send_message_dialog/attachment_extra.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'attachment_extra.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AttachmentExtra _$AttachmentExtraFromJson(Map json) => 10 | AttachmentExtra( 11 | attachmentId: json['attachment_id'] as String, 12 | messageId: json['message_id'] as String?, 13 | shareable: json['shareable'] as bool?, 14 | createdAt: json['created_at'] as String?, 15 | ); 16 | 17 | Map _$AttachmentExtraToJson(AttachmentExtra instance) => 18 | { 19 | 'attachment_id': instance.attachmentId, 20 | 'message_id': instance.messageId, 21 | 'created_at': instance.createdAt, 22 | 'shareable': instance.shareable, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/widgets/message/send_message_dialog/send_image_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import 'attachment_extra.dart'; 4 | 5 | part 'send_image_data.g.dart'; 6 | 7 | @JsonSerializable() 8 | class SendImageData { 9 | SendImageData({required this.url, this.attachmentExtra}); 10 | 11 | factory SendImageData.fromJson(Map json) => 12 | _$SendImageDataFromJson(json); 13 | 14 | @JsonKey(name: 'url') 15 | String url; 16 | @JsonKey(name: 'attachment_extra') 17 | AttachmentExtra? attachmentExtra; 18 | 19 | Map toJson() => _$SendImageDataToJson(this); 20 | } 21 | -------------------------------------------------------------------------------- /lib/widgets/message/send_message_dialog/send_image_data.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'send_image_data.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SendImageData _$SendImageDataFromJson(Map json) => 10 | SendImageData( 11 | url: json['url'] as String, 12 | attachmentExtra: 13 | json['attachment_extra'] == null 14 | ? null 15 | : AttachmentExtra.fromJson( 16 | json['attachment_extra'] as Map, 17 | ), 18 | ); 19 | 20 | Map _$SendImageDataToJson(SendImageData instance) => 21 | { 22 | 'url': instance.url, 23 | 'attachment_extra': instance.attachmentExtra?.toJson(), 24 | }; 25 | -------------------------------------------------------------------------------- /lib/widgets/portal_providers.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_portal/flutter_portal.dart'; 3 | 4 | const secondPortal = PortalLabel('second'); 5 | 6 | class PortalProviders extends StatelessWidget { 7 | const PortalProviders({required this.child, super.key}); 8 | 9 | final Widget child; 10 | 11 | @override 12 | Widget build(BuildContext context) => 13 | Portal(labels: const [secondPortal], child: Portal(child: child)); 14 | } 15 | -------------------------------------------------------------------------------- /lib/widgets/sticker_page/bloc/cubit/sticker_albums_cubit.dart: -------------------------------------------------------------------------------- 1 | import '../../../../bloc/stream_cubit.dart'; 2 | import '../../../../db/mixin_database.dart'; 3 | 4 | class StickerAlbumsCubit extends StreamCubit> { 5 | StickerAlbumsCubit(Stream> stream) : super([], stream); 6 | } 7 | -------------------------------------------------------------------------------- /lib/widgets/sticker_page/bloc/cubit/sticker_cubit.dart: -------------------------------------------------------------------------------- 1 | import '../../../../bloc/stream_cubit.dart'; 2 | import '../../../../db/mixin_database.dart'; 3 | 4 | class StickerCubit extends StreamCubit> { 5 | StickerCubit(Stream> stream) : super([], stream); 6 | } 7 | -------------------------------------------------------------------------------- /lib/widgets/window/window_shortcuts.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:window_manager/window_manager.dart'; 4 | 5 | class WindowShortcuts extends StatelessWidget { 6 | const WindowShortcuts({required this.child, super.key}); 7 | 8 | final Widget child; 9 | 10 | @override 11 | Widget build(BuildContext context) => FocusableActionDetector( 12 | shortcuts: const { 13 | SingleActivator(LogicalKeyboardKey.keyW, meta: true): 14 | _CloseWindowIntent(), 15 | }, 16 | actions: { 17 | _CloseWindowIntent: CallbackAction( 18 | onInvoke: (intent) { 19 | windowManager.hide(); 20 | }, 21 | ), 22 | }, 23 | child: child, 24 | ); 25 | } 26 | 27 | class _CloseWindowIntent extends Intent { 28 | const _CloseWindowIntent() : super(); 29 | } 30 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | 3 | cmake-build-* -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 3 | #include "ephemeral/Flutter-Generated.xcconfig" 4 | 5 | OTHER_LDFLAGS=$(inherited) -lstdc++ 6 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 3 | #include "ephemeral/Flutter-Generated.xcconfig" 4 | 5 | OTHER_LDFLAGS=$(inherited) -lstdc++ 6 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = Mixin 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = one.mixin.messenger.desktop 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 Mixin. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.files.user-selected.read-write 10 | 11 | com.apple.security.network.client 12 | 13 | com.apple.security.network.server 14 | 15 | com.apple.security.device.microphone 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /macos/Runner/PlatformMenuPlugin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlatformMenuChannel.swift 3 | // Runner 4 | // 5 | // Created by Bin Yang on 2022/5/12. 6 | // Copyright © 2022 The Flutter Authors. All rights reserved. 7 | // 8 | 9 | import FlutterMacOS 10 | import Foundation 11 | 12 | class PlatformMenuPlugin: NSObject, FlutterPlugin { 13 | static func register(with registrar: FlutterPluginRegistrar) { 14 | let channel = FlutterMethodChannel(name: "mixin_desktop/platform_menus", binaryMessenger: registrar.messenger) 15 | let instance = PlatformMenuPlugin() 16 | registrar.addMethodCallDelegate(instance, channel: channel) 17 | } 18 | 19 | func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 20 | switch call.method { 21 | case "showAbout": 22 | NSApplication.shared.orderFrontStandardAboutPanel() 23 | result(nil) 24 | default: 25 | result(FlutterMethodNotImplemented) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.audio-input 8 | 9 | com.apple.security.device.microphone 10 | 11 | com.apple.security.files.user-selected.read-write 12 | 13 | com.apple.security.network.client 14 | 15 | com.apple.security.network.server 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /macos/Runner/mixin.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/macos/Runner/mixin.caf -------------------------------------------------------------------------------- /test/utils/iterable_extension_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app/utils/extension/extension.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | test('test chunked list', () { 6 | final list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 7 | final result = list.chunked(3); 8 | expect(result, [ 9 | [1, 2, 3], 10 | [4, 5, 6], 11 | [7, 8, 9], 12 | [10], 13 | ]); 14 | 15 | final result2 = list.chunked(4); 16 | expect(result2, [ 17 | [1, 2, 3, 4], 18 | [5, 6, 7, 8], 19 | [9, 10], 20 | ]); 21 | 22 | final result3 = list.chunked(5); 23 | expect(result3, [ 24 | [1, 2, 3, 4, 5], 25 | [6, 7, 8, 9, 10], 26 | ]); 27 | 28 | final result4 = list.chunked(11); 29 | expect(result4, [ 30 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 31 | ]); 32 | 33 | expect([].chunked(2), []); 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /test/utils/number_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app/utils/extension/extension.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | test('number format', () { 6 | expect( 7 | '-1681845116007986013692583.43574366'.numberFormat(), 8 | '-1,681,845,116,007,986,013,692,583.43574366', 9 | ); 10 | expect('-0.43574366'.numberFormat(), '-0.43574366'); 11 | expect('0.43574366'.numberFormat(), '0.43574366'); 12 | expect('0.12345678910'.numberFormat(), '0.12345679'); 13 | expect('-0.1234567891011'.numberFormat(), '-0.12345679'); 14 | expect('0'.numberFormat(), '0'); 15 | expect('0.0'.numberFormat(), '0'); 16 | expect( 17 | '1234567891011121314151617181920'.numberFormat(), 18 | '1,234,567,891,011,121,314,151,617,181,920', 19 | ); 20 | expect( 21 | '1234567891011121314151617181920.0'.numberFormat(), 22 | '1,234,567,891,011,121,314,151,617,181,920', 23 | ); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /test/uuid_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter_app/crypto/uuid/uuid.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | 6 | void main() { 7 | test('test generate conversationId', () { 8 | const a = '80f5130e-a5f5-47e4-80a1-535563687709'; 9 | const b = '508c75a2-ddce-4858-9e66-cf6d58db15cf'; 10 | final result = generateConversationId(a, b); 11 | final otherResult = generateConversationId(b, a); 12 | expect(result, 'a59c170e-02e6-3aa6-8ff1-6cb9350fa8fc'); 13 | expect(result, otherResult); 14 | }); 15 | 16 | test('test generate uuid with same bytes', () { 17 | final value = nameUuidFromBytes(utf8.encode('test')); 18 | expect(value.toString(), '098f6bcd-4621-3373-8ade-4e832627b4f6'); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /test/widgets/message/inscription_content_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app/widgets/message/item/transfer/inscription_message/inscription_content.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | test('inscription text display', () { 6 | final tests = [ 7 | ('1 .mao', '1■.mao'), 8 | ('mixin.mao', 'mixin.mao'), 9 | ('🇨🇳.mao', '🇨🇳.mao'), 10 | ('\u{0001}.mao', '■.mao'), 11 | ('\u{008C}.mao', '■.mao'), 12 | ('\u{200B}.mao', '■.mao'), 13 | ('\tmao', '■mao'), 14 | ('\nmao', '■mao'), 15 | ('\rmao', '■mao'), 16 | ('\u{FEFF}mao', '■mao'), 17 | (' mao ', '■mao■'), 18 | ('\u{202F}.mao', '■.mao'), 19 | ('\u{2060}.mao', '■.mao'), 20 | ('\u{200E}left', '■left'), 21 | ('\u{200F}right', '■right'), 22 | ]; 23 | for (final test in tests) { 24 | expect(inscriptionDisplayContent(test.$1), test.$2, reason: test.$1); 25 | } 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /third_party/README.md: -------------------------------------------------------------------------------- 1 | # Third party flutter plugins 2 | 3 | This directory contains third party flutter plugins which used in Mixin Messenger. 4 | -------------------------------------------------------------------------------- /third_party/system_tray/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium -------------------------------------------------------------------------------- /third_party/system_tray/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | 9 | /.fvm/flutter_sdk -------------------------------------------------------------------------------- /third_party/system_tray/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: fa5883b78e566877613ad1ccb48dd92075cb5c23 8 | channel: dev 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /third_party/system_tray/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 2 | 3 | * [Feature] add some helper functions (setImage / setTooltip / setTitle / getTitle) 4 | * [Fixed] enable change icon image on macOS 5 | 6 | ## 0.0.9 7 | 8 | * [Feature] add popUpContextMenu 9 | * [Feature] add new system tray event (leftMouseDown / rightMouseDown) 10 | 11 | ## 0.0.8 12 | 13 | * [Feature] tray icon support high DPI on windows 14 | * [Feature] support simple class appwindow for control window on all platforms 15 | * [Fixed] fixed crash when minimize window, then click on menubar on macOS 16 | 17 | ## 0.0.7 18 | 19 | * Support handle system tray event leftMouseUp/rightMouseUp (only for macos、windows) 20 | 21 | ## 0.0.6 22 | 23 | * Fixed flash tray icon for macos 24 | 25 | ## 0.0.4 26 | 27 | * Fixed flash tray icon for macos 28 | 29 | ## 0.0.3 30 | 31 | * Add function setSystemTrayInfo 32 | 33 | ## 0.0.2 34 | 35 | * Upgrade README.md 36 | 37 | ## 0.0.1 38 | 39 | * Initial Windows release as federated plugin -------------------------------------------------------------------------------- /third_party/system_tray/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /third_party/system_tray/lib/system_tray.dart: -------------------------------------------------------------------------------- 1 | export 'src/tray.dart'; 2 | export 'src/app_window.dart'; 3 | export 'src/menu_item.dart'; 4 | -------------------------------------------------------------------------------- /third_party/system_tray/test/system_tray_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | const MethodChannel channel = MethodChannel('flutter/system_tray'); 6 | 7 | TestWidgetsFlutterBinding.ensureInitialized(); 8 | 9 | setUp(() { 10 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 11 | return '42'; 12 | }); 13 | }); 14 | 15 | tearDown(() { 16 | channel.setMockMethodCallHandler(null); 17 | }); 18 | 19 | test('getPlatformVersion', () async {}); 20 | } 21 | -------------------------------------------------------------------------------- /third_party/system_tray/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /third_party/system_tray/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | set(PROJECT_NAME "system_tray") 3 | project(${PROJECT_NAME} LANGUAGES CXX) 4 | 5 | # This value is used when generating builds using this plugin, so it must 6 | # not be changed 7 | set(PLUGIN_NAME "system_tray_plugin") 8 | 9 | add_library(${PLUGIN_NAME} SHARED 10 | "system_tray_plugin.cpp" 11 | "tray.cpp" 12 | "app_window.cpp" 13 | ) 14 | apply_standard_settings(${PLUGIN_NAME}) 15 | set_target_properties(${PLUGIN_NAME} PROPERTIES 16 | CXX_VISIBILITY_PRESET hidden) 17 | target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) 18 | target_include_directories(${PLUGIN_NAME} INTERFACE 19 | "${CMAKE_CURRENT_SOURCE_DIR}/include") 20 | target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) 21 | 22 | # List of absolute paths to libraries that should be bundled with the plugin 23 | set(system_tray_bundled_libraries 24 | "" 25 | PARENT_SCOPE 26 | ) 27 | -------------------------------------------------------------------------------- /third_party/system_tray/windows/app_window.h: -------------------------------------------------------------------------------- 1 | #ifndef __AppWindow_H__ 2 | #define __AppWindow_H__ 3 | 4 | #include 5 | 6 | class AppWindow { 7 | public: 8 | bool initAppWindow(HWND window, HWND flutter_window); 9 | bool showAppWindow(bool visible); 10 | bool closeAppWindow(); 11 | 12 | protected: 13 | void activeWindow(); 14 | void refreshFlutterWindow(); 15 | 16 | protected: 17 | HWND window_ = nullptr; 18 | HWND flutter_window_ = nullptr; 19 | }; 20 | 21 | #endif // __AppWindow_H__ -------------------------------------------------------------------------------- /third_party/system_tray/windows/include/system_tray/system_tray_plugin.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_PLUGIN_SYSTEM_TRAY_PLUGIN_H_ 2 | #define FLUTTER_PLUGIN_SYSTEM_TRAY_PLUGIN_H_ 3 | 4 | #include 5 | 6 | #ifdef FLUTTER_PLUGIN_IMPL 7 | #define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) 8 | #else 9 | #define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) 10 | #endif 11 | 12 | #if defined(__cplusplus) 13 | extern "C" { 14 | #endif 15 | 16 | FLUTTER_PLUGIN_EXPORT void SystemTrayPluginRegisterWithRegistrar( 17 | FlutterDesktopPluginRegistrarRef registrar); 18 | 19 | #if defined(__cplusplus) 20 | } // extern "C" 21 | #endif 22 | 23 | #endif // FLUTTER_PLUGIN_SYSTEM_TRAY_PLUGIN_H_ 24 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | flutter_app 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | 19 | # clion cmake project build dir. 20 | cmake-build-* -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/libs/vclibs/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/windows/libs/vclibs/msvcp140.dll -------------------------------------------------------------------------------- /windows/libs/vclibs/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/windows/libs/vclibs/vcruntime140.dll -------------------------------------------------------------------------------- /windows/libs/vclibs/vcruntime140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/windows/libs/vclibs/vcruntime140_1.dll -------------------------------------------------------------------------------- /windows/runner/raw_hwnd_plugin.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_PLUGIN_RAW_HWND_PLUGIN_H_ 2 | #define FLUTTER_PLUGIN_RAW_HWND_PLUGIN_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #if defined(__cplusplus) 9 | extern "C" { 10 | #endif 11 | 12 | void RawHwndPluginRegisterWithRegistrar(FlutterDesktopPluginRegistrarRef registrar, HWND handle); 13 | 14 | #if defined(__cplusplus) 15 | } // extern "C" 16 | #endif 17 | 18 | #endif // FLUTTER_PLUGIN_RAW_HWND_PLUGIN_H_ -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MixinNetwork/flutter-app/8d35159e627078e0d35c192076dac057c0f75ec9/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------