├── test ├── ui │ ├── common.dart │ ├── widgets │ │ ├── post_action_comment │ │ │ └── index_test.dart │ │ ├── sync_snackbar │ │ │ └── index_test.dart │ │ ├── loading_indicator │ │ │ └── index_test.dart │ │ ├── posts_list_empty_container │ │ │ └── index_test.dart │ │ ├── posts_list_item │ │ │ └── widgets │ │ │ │ ├── popup_content_tx_success │ │ │ │ └── index_test.dart │ │ │ │ └── popup_content_tx_error │ │ │ │ └── index_test.dart │ │ ├── post_action_add_reaction │ │ │ └── index_test.dart │ │ ├── post_content_message │ │ │ └── index_test.dart │ │ ├── buttons │ │ │ ├── primary_light_button │ │ │ │ └── index_test.dart │ │ │ └── secondary_button │ │ │ │ └── index_test.dart │ │ ├── mnemonic_visualizer │ │ │ └── widgets │ │ │ │ ├── backup_mnemonic_details │ │ │ │ └── index_test.dart │ │ │ │ └── mnemonic_item │ │ │ │ └── index_test.dart │ │ └── post_content │ │ │ └── widgets │ │ │ ├── link_preview │ │ │ └── index_test.dart │ │ │ └── post_poll_content │ │ │ └── widgets │ │ │ └── post_poll_option_item │ │ │ └── index_test.dart │ └── screens │ │ ├── user_wallet_screen │ │ └── widgets │ │ │ ├── wallet_actions_list │ │ │ └── index_test.dart │ │ │ ├── empty_wallet │ │ │ └── index_test.dart │ │ │ └── wallet_header │ │ │ └── index_test.dart │ │ ├── login_screen │ │ └── widgets │ │ │ └── login_popup │ │ │ └── index_test.dart │ │ ├── post_details_screen │ │ └── widgets │ │ │ └── post_details_loading │ │ │ └── index_test.dart │ │ ├── security_set_password_screen │ │ └── widgets │ │ │ └── saving_password_popup_content │ │ │ └── index_test.dart │ │ └── security_set_biometrics_screen │ │ └── widgets │ │ └── saving_biometrics_popup_content │ │ └── index_test.dart ├── test_utils │ └── export.dart ├── mocks │ ├── mocks.dart │ └── account.dart ├── usecases │ ├── users │ │ ├── common.dart │ │ └── usecase_block_user_test.dart │ ├── posts │ │ ├── common.dart │ │ ├── usecase_delete_posts_test.dart │ │ └── usecase_hide_post_test.dart │ ├── notifications │ │ └── common.dart │ ├── settings │ │ ├── common.dart │ │ ├── usecase_save_setting_test.dart │ │ ├── usecase_watch_setting_test.dart │ │ └── usecase_get_setting_test.dart │ ├── biometrics │ │ └── common.dart │ └── account │ │ ├── common.dart │ │ ├── usecase_generate_mnemonic_test.dart │ │ ├── usecase_refresh_account_test.dart │ │ ├── usecase_save_account_test.dart │ │ ├── usecase_get_mnemonic_test.dart │ │ ├── usecase_check_login_test.dart │ │ ├── usecase_get_accounts_test.dart │ │ ├── usecase_set_account_active_test.dart │ │ ├── usecase_encrypt_mnemonic_test.dart │ │ ├── usecase_logout_test.dart │ │ └── usecase_save_wallet_test.dart ├── sources │ ├── helpers.dart │ └── posts │ │ └── common.dart ├── entities │ ├── posts │ │ └── polls │ │ │ ├── poll_option_test.dart │ │ │ └── poll_answer_test.dart │ ├── mnemonic │ │ └── mnemonic_data_test.dart │ ├── app │ │ └── constants_test.dart │ ├── emojis │ │ └── emojis_utils_test.dart │ └── account │ │ └── authentication_method_test.dart └── repositories │ └── settings │ └── settings_repository_impl_test.dart ├── android ├── settings_aar.gradle ├── app │ └── src │ │ ├── main │ │ ├── ic_launcher-playstore.png │ │ ├── res │ │ │ ├── drawable │ │ │ │ ├── ic_notification.png │ │ │ │ └── launcher_background.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ └── styles.xml │ │ │ ├── xml │ │ │ │ └── backup_rules.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_background.xml │ │ └── kotlin │ │ │ └── com │ │ │ └── forbole │ │ │ └── mooncake │ │ │ ├── MainActivity.kt │ │ │ └── Application.kt │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── gradle.properties ├── .gitignore ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── lib ├── ui │ ├── utils │ │ ├── icons │ │ │ ├── export.dart │ │ │ └── icon_data.dart │ │ ├── extensions │ │ │ ├── export.dart │ │ │ └── user_ext.dart │ │ ├── helpers │ │ │ ├── export.dart │ │ │ └── common_security.dart │ │ ├── jazzicon │ │ │ └── export.dart │ │ └── export.dart │ ├── models │ │ ├── export.dart │ │ └── password_security.dart │ ├── screens │ │ ├── post_create_screen │ │ │ ├── blocs │ │ │ │ ├── export.dart │ │ │ │ └── post_input │ │ │ │ │ ├── export.dart │ │ │ │ │ └── post_input_event_images.dart │ │ │ └── widgets │ │ │ │ ├── create_post_content │ │ │ │ └── widgets │ │ │ │ │ ├── post_poll_creator │ │ │ │ │ ├── utils │ │ │ │ │ │ ├── export.dart │ │ │ │ │ │ └── common.dart │ │ │ │ │ └── widgets │ │ │ │ │ │ └── export.dart │ │ │ │ │ ├── create_post_images_list │ │ │ │ │ └── widgets │ │ │ │ │ │ └── export.dart │ │ │ │ │ └── export.dart │ │ │ │ └── export.dart │ │ ├── user_account_edit_screen │ │ │ ├── blocs │ │ │ │ ├── export.dart │ │ │ │ └── edit │ │ │ │ │ └── export.dart │ │ │ ├── widgets │ │ │ │ ├── export.dart │ │ │ │ └── account_edit_body │ │ │ │ │ └── widgets │ │ │ │ │ ├── account_text_info_editor │ │ │ │ │ └── widgets │ │ │ │ │ │ └── export.dart │ │ │ │ │ └── export.dart │ │ │ └── index.dart │ │ ├── security_set_password_screen │ │ │ ├── blocs │ │ │ │ ├── export.dart │ │ │ │ └── password │ │ │ │ │ └── export.dart │ │ │ └── widgets │ │ │ │ ├── set_password_content │ │ │ │ └── widgets │ │ │ │ │ └── export.dart │ │ │ │ └── export.dart │ │ ├── security_set_biometrics_screen │ │ │ ├── blocs │ │ │ │ ├── export.dart │ │ │ │ └── biometrics │ │ │ │ │ ├── export.dart │ │ │ │ │ └── biometrics_event.dart │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ └── saving_biometrics_popup_content │ │ │ │ └── index.dart │ │ ├── restore_mnemonic_backup_screen │ │ │ └── blocs │ │ │ │ ├── export.dart │ │ │ │ └── restore_backup │ │ │ │ └── export.dart │ │ ├── login_screen │ │ │ └── widgets │ │ │ │ ├── login_main_content │ │ │ │ └── widgets │ │ │ │ │ └── export.dart │ │ │ │ └── export.dart │ │ ├── user_details_screen │ │ │ └── widgets │ │ │ │ ├── menu_drawer │ │ │ │ └── widgets │ │ │ │ │ └── export.dart │ │ │ │ ├── account_app_bar │ │ │ │ └── widgets │ │ │ │ │ ├── export.dart │ │ │ │ │ ├── draft_button │ │ │ │ │ └── index.dart │ │ │ │ │ └── menu_button │ │ │ │ │ └── index.dart │ │ │ │ └── export.dart │ │ ├── home_screen │ │ │ └── widgets │ │ │ │ ├── notifications_main_content │ │ │ │ └── widgets │ │ │ │ │ ├── export.dart │ │ │ │ │ └── notifications_list │ │ │ │ │ └── widgets │ │ │ │ │ └── export.dart │ │ │ │ ├── export.dart │ │ │ │ └── posts_list │ │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ ├── posts_bottom_loader │ │ │ │ └── index.dart │ │ │ │ ├── error_post_message │ │ │ │ └── index.dart │ │ │ │ ├── posts_list_loading_container │ │ │ │ └── index.dart │ │ │ │ └── posts_list_syncing_indicator │ │ │ │ └── index.dart │ │ ├── post_details_screen │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ ├── post_details_main_content │ │ │ │ └── widgets │ │ │ │ │ ├── post_comments_list │ │ │ │ │ └── widgets │ │ │ │ │ │ └── export.dart │ │ │ │ │ ├── post_details_reactions_list │ │ │ │ │ └── widgets │ │ │ │ │ │ ├── export.dart │ │ │ │ │ │ └── reactions_list │ │ │ │ │ │ └── widgets │ │ │ │ │ │ └── export.dart │ │ │ │ │ └── export.dart │ │ │ │ └── post_details_loading │ │ │ │ └── index.dart │ │ ├── user_wallet_screen │ │ │ └── widgets │ │ │ │ └── export.dart │ │ └── export.dart │ ├── localization │ │ └── export.dart │ ├── widgets │ │ ├── post_item_header │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ └── post_more_button │ │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ └── dialogs │ │ │ │ ├── blocs │ │ │ │ ├── export.dart │ │ │ │ └── report_popup │ │ │ │ │ └── export.dart │ │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ └── popup_report │ │ │ │ └── widgets │ │ │ │ └── export.dart │ │ ├── post_action_add_reaction │ │ │ └── widgets │ │ │ │ └── export.dart │ │ ├── bottom_navigation_bar │ │ │ └── widgets │ │ │ │ └── export.dart │ │ ├── recover_account_main_content │ │ │ └── widgets │ │ │ │ └── export.dart │ │ ├── posts_list_item │ │ │ └── widgets │ │ │ │ ├── post_actions_bar │ │ │ │ └── widgets │ │ │ │ │ └── export.dart │ │ │ │ ├── export.dart │ │ │ │ └── show_post_item_popup │ │ │ │ └── index.dart │ │ ├── post_content │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ └── post_poll_content │ │ │ │ ├── widgets │ │ │ │ └── export.dart │ │ │ │ └── utils.dart │ │ ├── mnemonic_visualizer │ │ │ └── widgets │ │ │ │ ├── export.dart │ │ │ │ ├── export_mnemonic_button │ │ │ │ └── index.dart │ │ │ │ └── mnemonic_item │ │ │ │ └── index.dart │ │ ├── buttons │ │ │ └── export.dart │ │ ├── loading_indicator │ │ │ └── index.dart │ │ └── sync_snackbar │ │ │ └── index.dart │ ├── blocs │ │ ├── navigator │ │ │ └── export.dart │ │ ├── home │ │ │ └── export.dart │ │ ├── account_read │ │ │ └── export.dart │ │ ├── mnemonic │ │ │ └── export.dart │ │ ├── posts_list │ │ │ └── export.dart │ │ ├── post_details │ │ │ └── export.dart │ │ ├── notifications │ │ │ ├── export.dart │ │ │ └── notifications_event.dart │ │ ├── recover_account │ │ │ └── export.dart │ │ ├── export.dart │ │ └── simple_bloc_delegate.dart │ ├── theme │ │ ├── export.dart │ │ ├── spaces.dart │ │ └── fonts.dart │ ├── ui.dart │ └── dependency_injection.dart ├── entities │ ├── emojis │ │ ├── export.dart │ │ └── emoji_utils.dart │ ├── mnemonic │ │ ├── export.dart │ │ └── mnemonic_data.g.dart │ ├── posts │ │ ├── medias │ │ │ ├── export.dart │ │ │ └── post_media.g.dart │ │ ├── reactions │ │ │ ├── export.dart │ │ │ └── reaction.g.dart │ │ ├── polls │ │ │ ├── export.dart │ │ │ ├── poll_option.g.dart │ │ │ └── poll_answer.g.dart │ │ ├── export.dart │ │ └── extensions_polls.dart │ ├── settings │ │ ├── export.dart │ │ └── setting_keys.dart │ ├── user │ │ ├── export.dart │ │ └── user.g.dart │ ├── app │ │ ├── export.dart │ │ └── app_tab.dart │ ├── account │ │ ├── export.dart │ │ ├── extensions.dart │ │ └── account_save_result.dart │ ├── notifications │ │ ├── export.dart │ │ └── notification.g.dart │ └── entities.dart ├── sources │ ├── medias │ │ ├── export.dart │ │ └── remote │ │ │ ├── models │ │ │ ├── export.dart │ │ │ └── ipfs │ │ │ │ ├── export.dart │ │ │ │ └── ipfs_upload_response.g.dart │ │ │ └── export.dart │ ├── chain │ │ ├── models │ │ │ ├── models.dart │ │ │ └── msgs │ │ │ │ ├── export.dart │ │ │ │ ├── chain_poll_option.g.dart │ │ │ │ ├── user_pictures.g.dart │ │ │ │ ├── chain_poll_option.dart │ │ │ │ ├── msg_add_post_reaction.g.dart │ │ │ │ ├── msg_answer_poll.g.dart │ │ │ │ └── msg_remove_post_reaction.g.dart │ │ └── export.dart │ ├── settings │ │ ├── export.dart │ │ └── local │ │ │ └── export.dart │ ├── posts │ │ ├── local │ │ │ └── export.dart │ │ ├── remote │ │ │ ├── helpers │ │ │ │ └── helpers.dart │ │ │ ├── export.dart │ │ │ └── converters │ │ │ │ └── converters.dart │ │ └── export.dart │ ├── user │ │ ├── local │ │ │ └── export.dart │ │ ├── remote │ │ │ ├── helpers │ │ │ │ └── export.dart │ │ │ ├── converters │ │ │ │ ├── export.dart │ │ │ │ └── user_msg_converter.dart │ │ │ └── export.dart │ │ └── export.dart │ ├── users │ │ └── export.dart │ ├── notifications │ │ ├── remote │ │ │ ├── models │ │ │ │ └── models.dart │ │ │ └── export.dart │ │ ├── local │ │ │ └── export.dart │ │ └── export.dart │ └── sources.dart ├── usecases │ ├── medias │ │ ├── export.dart │ │ └── repository_medias.dart │ ├── users │ │ ├── export.dart │ │ ├── usecase_block_user.dart │ │ └── repository_users.dart │ ├── notifications │ │ ├── export.dart │ │ ├── repository_notifications.dart │ │ └── usecase_get_notifications.dart │ ├── biometrics │ │ ├── export.dart │ │ ├── usecase_can_use_biometric.dart │ │ └── usecase_get_available_biometrics.dart │ ├── settings │ │ ├── export.dart │ │ ├── repository_settings.dart │ │ ├── usecase_watch_setting.dart │ │ ├── usecase_save_setting.dart │ │ └── usecase_get_setting.dart │ ├── usecases.dart │ ├── posts │ │ ├── usecase_report_post.dart │ │ ├── usecase_delete_posts.dart │ │ ├── export.dart │ │ ├── usecase_sync.dart │ │ ├── usecase_hide_post.dart │ │ ├── usecase_get_home_remote_events.dart │ │ ├── usecase_delete_post.dart │ │ ├── usecase_get_home_posts.dart │ │ └── usecase_update_post.dart │ └── account │ │ ├── usecase_generate_mnemonic.dart │ │ ├── usecase_get_accounts.dart │ │ ├── usecase_get_account.dart │ │ ├── usecase_refresh_account.dart │ │ ├── usecase_check_login.dart │ │ ├── usecase_save_wallet.dart │ │ ├── usecase_set_account_active.dart │ │ ├── export.dart │ │ ├── usecase_get_mnemonic.dart │ │ ├── usecase_save_account.dart │ │ ├── usecase_get_authentication_method.dart │ │ ├── usecase_get_active_account.dart │ │ └── usecase_logout.dart ├── repositories │ ├── chain │ │ └── export.dart │ ├── users │ │ ├── export.dart │ │ └── source_users_local.dart │ ├── medias │ │ ├── export.dart │ │ ├── source_medias_remote.dart │ │ └── medias_repository_impl.dart │ ├── settings │ │ ├── export.dart │ │ ├── source_settings_local.dart │ │ └── settings_repository_impl.dart │ ├── user │ │ ├── export.dart │ │ └── source_user_remote.dart │ ├── posts │ │ └── export.dart │ ├── notifications │ │ ├── export.dart │ │ ├── source_notifications_remote.dart │ │ └── source_notifications_local.dart │ └── repositories.dart ├── dependency_injection │ └── dependency_injection.dart ├── utils │ ├── utils.dart │ ├── dependency_injector.dart │ └── measure_exec_time.dart └── notifications │ ├── notifications.dart │ └── dependency_injection.dart ├── .docs └── .vuepress │ ├── styles │ └── palette.styl │ └── public │ └── assets │ ├── logo.png │ ├── cover.png │ └── pwa │ ├── favicon.ico │ ├── apple-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── ms-icon-70x70.png │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── apple-icon-precomposed.png │ ├── browserconfig.xml │ └── manifest.json ├── ios ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ └── 1024.png │ │ └── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ ├── AppDelegate.swift │ └── Runner.entitlements ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner.xcodeproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── .gitignore ├── .img ├── cover.png ├── screen_list.png ├── screen_login.png └── screen_detail.png ├── assets ├── images │ ├── cry.png │ ├── sad.png │ ├── logo.png │ ├── smile.png │ ├── wink.png │ ├── frowned.png │ ├── pattern.png │ ├── tongue.png │ └── pattern_dark.png └── fonts │ ├── mooncake-icons.ttf │ ├── sf-pro │ ├── SF-Pro-Display-Bold.otf │ ├── SF-Pro-Display-Thin.otf │ ├── SF-Pro-Display-Black.otf │ ├── SF-Pro-Display-Heavy.otf │ ├── SF-Pro-Display-Light.otf │ ├── SF-Pro-Display-Medium.otf │ ├── SF-Pro-Display-Regular.otf │ ├── SF-Pro-Display-Semibold.otf │ ├── SF-Pro-Display-BlackItalic.otf │ ├── SF-Pro-Display-BoldItalic.otf │ ├── SF-Pro-Display-HeavyItalic.otf │ ├── SF-Pro-Display-LightItalic.otf │ ├── SF-Pro-Display-MediumItalic.otf │ ├── SF-Pro-Display-ThinItalic.otf │ ├── SF-Pro-Display-Ultralight.otf │ ├── SF-Pro-Display-RegularItalic.otf │ ├── SF-Pro-Display-SemiboldItalic.otf │ └── SF-Pro-Display-UltralightItalic.otf │ └── montserrat │ ├── Montserrat-Medium.ttf │ ├── Montserrat-Regular.ttf │ └── Montserrat-MediumItalic.ttf ├── test_resources ├── posts │ ├── posts_list_response_empty.json │ ├── post_valid_children.json │ ├── post_valid_optdata.json │ ├── post_response.json │ └── post_valid_reactions.json ├── user │ └── user.json ├── account │ ├── image.jpeg │ └── account_response.json └── chain │ ├── websocket_event.json │ ├── chain_response.json │ └── node_info_response.json ├── distribution ├── keystore.jks.gpg ├── google-services.json.gpg ├── service-account.json.gpg └── whatsnew │ └── whatsnew-en-US ├── .metadata ├── .codecov.yml ├── analysis_options.yaml ├── .github ├── ISSUE_TEMPLATE │ ├── question.md │ ├── performance_report.md │ ├── feature_request.md │ └── bug_report.md ├── workflows │ └── docs.yml └── PULL_REQUEST_TEMPLATE.md ├── package.json ├── .gitignore └── tool └── generator.g.dart /test/ui/common.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /lib/ui/utils/icons/export.dart: -------------------------------------------------------------------------------- 1 | export 'icons.dart'; 2 | -------------------------------------------------------------------------------- /.docs/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | $accentColor = #8959F2 2 | -------------------------------------------------------------------------------- /lib/entities/emojis/export.dart: -------------------------------------------------------------------------------- 1 | export 'emoji_utils.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/medias/export.dart: -------------------------------------------------------------------------------- 1 | export 'remote/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/models/export.dart: -------------------------------------------------------------------------------- 1 | export 'password_security.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/utils/extensions/export.dart: -------------------------------------------------------------------------------- 1 | export 'user_ext.dart'; 2 | -------------------------------------------------------------------------------- /test/test_utils/export.dart: -------------------------------------------------------------------------------- 1 | export 'network_image.dart'; 2 | -------------------------------------------------------------------------------- /lib/entities/mnemonic/export.dart: -------------------------------------------------------------------------------- 1 | export 'mnemonic_data.dart'; 2 | -------------------------------------------------------------------------------- /lib/entities/posts/medias/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_media.dart'; 2 | -------------------------------------------------------------------------------- /lib/entities/posts/reactions/export.dart: -------------------------------------------------------------------------------- 1 | export 'reaction.dart'; 2 | -------------------------------------------------------------------------------- /lib/entities/settings/export.dart: -------------------------------------------------------------------------------- 1 | export 'setting_keys.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/chain/models/models.dart: -------------------------------------------------------------------------------- 1 | export 'msgs/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/settings/export.dart: -------------------------------------------------------------------------------- 1 | export 'local/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/utils/helpers/export.dart: -------------------------------------------------------------------------------- 1 | export 'common_security.dart'; 2 | -------------------------------------------------------------------------------- /lib/usecases/medias/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_medias.dart'; 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /lib/repositories/chain/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_chain_remote.dart'; 2 | -------------------------------------------------------------------------------- /lib/repositories/users/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_users_local.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/posts/local/export.dart: -------------------------------------------------------------------------------- 1 | export 'local_posts_source.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/utils/jazzicon/export.dart: -------------------------------------------------------------------------------- 1 | export 'jazzicon_painter.dart'; 2 | -------------------------------------------------------------------------------- /test/mocks/mocks.dart: -------------------------------------------------------------------------------- 1 | export 'account.dart'; 2 | export 'posts.dart'; 3 | -------------------------------------------------------------------------------- /lib/dependency_injection/dependency_injection.dart: -------------------------------------------------------------------------------- 1 | export 'injector.dart'; 2 | -------------------------------------------------------------------------------- /lib/repositories/medias/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_medias_remote.dart'; 2 | -------------------------------------------------------------------------------- /lib/repositories/settings/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_settings_local.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/medias/remote/models/export.dart: -------------------------------------------------------------------------------- 1 | export 'ipfs/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/user/local/export.dart: -------------------------------------------------------------------------------- 1 | export 'local_user_source_impl.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/users/export.dart: -------------------------------------------------------------------------------- 1 | export 'local/local_users_source_impl.dart'; 2 | -------------------------------------------------------------------------------- /lib/entities/user/export.dart: -------------------------------------------------------------------------------- 1 | export 'user.dart'; 2 | export 'user_image.dart'; 3 | -------------------------------------------------------------------------------- /lib/sources/posts/remote/helpers/helpers.dart: -------------------------------------------------------------------------------- 1 | export 'gql_posts_helper.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/settings/local/export.dart: -------------------------------------------------------------------------------- 1 | export 'local_settings_source.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/user/remote/helpers/export.dart: -------------------------------------------------------------------------------- 1 | export 'gql_users_helper.dart'; 2 | -------------------------------------------------------------------------------- /lib/utils/utils.dart: -------------------------------------------------------------------------------- 1 | export 'logger.dart'; 2 | export 'measure_exec_time.dart'; 3 | -------------------------------------------------------------------------------- /.img/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.img/cover.png -------------------------------------------------------------------------------- /lib/entities/app/export.dart: -------------------------------------------------------------------------------- 1 | export 'app_tab.dart'; 2 | export 'constants.dart'; 3 | -------------------------------------------------------------------------------- /lib/sources/notifications/remote/models/models.dart: -------------------------------------------------------------------------------- 1 | export 'fcm_message_data.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/user/remote/converters/export.dart: -------------------------------------------------------------------------------- 1 | export 'user_msg_converter.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_input/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'edit/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/medias/remote/models/ipfs/export.dart: -------------------------------------------------------------------------------- 1 | export 'ipfs_upload_response.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/notifications/local/export.dart: -------------------------------------------------------------------------------- 1 | export 'local_notifications_source.dart'; 2 | -------------------------------------------------------------------------------- /lib/sources/notifications/remote/export.dart: -------------------------------------------------------------------------------- 1 | export 'remote_notifications_source.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/localization/export.dart: -------------------------------------------------------------------------------- 1 | export './index.dart'; 2 | export 'messages/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/models/password_security.dart: -------------------------------------------------------------------------------- 1 | enum PasswordSecurity { UNKNOWN, LOW, MEDIUM, HIGH } 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_more_button/index.dart'; 2 | -------------------------------------------------------------------------------- /.img/screen_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.img/screen_list.png -------------------------------------------------------------------------------- /.img/screen_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.img/screen_login.png -------------------------------------------------------------------------------- /assets/images/cry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/cry.png -------------------------------------------------------------------------------- /assets/images/sad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/sad.png -------------------------------------------------------------------------------- /lib/sources/posts/export.dart: -------------------------------------------------------------------------------- 1 | export 'local/export.dart'; 2 | export 'remote/export.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_password_screen/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'password/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_action_add_reaction/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'emoji_picker/index.dart'; 2 | -------------------------------------------------------------------------------- /.img/screen_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.img/screen_detail.png -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/smile.png -------------------------------------------------------------------------------- /assets/images/wink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/wink.png -------------------------------------------------------------------------------- /lib/sources/chain/export.dart: -------------------------------------------------------------------------------- 1 | export 'models/models.dart'; 2 | export 'chain_source_impl.dart'; 3 | -------------------------------------------------------------------------------- /lib/sources/notifications/export.dart: -------------------------------------------------------------------------------- 1 | export 'local/export.dart'; 2 | export 'remote/export.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/blocs/navigator/export.dart: -------------------------------------------------------------------------------- 1 | export 'navigator_bloc.dart'; 2 | export 'navigator_event.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_biometrics_screen/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'biometrics/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_edit_body/index.dart'; 2 | -------------------------------------------------------------------------------- /test_resources/posts/posts_list_response_empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "height": "337836", 3 | "result": [] 4 | } -------------------------------------------------------------------------------- /assets/images/frowned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/frowned.png -------------------------------------------------------------------------------- /assets/images/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/pattern.png -------------------------------------------------------------------------------- /assets/images/tongue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/tongue.png -------------------------------------------------------------------------------- /lib/repositories/user/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_user_local.dart'; 2 | export 'source_user_remote.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/restore_mnemonic_backup_screen/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'restore_backup/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/bottom_navigation_bar/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'bottom_navigation_button/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/recover_account_main_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'mnemonic_input_item/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/usecases/users/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_users.dart'; 2 | export 'usecase_block_user.dart'; 3 | -------------------------------------------------------------------------------- /test_resources/user/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "desmos10u276x6j0sltj4jzwnk892swcues3wehsv8dk3" 3 | } 4 | -------------------------------------------------------------------------------- /lib/repositories/posts/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_posts_local.dart'; 2 | export 'source_posts_remote.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/post_more_button/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'dialogs/index.dart'; 2 | -------------------------------------------------------------------------------- /assets/fonts/mooncake-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/mooncake-icons.ttf -------------------------------------------------------------------------------- /assets/images/pattern_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/images/pattern_dark.png -------------------------------------------------------------------------------- /distribution/keystore.jks.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/distribution/keystore.jks.gpg -------------------------------------------------------------------------------- /lib/sources/medias/remote/export.dart: -------------------------------------------------------------------------------- 1 | export 'remote_medias_source_impl.dart'; 2 | export 'models/export.dart'; 3 | -------------------------------------------------------------------------------- /lib/sources/posts/remote/export.dart: -------------------------------------------------------------------------------- 1 | export 'converters/converters.dart'; 2 | export 'remote_posts_source.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/blocs/home/export.dart: -------------------------------------------------------------------------------- 1 | export 'home_bloc.dart'; 2 | export 'home_event.dart'; 3 | export 'home_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/notifications/notifications.dart: -------------------------------------------------------------------------------- 1 | export 'notifications_manager.dart'; 2 | export 'notification_tap_handler.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/login_screen/widgets/login_main_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'login_terms_conditions/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/user_details_screen/widgets/menu_drawer/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'single_account_item/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/posts_list_item/widgets/post_actions_bar/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_likes_counter/index.dart'; 2 | -------------------------------------------------------------------------------- /test_resources/account/image.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/test_resources/account/image.jpeg -------------------------------------------------------------------------------- /lib/entities/posts/polls/export.dart: -------------------------------------------------------------------------------- 1 | export 'poll_answer.dart'; 2 | export 'post_poll.dart'; 3 | export 'poll_option.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/notifications_main_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'notifications_list/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_poll_content/index.dart'; 2 | export 'link_preview/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/usecases/notifications/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_notifications.dart'; 2 | export 'usecase_get_notifications.dart'; 3 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/logo.png -------------------------------------------------------------------------------- /distribution/google-services.json.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/distribution/google-services.json.gpg -------------------------------------------------------------------------------- /distribution/service-account.json.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/distribution/service-account.json.gpg -------------------------------------------------------------------------------- /lib/sources/posts/remote/converters/converters.dart: -------------------------------------------------------------------------------- 1 | export 'posts_msg_converter.dart'; 2 | export 'link_preview_converter.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/create_post_content/widgets/post_poll_creator/utils/export.dart: -------------------------------------------------------------------------------- 1 | export 'common.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/theme/export.dart: -------------------------------------------------------------------------------- 1 | export 'theme.dart'; 2 | export 'colors.dart'; 3 | export 'decorations.dart'; 4 | export 'spaces.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/post_more_button/widgets/dialogs/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'report_popup/export.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/post_more_button/widgets/dialogs/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'popup_report/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/usecases/biometrics/export.dart: -------------------------------------------------------------------------------- 1 | export 'usecase_can_use_biometric.dart'; 2 | export 'usecase_get_available_biometrics.dart'; 3 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/cover.png -------------------------------------------------------------------------------- /lib/repositories/notifications/export.dart: -------------------------------------------------------------------------------- 1 | export 'source_notifications_local.dart'; 2 | export 'source_notifications_remote.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/blocs/account_read/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_bloc.dart'; 2 | export 'account_event.dart'; 3 | export 'account_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/blocs/mnemonic/export.dart: -------------------------------------------------------------------------------- 1 | export 'mnemonic_bloc.dart'; 2 | export 'mnemonic_event.dart'; 3 | export 'mnemonic_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_password_screen/widgets/set_password_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'password_input_field/index.dart'; 2 | -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Bold.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Thin.otf -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/ui/blocs/posts_list/export.dart: -------------------------------------------------------------------------------- 1 | export 'posts_list_bloc.dart'; 2 | export 'posts_list_event.dart'; 3 | export 'posts_list_state.dart'; 4 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/favicon.ico -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /assets/fonts/montserrat/Montserrat-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/montserrat/Montserrat-Medium.ttf -------------------------------------------------------------------------------- /assets/fonts/montserrat/Montserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/montserrat/Montserrat-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Black.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Black.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Heavy.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Heavy.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Light.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Medium.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Regular.otf -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/entities/app/app_tab.dart: -------------------------------------------------------------------------------- 1 | /// Represents all the possible app navigation tabs 2 | enum AppTab { home, likedPosts, notifications, account } 3 | -------------------------------------------------------------------------------- /lib/sources/user/export.dart: -------------------------------------------------------------------------------- 1 | export 'package:alan/models/export.dart'; 2 | 3 | export 'local/export.dart'; 4 | export 'remote/export.dart'; 5 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon.png -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Semibold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Semibold.otf -------------------------------------------------------------------------------- /lib/ui/blocs/post_details/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_details_bloc.dart'; 2 | export 'post_details_event.dart'; 3 | export 'post_details_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/notifications_main_content/widgets/notifications_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'notification_item/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_details_loading/index.dart'; 2 | export 'post_details_main_content/index.dart'; 3 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/favicon-16x16.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/favicon-32x32.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/favicon-96x96.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/ms-icon-70x70.png -------------------------------------------------------------------------------- /assets/fonts/montserrat/Montserrat-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/montserrat/Montserrat-MediumItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-BlackItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-BlackItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-BoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-BoldItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-HeavyItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-HeavyItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-LightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-LightItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-MediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-MediumItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-ThinItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-ThinItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-Ultralight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-Ultralight.otf -------------------------------------------------------------------------------- /lib/ui/blocs/notifications/export.dart: -------------------------------------------------------------------------------- 1 | export 'notifications_bloc.dart'; 2 | export 'notifications_event.dart'; 3 | export 'notifications_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/post_details_main_content/widgets/post_comments_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_comment_item/index.dart'; 2 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/ms-icon-144x144.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/ms-icon-150x150.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/ms-icon-310x310.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/drawable/ic_notification.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-RegularItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-RegularItalic.otf -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-SemiboldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-SemiboldItalic.otf -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /lib/sources/user/remote/export.dart: -------------------------------------------------------------------------------- 1 | export 'converters/user_msg_converter.dart'; 2 | export 'helpers/export.dart'; 3 | export 'remote_user_source_impl.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/blocs/recover_account/export.dart: -------------------------------------------------------------------------------- 1 | export 'recover_account_bloc.dart'; 2 | export 'recover_account_event.dart'; 3 | export 'recover_account_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/create_post_content/widgets/create_post_images_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'create_post_image_item/index.dart'; 2 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/widgets/account_edit_body/widgets/account_text_info_editor/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_text_input/index.dart'; 2 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-36x36.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-48x48.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-72x72.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-96x96.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-114x114.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-120x120.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-144x144.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-152x152.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-180x180.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-57x57.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-60x60.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-72x72.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-76x76.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /assets/fonts/sf-pro/SF-Pro-Display-UltralightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/assets/fonts/sf-pro/SF-Pro-Display-UltralightItalic.otf -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /lib/ui/screens/security_set_password_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'set_password_content/index.dart'; 2 | export 'saving_password_popup_content/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_content/widgets/post_poll_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_poll_option_item/index.dart'; 2 | export 'post_poll_result_item/index.dart'; 3 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-144x144.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/android-icon-192x192.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/.docs/.vuepress/public/assets/pwa/apple-icon-precomposed.png -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | /key.properties 8 | GeneratedPluginRegistrant.java 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /lib/entities/account/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_save_result.dart'; 2 | export 'authentication_method.dart'; 3 | export 'extensions.dart'; 4 | export 'mooncake_account.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/blocs/edit/export.dart: -------------------------------------------------------------------------------- 1 | export 'edit_account_bloc.dart'; 2 | export 'edit_account_event.dart'; 3 | export 'edit_account_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/user_wallet_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'empty_wallet/index.dart'; 2 | export 'wallet_header/index.dart'; 3 | export 'wallet_actions_list/index.dart'; 4 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /lib/entities/notifications/export.dart: -------------------------------------------------------------------------------- 1 | export 'constants.dart'; 2 | export 'notification.dart'; 3 | export 'post_notifications.dart'; 4 | export 'transaction_notifications.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_biometrics_screen/blocs/biometrics/export.dart: -------------------------------------------------------------------------------- 1 | export 'biometrics_bloc.dart'; 2 | export 'biometrics_event.dart'; 3 | export 'biometrics_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_password_screen/blocs/password/export.dart: -------------------------------------------------------------------------------- 1 | export 'set_password_bloc.dart'; 2 | export 'set_password_event.dart'; 3 | export 'set_password_state.dart'; 4 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desmos-labs/mooncake/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /lib/entities/settings/setting_keys.dart: -------------------------------------------------------------------------------- 1 | class SettingKeys { 2 | static const TX_AMOUNT = 'tx_amount'; 3 | static const BACKUP_POPUP_PERMISSION = 'backup_popup_permission'; 4 | } 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #946FAE 4 | -------------------------------------------------------------------------------- /lib/ui/utils/export.dart: -------------------------------------------------------------------------------- 1 | export 'keys/export.dart'; 2 | export 'icons/export.dart'; 3 | export 'jazzicon/export.dart'; 4 | export 'extensions/export.dart'; 5 | export 'helpers/export.dart'; 6 | -------------------------------------------------------------------------------- /lib/usecases/settings/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_settings.dart'; 2 | export 'usecase_save_setting.dart'; 3 | export 'usecase_get_setting.dart'; 4 | export 'usecase_watch_setting.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/create_post_content/widgets/post_poll_creator/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'poll_end_date_editor/index.dart'; 2 | export 'poll_option_editor/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/restore_mnemonic_backup_screen/blocs/restore_backup/export.dart: -------------------------------------------------------------------------------- 1 | export 'restore_backup_bloc.dart'; 2 | export 'restore_backup_event.dart'; 3 | export 'restore_backup_state.dart'; 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/ui/screens/user_details_screen/widgets/account_app_bar/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_options_button/index.dart'; 2 | export 'menu_button/index.dart'; 3 | export 'draft_button/index.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'create_post_actions_bar/index.dart'; 2 | export 'create_post_content/index.dart'; 3 | export 'post_create_saving_popup_content/index.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/post_details_main_content/widgets/post_details_reactions_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'empty_reactions/index.dart'; 2 | export 'reactions_list/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/post_more_button/widgets/dialogs/widgets/popup_report/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'popup_report_option/index.dart'; 2 | export 'popup_report_text_input/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_biometrics_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'set_biometric_title/index.dart'; 2 | export 'set_biometric_body/index.dart'; 3 | export 'saving_biometrics_popup_content/index.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/create_post_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'create_post_top_bar/index.dart'; 2 | export 'create_post_images_list/index.dart'; 3 | export 'post_poll_creator/index.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_item_header/widgets/post_more_button/widgets/dialogs/blocs/report_popup/export.dart: -------------------------------------------------------------------------------- 1 | export 'report_popup_bloc.dart'; 2 | export 'report_popup_event.dart'; 3 | export 'report_popup_state.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/screens/user_details_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_app_bar/index.dart'; 2 | export 'account_name_row/index.dart'; 3 | export 'account_posts_viewer/index.dart'; 4 | export 'menu_drawer/index.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/screens/login_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_created_content/index.dart'; 2 | export 'login_popup/index.dart'; 3 | export 'login_main_content/index.dart'; 4 | export 'account_creating_content/index.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/post_details_main_content/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_details_reactions_list/index.dart'; 2 | export 'post_comments_list/index.dart'; 3 | export 'post_details_bottom_bar/index.dart'; 4 | -------------------------------------------------------------------------------- /lib/ui/widgets/mnemonic_visualizer/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'mnemonic_item/index.dart'; 2 | export 'backup_mnemonic_details/index.dart'; 3 | export 'export_mnemonic_button/index.dart'; 4 | export 'backup_mnemonic_button/index.dart'; 5 | -------------------------------------------------------------------------------- /lib/ui/widgets/posts_list_item/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_actions_bar/index.dart'; 2 | export 'popup_content_tx_error/index.dart'; 3 | export 'popup_content_tx_success/index.dart'; 4 | export 'show_post_item_popup/index.dart'; 5 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/post_details_main_content/widgets/post_details_reactions_list/widgets/reactions_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'reaction_filter_item/index.dart'; 2 | export 'post_details_reactions_list/index.dart'; 3 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/blocs/post_input/export.dart: -------------------------------------------------------------------------------- 1 | export 'post_input_bloc.dart'; 2 | export 'post_input_event.dart'; 3 | export 'post_input_event_images.dart'; 4 | export 'post_input_event_poll.dart'; 5 | export 'post_input_state.dart'; 6 | -------------------------------------------------------------------------------- /lib/ui/widgets/buttons/export.dart: -------------------------------------------------------------------------------- 1 | export 'check_box_button/index.dart'; 2 | export 'primary_light_button/index.dart'; 3 | export 'primary_button/index.dart'; 4 | export 'secondary_light_button/index.dart'; 5 | export 'secondary_dark_button/index.dart'; 6 | -------------------------------------------------------------------------------- /lib/sources/sources.dart: -------------------------------------------------------------------------------- 1 | export 'chain/export.dart'; 2 | export 'medias/export.dart'; 3 | export 'notifications/export.dart'; 4 | export 'posts/export.dart'; 5 | export 'user/export.dart'; 6 | export 'users/export.dart'; 7 | export 'settings/export.dart'; 8 | -------------------------------------------------------------------------------- /test/usecases/users/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:mockito/mockito.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily mock a [UsersRepository] instance 5 | class UsersRepositoryMock extends Mock implements UsersRepository {} 6 | -------------------------------------------------------------------------------- /lib/repositories/repositories.dart: -------------------------------------------------------------------------------- 1 | export 'chain/export.dart'; 2 | export 'medias/export.dart'; 3 | export 'notifications/export.dart'; 4 | export 'posts/export.dart'; 5 | export 'user/export.dart'; 6 | export 'users/export.dart'; 7 | export 'settings/export.dart'; 8 | -------------------------------------------------------------------------------- /lib/usecases/usecases.dart: -------------------------------------------------------------------------------- 1 | export 'account/export.dart'; 2 | export 'biometrics/export.dart'; 3 | export 'medias/export.dart'; 4 | export 'notifications/export.dart'; 5 | export 'posts/export.dart'; 6 | export 'settings/export.dart'; 7 | export 'users/export.dart'; 8 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'mnemonic_backup_popup/index.dart'; 2 | export 'home_screen_top_bar_posts/index.dart'; 3 | export 'home_screen_top_bar_account/index.dart'; 4 | export 'posts_list/index.dart'; 5 | export 'notifications_main_content/index.dart'; 6 | -------------------------------------------------------------------------------- /lib/ui/widgets/post_content/widgets/post_poll_content/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const List pollColors = [ 4 | Color(0xFFF277B0), 5 | Color(0xFFFD875B), 6 | Color(0xFF57C9F4), 7 | Color(0xFF8164E5), 8 | Color(0xFF57D3A3), 9 | ]; 10 | -------------------------------------------------------------------------------- /lib/entities/posts/export.dart: -------------------------------------------------------------------------------- 1 | export 'extensions_polls.dart'; 2 | export 'extensions_reactions.dart'; 3 | export 'post.dart'; 4 | export 'post_status.dart'; 5 | export 'polls/export.dart'; 6 | export 'medias/export.dart'; 7 | export 'reactions/export.dart'; 8 | export 'link_preview.dart'; 9 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/posts_list/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'posts_bottom_loader/index.dart'; 2 | export 'posts_list_loading_container/index.dart'; 3 | export 'posts_list_syncing_indicator/index.dart'; 4 | export 'error_post/index.dart'; 5 | export 'error_post_message/index.dart'; 6 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /distribution/whatsnew/whatsnew-en-US: -------------------------------------------------------------------------------- 1 | • Added the possibility of controlling multiple accounts 2 | • Changed the reactions and likes visualization 3 | • Added the possibility of scrolling to the top of the posts list by clicking the bottom button 4 | • UI and UX improvements 5 | • Bug fixes and performance improvements 6 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lib/repositories/medias/source_medias_remote.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /// Represents a remote source for medias. 4 | abstract class RemoteMediasSource { 5 | /// Allows to upload the given [File] to the remote server, returning 6 | /// the remote reference to it. 7 | Future uploadMedia(File file); 8 | } 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/widgets/account_edit_body/widgets/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_cover_image_editor/index.dart'; 2 | export 'account_text_info_editor/index.dart'; 3 | export 'image_picker/index.dart'; 4 | export 'account_profile_image_editor/index.dart'; 5 | export 'account_edit_error_popup/index.dart'; 6 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/export.dart: -------------------------------------------------------------------------------- 1 | export 'chain_poll_data.dart'; 2 | export 'chain_poll_option.dart'; 3 | export 'msg_add_post_reaction.dart'; 4 | export 'msg_answer_poll.dart'; 5 | export 'msg_create_post.dart'; 6 | export 'msg_remove_post_reaction.dart'; 7 | export 'msg_save_profile.dart'; 8 | export 'user_pictures.dart'; 9 | -------------------------------------------------------------------------------- /lib/ui/ui.dart: -------------------------------------------------------------------------------- 1 | export 'package:font_awesome_flutter/font_awesome_flutter.dart'; 2 | 3 | export 'blocs/export.dart'; 4 | export 'localization/export.dart'; 5 | export 'screens/export.dart'; 6 | export 'theme/export.dart'; 7 | export 'widgets/export.dart'; 8 | export 'utils/export.dart'; 9 | export 'models/export.dart'; 10 | -------------------------------------------------------------------------------- /lib/ui/theme/spaces.dart: -------------------------------------------------------------------------------- 1 | class ThemeSpaces { 2 | static const double smallGutter = 4.0; 3 | static const double mediumGutter = 6.0; 4 | static const double largeGutter = 8.0; 5 | 6 | static const double smallMargin = 8.0; 7 | static const double mediumMargin = 16.0; 8 | static const double largeMargin = 24.0; 9 | } 10 | -------------------------------------------------------------------------------- /lib/usecases/medias/repository_medias.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | /// Represents the repository to use when dealing with medias. 4 | abstract class MediasRepository { 5 | /// Allows to upload the given [File] to the remote server, returning 6 | /// the remote reference to it. 7 | Future uploadMedia(File file); 8 | } 9 | -------------------------------------------------------------------------------- /test/usecases/posts/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:mockito/mockito.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily mock a [PostsRepository] instance. We declare it 5 | /// here so that we can re-use it inside different tests. 6 | class PostsRepositoryMock extends Mock implements PostsRepository {} 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/ui/utils/icons/icon_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// Extends [IconData] to properly show a Mooncake icon. 4 | class IconDataMooncake extends IconData { 5 | const IconDataMooncake(int codePoint) 6 | : super( 7 | codePoint, 8 | fontFamily: 'Mooncake', 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /lib/entities/entities.dart: -------------------------------------------------------------------------------- 1 | export 'package:alan/alan.dart'; 2 | 3 | export 'account/export.dart'; 4 | export 'app/export.dart'; 5 | export 'emojis/export.dart'; 6 | export 'mnemonic/export.dart'; 7 | export 'notifications/export.dart'; 8 | export 'posts/export.dart'; 9 | export 'user/export.dart'; 10 | export 'settings/export.dart'; 11 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_report_post.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_email_sender/flutter_email_sender.dart'; 2 | 3 | /// Sends and email about a post reported 4 | class ReportPostUseCase { 5 | /// Syncs the locally stored data to the chain. 6 | Future send(Email email) async { 7 | await FlutterEmailSender.send(email); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.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: 0216953674ba2960994c65ccd83d74305465daa1 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /test_resources/chain/websocket_event.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": { 3 | "data": { 4 | "type": "Tx", 5 | "value": { 6 | "TxResult": { 7 | "height": "15914", 8 | "index": 0, 9 | "tx": "10BF44337A7D0A54169D9C057E013BCD8B2694C970479DFD2068445217CF155C" 10 | } 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/ui/blocs/export.dart: -------------------------------------------------------------------------------- 1 | export 'account_read/export.dart'; 2 | export 'home/export.dart'; 3 | export 'mnemonic/export.dart'; 4 | export 'navigator/export.dart'; 5 | export 'notifications/export.dart'; 6 | export 'recover_account/export.dart'; 7 | export 'posts_list/export.dart'; 8 | export 'post_details/export.dart'; 9 | export 'simple_bloc_delegate.dart'; 10 | -------------------------------------------------------------------------------- /test/usecases/notifications/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:mockito/mockito.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily mock a [NotificationsRepository] instance. 5 | /// We define it to keep the code DRY and avoid duplicated. 6 | class NotificationsRepositoryMock extends Mock 7 | implements NotificationsRepository {} 8 | -------------------------------------------------------------------------------- /test/usecases/settings/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:mockito/mockito.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily mock a [SettingsRepository] instance. 5 | /// This is defined here so that it can be used by multiple tests to keep 6 | /// the code DRY. 7 | class SettingsRepositoryMock extends Mock implements SettingsRepository {} 8 | -------------------------------------------------------------------------------- /test/usecases/biometrics/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:local_auth/local_auth.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | 4 | /// Allows to mock a [LocalAuthentication] instance. 5 | /// We declare it here cause it might be used by different usecases and 6 | /// we want to prevent duplicated code. 7 | class LocalAuthenticationMock extends Mock implements LocalAuthentication {} 8 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/usecases/account/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:mockito/mockito.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Mocks the [UserRepository] interface to make tests simpler. 5 | /// It is here because it will be used by most of the account tests and 6 | /// we do not want to replicate code ;) 7 | class UserRepositoryMock extends Mock implements UserRepository {} 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /test/sources/helpers.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | import 'package:meta/meta.dart'; 3 | 4 | /// Allows to create an http mock response having the given [body] and [status]. 5 | http.Response simpleResponse({@required String body, int status}) { 6 | return http.Response(body, status ?? 200, headers: { 7 | 'Content-Type': 'application/json', 8 | 'Authorization': '', 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /test_resources/posts/post_valid_children.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "86", 3 | "parent_id": "0", 4 | "message": "2", 5 | "created": "2020-01-20T12:39:02.855Z", 6 | "last_edited": "0001-01-01T00:00:00Z", 7 | "allows_comments": true, 8 | "subspace": "mooncake", 9 | "creator": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 10 | "reactions": [], 11 | "children": [ 12 | "87", 13 | "88" 14 | ] 15 | } -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /lib/repositories/settings/source_settings_local.dart: -------------------------------------------------------------------------------- 1 | abstract class LocalSettingsSource { 2 | /// Save the key and value locally. 3 | Future save(String key, value); 4 | 5 | /// Returns value of the given key and null if not found. 6 | Future get(String key); 7 | 8 | /// Returns a stream that emits all future changes to the value of the setting having the given [key] 9 | Stream watch(String key); 10 | } 11 | -------------------------------------------------------------------------------- /test/entities/posts/polls/poll_option_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | 4 | void main() { 5 | final option = PollOption(text: 'This is a poll option', id: 1); 6 | 7 | test('toJson and fromJson', () { 8 | final json = option.toJson(); 9 | final fromJson = PollOption.fromJson(json); 10 | expect(fromJson, equals(option)); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | # https://docs.codecov.io/docs/commit-status 2 | coverage: 3 | status: 4 | project: 5 | default: 6 | # basic 7 | target: 0% 8 | threshold: 0% 9 | base: 0% 10 | # advanced 11 | branches: null 12 | if_no_uploads: error 13 | if_not_found: success 14 | if_ci_failed: error 15 | only_pulls: false 16 | flags: null 17 | paths: null 18 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_generate_mnemonic.dart: -------------------------------------------------------------------------------- 1 | import 'package:bip39/bip39.dart' as bip39; 2 | 3 | /// Allows to easily generate a new mnemonic that can be used to 4 | /// create a new account. 5 | class GenerateMnemonicUseCase { 6 | /// Generates a new random 24-word mnemonic. 7 | Future> generate() async { 8 | final mnemonic = bip39.generateMnemonic(strength: 256); 9 | return mnemonic.split(' '); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/entities/posts/polls/poll_answer_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | 4 | void main() { 5 | final answer = PollAnswer(user: User.fromAddress('address'), answer: 1); 6 | 7 | test('toJson and fromJson', () { 8 | final json = answer.toJson(); 9 | final fromJson = PollAnswer.fromJson(json); 10 | expect(fromJson, equals(answer)); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /lib/ui/dependency_injection.dart: -------------------------------------------------------------------------------- 1 | import 'package:dependencies/dependencies.dart'; 2 | import 'package:mooncake/ui/blocs/export.dart'; 3 | 4 | /// Dependency injection module that defines how to build 5 | /// some of the Bloc instances that might be useful somewhere else. 6 | class BlocsModule implements Module { 7 | @override 8 | void configure(Binder binder) { 9 | binder..bindFactory((injector, params) => NavigatorBloc.create()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/posts/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:alan/alan.dart'; 2 | import 'package:mooncake/sources/sources.dart'; 3 | 4 | /// Initializes the codec to properly register all the types. 5 | void initializeCodec() { 6 | Codec.registerMsgType('desmos/MsgCreatePost', MsgCreatePost); 7 | Codec.registerMsgType('desmos/MsgAddPostReaction', MsgAddPostReaction); 8 | Codec.registerMsgType( 9 | 'desmos/MsgRemovePostReaction', 10 | MsgRemovePostReaction, 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 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 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test_resources/posts/post_valid_optdata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "1", 3 | "parent_id": "0", 4 | "message": "This is a post", 5 | "created": "2019-12-11T07:57:54.03384Z", 6 | "last_edited": "0001-01-01T00:00:00Z", 7 | "allows_comments": false, 8 | "subspace": "", 9 | "optional_data": { 10 | "external_reference": "dwitter-2019-12-13T08:51:32.262217" 11 | }, 12 | "creator": "desmos17573axzcrmq6w5jwx27qlf9d90lcgkfmsrjycg", 13 | "reactions": [], 14 | "children": [] 15 | } -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:pedantic/analysis_options.1.9.0.yaml 2 | 3 | analyzer: 4 | exclude: 5 | - build/** 6 | - lib/**/*.g.dart 7 | - test/**/*.g.dart 8 | - tool/**/*.g.dart 9 | - lib/main.reflectable.dart 10 | - lib/**/*.reflectable.dart 11 | - test/**/*.reflectable.dart 12 | strong-mode: 13 | implicit-casts: false 14 | 15 | # enable-experiment: 16 | # - non-nullable 17 | 18 | linter: 19 | rules: 20 | - camel_case_types 21 | -------------------------------------------------------------------------------- /test/entities/mnemonic/mnemonic_data_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | 4 | void main() { 5 | final data = MnemonicData( 6 | encryptedMnemonicBase64: 'encrypted_mnemonic_base64', 7 | ivBase64: 'iv_base_64', 8 | ); 9 | 10 | test('toJson and fromJson', () { 11 | final json = data.toJson(); 12 | final fromJson = MnemonicData.fromJson(json); 13 | expect(fromJson, equals(data)); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /test/entities/app/constants_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | 4 | void main() { 5 | test('constants values', () { 6 | expect(Constants.EXPLORER, equals('https://morpheus.desmos.network')); 7 | expect(Constants.SUBSPACE, 8 | '2bdf5932925584b9a86470bea60adce69041608a447f84a3317723aa5678ec88'); 9 | expect(Constants.FEE_TOKEN, equals('udaric')); 10 | expect(Constants.LIKE_REACTION, equals('❤')); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /test/mocks/account.dart: -------------------------------------------------------------------------------- 1 | import 'package:alan/alan.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | 4 | final CosmosAccount cosmosAccount = CosmosAccount( 5 | accountNumber: '153', 6 | sequence: '45', 7 | address: 'desmos1ew60ztvqxlf5kjjyyzxf7hummlwdadgesu3725', 8 | coins: [ 9 | StdCoin(amount: '10000', denom: 'udaric'), 10 | ], 11 | ); 12 | 13 | // ignore: must_be_immutable 14 | class MockWallet extends Mock implements Wallet { 15 | @override 16 | String get bech32Address => 'address'; 17 | } 18 | -------------------------------------------------------------------------------- /lib/ui/blocs/notifications/notifications_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | /// Represents a generic event of the notification event. 4 | abstract class NotificationsEvent extends Equatable { 5 | const NotificationsEvent(); 6 | 7 | @override 8 | List get props => []; 9 | } 10 | 11 | /// Tells the Bloc that it needs to start loading the notifications. 12 | class LoadNotifications extends NotificationsEvent { 13 | @override 14 | String toString() => 'LoadNotifications'; 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/forbole/mooncake/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.forbole.mooncake 2 | 3 | import androidx.annotation.NonNull 4 | import io.flutter.embedding.android.FlutterFragmentActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterFragmentActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Have a question? Ask it using this template 4 | title: '' 5 | labels: 'king/question' 6 | assignees: '' 7 | 8 | --- 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lib/entities/posts/extensions_polls.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Defines a set of useful extensions on the [PostPoll] type. 4 | extension PollsExt on PostPoll { 5 | /// Tells whether `this` [PostPoll] contains an answer from the user 6 | /// having the given [address] with the given [value]. 7 | bool containsAnswerFrom(String address, int value) { 8 | return userAnswers.where((element) { 9 | return element.user.address == address && element.answer == value; 10 | }).isNotEmpty; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/repositories/users/source_users_local.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the source that stores local information about the users. 4 | abstract class LocalUsersSource { 5 | Stream> get blockedUsersStream; 6 | 7 | /// Blocks the given [user] locally. 8 | Future blockUser(User user); 9 | 10 | /// Unblocks the given [user]. 11 | Future unblockUser(User user); 12 | 13 | /// Returns the list of all the blocked users. 14 | Future> getBlockedUsers(); 15 | } 16 | -------------------------------------------------------------------------------- /test_resources/chain/chain_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "height": "0", 3 | "result": { 4 | "id": "1", 5 | "parent_id": "0", 6 | "message": "This is a post", 7 | "created": "2019-12-11T07:57:54.03384Z", 8 | "last_edited": "0001-01-01T00:00:00Z", 9 | "allows_comments": false, 10 | "subspace": "", 11 | "optional_data": { 12 | "external_reference": "dwitter-2019-12-13T08:51:32.262217" 13 | }, 14 | "creator": "desmos17573axzcrmq6w5jwx27qlf9d90lcgkfmsrjycg", 15 | "reactions": [], 16 | "children": [] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/dependency_injector.dart: -------------------------------------------------------------------------------- 1 | import 'package:dependencies/dependencies.dart'; 2 | import 'package:firebase_analytics/firebase_analytics.dart'; 3 | import 'package:flutter_local_notifications/flutter_local_notifications.dart'; 4 | import 'package:local_auth/local_auth.dart'; 5 | 6 | class UtilsModule implements Module { 7 | @override 8 | void configure(Binder binder) { 9 | binder 10 | ..bindSingleton(FlutterLocalNotificationsPlugin()) 11 | ..bindSingleton(FirebaseAnalytics()) 12 | ..bindSingleton(LocalAuthentication()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/usecases/notifications/repository_notifications.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the repository that should be used when dealing with 4 | /// user notifications. 5 | abstract class NotificationsRepository { 6 | /// Returns the list of notifications that are 7 | /// currently stored inside the device. 8 | Future> getNotifications(); 9 | 10 | /// Returns a Stream that emits all the new notifications 11 | /// when they are created. 12 | Stream get liveNotificationsStream; 13 | } 14 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_delete_posts.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to delete the locally stored posts. 5 | class DeletePostsUseCase { 6 | final PostsRepository _postsRepository; 7 | 8 | DeletePostsUseCase({ 9 | @required PostsRepository postsRepository, 10 | }) : assert(postsRepository != null), 11 | _postsRepository = postsRepository; 12 | 13 | /// Deletes the locally stored posts. 14 | Future delete() { 15 | return _postsRepository.deletePosts(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/posts_list/widgets/posts_bottom_loader/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | class BottomLoader extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | padding: EdgeInsets.all(8), 9 | alignment: Alignment.center, 10 | child: Center( 11 | child: SizedBox( 12 | width: 33, 13 | height: 33, 14 | child: LoadingIndicator(), 15 | ), 16 | ), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test_resources/account/account_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "height": "217386", 3 | "result": { 4 | "type": "cosmos-sdk/Account", 5 | "value": { 6 | "address": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 7 | "coins": [ 8 | { 9 | "denom": "udaric", 10 | "amount": "10000000" 11 | } 12 | ], 13 | "public_key": { 14 | "type": "tendermint/PubKeySecp256k1", 15 | "value": "A735NvHpqbi+AboXD2win9kHAVGJo+O1VeuKUASypGe3" 16 | }, 17 | "account_number": "54", 18 | "sequence": "39" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_get_accounts.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | 5 | class GetAccountsUseCase { 6 | final UserRepository _userRepository; 7 | 8 | GetAccountsUseCase({ 9 | @required UserRepository userRepository, 10 | }) : assert(userRepository != null), 11 | _userRepository = userRepository; 12 | 13 | /// Returns all locally stored accounts that can be used. 14 | Future> all() { 15 | return _userRepository.getAccounts(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/notifications/dependency_injection.dart: -------------------------------------------------------------------------------- 1 | import 'package:dependencies/dependencies.dart'; 2 | import 'package:mooncake/notifications/notifications.dart'; 3 | 4 | /// Dependency injection module that builds the different 5 | /// instances for the classes related to the notifications management. 6 | class NotificationsModule implements Module { 7 | @override 8 | void configure(Binder binder) { 9 | binder 10 | ..bindLazySingleton( 11 | (injector, _) => NotificationTapHandler( 12 | navigatorBloc: injector.get(), 13 | )); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/usecases/users/usecase_block_user.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to block a specified user. 6 | class BlockUserUseCase { 7 | final UsersRepository _usersRepository; 8 | 9 | BlockUserUseCase({ 10 | @required UsersRepository usersRepository, 11 | }) : assert(usersRepository != null), 12 | _usersRepository = usersRepository; 13 | 14 | /// Block the given [user]. 15 | Future block(User user) { 16 | return _usersRepository.blockUser(user); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/entities/emojis/emoji_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_emoji/flutter_emoji.dart'; 2 | 3 | class EmojiUtils { 4 | /// Given the [unicode] of an emoji, returns the `:code:` representation 5 | /// of such emoji. 6 | static String getEmojiCode(String unicode) { 7 | final parser = EmojiParser(); 8 | return parser.unemojify(unicode); 9 | } 10 | 11 | /// Given an emoji [code], returns the corresponding rune that identifies 12 | /// such emoji. 13 | static String getEmojiRune(String code) { 14 | final parser = EmojiParser(); 15 | return parser.emojify(code).replaceAll('️', ''); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/usecases/settings/repository_settings.dart: -------------------------------------------------------------------------------- 1 | /// Represents the repository that must be used when dealing the settings 2 | /// that the user can change. 3 | abstract class SettingsRepository { 4 | /// Saves the given [value] associating it to the specified [key]. 5 | Future save(String key, dynamic value); 6 | 7 | /// Reads the value associated to the given [key]. 8 | /// If not value can be read, returns `null` instead. 9 | Future get(String key); 10 | 11 | /// Returns a [Stream] that emits a value each time the value for the setting having the given [key] is changed. 12 | Stream watch(String key); 13 | } 14 | -------------------------------------------------------------------------------- /lib/entities/notifications/notification.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'notification.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Map _$NotificationDataToJson(NotificationData instance) => 10 | { 11 | 'type': instance.type, 12 | 'date': NotificationData.dateToJson(instance.date), 13 | 'title': instance.title, 14 | 'body': instance.body, 15 | 'action': instance.action, 16 | }; 17 | -------------------------------------------------------------------------------- /lib/ui/widgets/loading_indicator/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Represents an indicator that tells the user that data is being loaded. 4 | class LoadingIndicator extends StatelessWidget { 5 | final Color color; 6 | const LoadingIndicator({Key key, this.color}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Center( 11 | child: CircularProgressIndicator( 12 | strokeWidth: 2, 13 | valueColor: AlwaysStoppedAnimation( 14 | color ?? Theme.of(context).colorScheme.primary, 15 | ), 16 | ), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_get_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to retrieve the current user of the application. 6 | class GetAccountUseCase { 7 | final UserRepository _userRepository; 8 | 9 | GetAccountUseCase({@required UserRepository userRepository}) 10 | : _userRepository = userRepository; 11 | 12 | /// Returns the locally stored [MooncakeAccount] having the given [address]. 13 | Future single(String address) { 14 | return _userRepository.getAccount(address); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/utils/measure_exec_time.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | /// Measures the execution time of the given [function] returning its result. 4 | /// If prints the time on the console, using the optional [name] to identify the 5 | /// operation. 6 | Future measureExecTime( 7 | Future Function() function, { 8 | String name = '', 9 | }) async { 10 | if (kReleaseMode) { 11 | // DO nothing in release mode 12 | return function(); 13 | } 14 | 15 | final stopWatch = Stopwatch()..start(); 16 | final result = await function(); 17 | print('$name execution time: ${stopWatch.elapsedMilliseconds}'); 18 | return result; 19 | } 20 | -------------------------------------------------------------------------------- /lib/repositories/user/source_user_remote.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the remote source that needs to be used when wanting to 4 | /// deal with account data. 5 | abstract class RemoteUserSource { 6 | /// Returns the object containing the data 7 | /// of the current application user. 8 | Future getAccount(String address); 9 | 10 | /// Allows to sends funds from the faucet to the specified [user]. 11 | Future fundAccount(MooncakeAccount user); 12 | 13 | /// Saves the given [account] into the remote repository. 14 | Future saveAccount(MooncakeAccount account); 15 | } 16 | -------------------------------------------------------------------------------- /lib/ui/utils/extensions/user_ext.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | import 'package:mooncake/utils/utils.dart'; 3 | 4 | /// Contains a set of extension methods for the user class. 5 | extension UserExt on User { 6 | /// Returns the name that should be used on the screen 7 | String get screenName { 8 | if (moniker != null && moniker.isNotEmpty) return moniker; 9 | 10 | if (address == null) { 11 | Logger.log('User $this is invalid'); 12 | return ''; 13 | } 14 | 15 | return address.substring(0, 10) + 16 | '...' + 17 | address.substring(address.length - 5, address.length); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/usecases/biometrics/usecase_can_use_biometric.dart: -------------------------------------------------------------------------------- 1 | import 'package:local_auth/local_auth.dart'; 2 | import 'package:meta/meta.dart'; 3 | 4 | /// Tells whether this device allows for biometrics authentication or not. 5 | class CanUseBiometricsUseCase { 6 | final LocalAuthentication _localAuthentication; 7 | 8 | CanUseBiometricsUseCase({@required LocalAuthentication localAuthentication}) 9 | : assert(localAuthentication != null), 10 | _localAuthentication = localAuthentication; 11 | 12 | /// Returns true if device is capable of checking biometrics 13 | Future check() { 14 | return _localAuthentication.canCheckBiometrics; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/usecases/posts/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_posts.dart'; 2 | export 'usecase_manage_post_reactions.dart'; 3 | export 'usecase_create_post.dart'; 4 | export 'usecase_delete_posts.dart'; 5 | export 'usecase_get_comments.dart'; 6 | export 'usecase_get_post_details.dart'; 7 | export 'usecase_hide_post.dart'; 8 | export 'usecase_get_home_posts.dart'; 9 | export 'usecase_get_home_remote_events.dart'; 10 | export 'usecase_save_post.dart'; 11 | export 'usecase_sync.dart'; 12 | export 'usecase_update_posts_status.dart'; 13 | export 'usecase_vote_poll.dart'; 14 | export 'usecase_report_post.dart'; 15 | export 'usecase_update_post.dart'; 16 | export 'usecase_delete_post.dart'; 17 | -------------------------------------------------------------------------------- /lib/entities/posts/polls/poll_option.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'poll_option.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PollOption _$PollOptionFromJson(Map json) { 10 | return PollOption( 11 | id: json['id'] as int, 12 | text: json['text'] as String, 13 | ); 14 | } 15 | 16 | Map _$PollOptionToJson(PollOption instance) => 17 | { 18 | 'id': instance.id, 19 | 'text': instance.text, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_refresh_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily refresh the account. 5 | class RefreshAccountUseCase { 6 | final UserRepository _userRepository; 7 | 8 | RefreshAccountUseCase({ 9 | @required UserRepository userRepository, 10 | }) : assert(userRepository != null), 11 | _userRepository = userRepository; 12 | 13 | /// Refreshes the account having the given [address] 14 | /// an emits any new change using the proper stream. 15 | Future refresh(String address) { 16 | return _userRepository.refreshAccount(address); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/usecases/settings/usecase_watch_setting.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily watch any setting value. 5 | class WatchSettingUseCase { 6 | final SettingsRepository _settingsRepository; 7 | 8 | WatchSettingUseCase({ 9 | @required SettingsRepository settingsRepository, 10 | }) : assert(settingsRepository != null), 11 | _settingsRepository = settingsRepository; 12 | 13 | /// Returns a [Stream] that emits all the values that will be stored to the setting having the given [key]. 14 | Stream watch({String key}) { 15 | return _settingsRepository.watch(key); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/ui/utils/helpers/common_security.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/ui/ui.dart'; 2 | 3 | /// Returns the String representing the user mnemonic that has either been 4 | /// generated using the account creation feature, or that has been inserted 5 | /// using the recovery account feature. 6 | String getMnemonic( 7 | RecoverAccountState recoverAccountState, 8 | AccountState accountState, 9 | ) { 10 | if (accountState is AccountCreated) { 11 | return accountState.mnemonic.join(' '); 12 | } 13 | 14 | if (accountState is AccountCreatedWhileLoggedIn) { 15 | return accountState.mnemonic.join(' '); 16 | } 17 | 18 | return recoverAccountState.wordsList.join(' '); 19 | } 20 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_check_login.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily check whether the user has already logged in into the 5 | /// application or not. 6 | class CheckLoginUseCase { 7 | final UserRepository _userRepository; 8 | 9 | CheckLoginUseCase({ 10 | @required UserRepository userRepository, 11 | }) : assert(userRepository != null), 12 | _userRepository = userRepository; 13 | 14 | /// Returns `true` iff the user has logged in, `false` otherwise. 15 | Future isLoggedIn() async { 16 | return await _userRepository.getActiveAccount() != null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/usecases/settings/usecase_save_setting.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily save any setting value. 5 | class SaveSettingUseCase { 6 | final SettingsRepository _settingsRepository; 7 | 8 | SaveSettingUseCase({ 9 | @required SettingsRepository settingsRepository, 10 | }) : assert(settingsRepository != null), 11 | _settingsRepository = settingsRepository; 12 | 13 | /// Saves the given [value] associating it to the specified [key]. 14 | Future save({@required String key, @required dynamic value}) { 15 | return _settingsRepository.save(key, value); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/usecases/users/repository_users.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the repository that should be used when dealing with users. 4 | abstract class UsersRepository { 5 | /// Returns a stream that emits the list of blocked users as soon 6 | /// as a new user is blocked or an existing user is unblocked. 7 | Stream> blockedUsersStream; 8 | 9 | /// Returns the list of blocked users. 10 | Future> getBlockedUsers(); 11 | 12 | /// Allows to block the given [user]. 13 | Future blockUser(User user); 14 | 15 | /// Allows to unblock the given [user]. 16 | Future unblockUser(User user); 17 | } 18 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_generate_mnemonic_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | void main() { 5 | final generateMnemonicUseCase = GenerateMnemonicUseCase(); 6 | 7 | test('a mnemonic is never generated twice', () async { 8 | final mnemonics = []; 9 | for (var i = 0; i < 100; i++) { 10 | mnemonics.add(await generateMnemonicUseCase.generate()); 11 | } 12 | expect(mnemonics, isNotEmpty); 13 | 14 | // Remove duplicates and check for equality 15 | final mnemonicSet = mnemonics.toSet(); 16 | expect(mnemonics.length, equals(mnemonicSet.length)); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /lib/entities/posts/medias/post_media.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'post_media.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PostMedia _$PostMediaFromJson(Map json) { 10 | return PostMedia( 11 | uri: json['uri'] as String, 12 | mimeType: json['mime_type'] as String, 13 | ); 14 | } 15 | 16 | Map _$PostMediaToJson(PostMedia instance) => { 17 | 'uri': instance.uri, 18 | 'mime_type': instance.mimeType, 19 | }; 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mooncake-docs", 3 | "version": "0.0.4", 4 | "description": "Mooncake documentation", 5 | "main": "index.js", 6 | "scripts": { 7 | "docs:serve": "vuepress dev .docs", 8 | "docs:build": "vuepress build .docs" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "@vuepress/plugin-google-analytics": "^1.3.0", 14 | "lodash": "^4.17.21", 15 | "markdown-it": "^8.4.2", 16 | "markdown-it-meta": "0.0.1", 17 | "vuepress": "^1.2.0", 18 | "vuepress-plugin-element-tabs": "^0.2.8" 19 | }, 20 | "dependencies": { 21 | "axios": "^0.21.1", 22 | "vuepress-plugin-latex": "^0.1.3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/sources/user/remote/converters/user_msg_converter.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | import 'package:mooncake/sources/sources.dart'; 3 | 4 | /// Allows to convert a [MooncakeAccount] into a [StdMsg] object. 5 | class UserMsgConverter { 6 | /// Takes the given [local] and [remote] accounts, and transforms them 7 | /// into either a [MsgSaveProfile]. 8 | StdMsg toUserMsg(MooncakeAccount local) { 9 | return MsgSaveProfile( 10 | dtag: local.dtag, 11 | moniker: local.moniker, 12 | bio: local.bio, 13 | profilePic: local.profilePicUri, 14 | coverPic: local.coverPicUri, 15 | creator: local.address, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_sync.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to sync all the posts that have been created offline as well as 5 | /// all the likes and unlikes that have been set to posts. 6 | class SyncPostsUseCase { 7 | final PostsRepository _postsRepository; 8 | 9 | SyncPostsUseCase({ 10 | @required PostsRepository postsRepository, 11 | }) : assert(postsRepository != null), 12 | _postsRepository = postsRepository; 13 | 14 | /// Syncs the locally stored data to the chain. 15 | Future sync(String address) async { 16 | return _postsRepository.syncPosts(address); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_save_wallet.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to properly log in a user. 6 | class SaveWalletUseCase { 7 | final UserRepository _userRepository; 8 | 9 | SaveWalletUseCase({@required UserRepository userRepository}) 10 | : assert(userRepository != null), 11 | _userRepository = userRepository; 12 | 13 | /// Saves the given [mnemonic] into the encrypted storage of the 14 | /// device as the user wallet. 15 | Future saveWallet(String mnemonic) async { 16 | return _userRepository.saveWallet(mnemonic); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/usecases/settings/usecase_get_setting.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily read any setting value based on its key. 5 | class GetSettingUseCase { 6 | final SettingsRepository _settingsRepository; 7 | 8 | GetSettingUseCase({ 9 | @required SettingsRepository settingsRepository, 10 | }) : assert(settingsRepository != null), 11 | _settingsRepository = settingsRepository; 12 | 13 | /// Reads the value associated to the given [key]. 14 | /// If not value can be read, returns `null` instead. 15 | Future get({@required String key}) { 16 | return _settingsRepository.get(key); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/ui/widgets/post_action_comment/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../../mocks/posts.dart'; 5 | import '../../helper.dart'; 6 | 7 | void main() { 8 | testWidgets('MnemonicVisualizer: Displays export correctly', 9 | (WidgetTester tester) async { 10 | await tester.pumpWidget( 11 | makeTestableWidget( 12 | child: PostCommentAction(post: testPost), 13 | ), 14 | ); 15 | 16 | await tester.pumpAndSettle(); 17 | 18 | expect(find.byType(IconButton), findsOneWidget); 19 | expect(find.byType(FaIcon), findsOneWidget); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /test/ui/widgets/sync_snackbar/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('SyncSnackBar: Displays export correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: SyncSnackBar(), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | expect(find.byType(SizedBox), findsWidgets); 17 | expect(find.byIcon(FontAwesomeIcons.cloudUploadAlt), findsOneWidget); 18 | expect(find.text('syncingActivities'), findsOneWidget); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /lib/repositories/medias/medias_repository_impl.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:meta/meta.dart'; 4 | import 'package:mooncake/repositories/repositories.dart'; 5 | import 'package:mooncake/usecases/usecases.dart'; 6 | 7 | /// Implementation of [MediasRepository]. 8 | class MediasRepositoryImpl extends MediasRepository { 9 | final RemoteMediasSource _remoteMediasSource; 10 | 11 | MediasRepositoryImpl({ 12 | @required RemoteMediasSource remoteMediasSource, 13 | }) : assert(remoteMediasSource != null), 14 | _remoteMediasSource = remoteMediasSource; 15 | 16 | @override 17 | Future uploadMedia(File file) { 18 | return _remoteMediasSource.uploadMedia(file); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_set_account_active.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to set an account as the current actively used one 6 | class SetAccountActiveUsecase { 7 | final UserRepository _userRepository; 8 | 9 | SetAccountActiveUsecase({ 10 | @required UserRepository userRepository, 11 | }) : assert(userRepository != null), 12 | _userRepository = userRepository; 13 | 14 | /// Sets the given [account] as the current user account. 15 | Future setActive(MooncakeAccount account) { 16 | return _userRepository.setActiveAccount(account); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/ui/widgets/loading_indicator/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | 5 | void main() { 6 | testWidgets('LoadingIndicator: Displays correctly', 7 | (WidgetTester tester) async { 8 | await tester.pumpWidget( 9 | LoadingIndicator(), 10 | ); 11 | await tester.pump(const Duration(seconds: 3)); 12 | expect(find.byType(CircularProgressIndicator), findsOneWidget); 13 | expect( 14 | tester 15 | .widget( 16 | find.byType(CircularProgressIndicator)) 17 | .strokeWidth, 18 | 2, 19 | ); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/chain_poll_option.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'chain_poll_option.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ChainPollOption _$ChainPollOptionFromJson(Map json) { 10 | return ChainPollOption( 11 | id: json['id'] as String, 12 | text: json['text'] as String, 13 | ); 14 | } 15 | 16 | Map _$ChainPollOptionToJson(ChainPollOption instance) => 17 | { 18 | 'id': instance.id, 19 | 'text': instance.text, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/user_pictures.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'user_pictures.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | UserPictures _$UserPicturesFromJson(Map json) { 10 | return UserPictures( 11 | cover: json['cover'] as String, 12 | profile: json['profile'] as String, 13 | ); 14 | } 15 | 16 | Map _$UserPicturesToJson(UserPictures instance) => 17 | { 18 | 'cover': instance.cover, 19 | 'profile': instance.profile, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/ui/theme/fonts.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ThemeFonts { 4 | static TextTheme get iOSTextTheme { 5 | return TextTheme( 6 | headline1: TextStyle(fontFamily: 'SF-Pro'), 7 | headline2: TextStyle(fontFamily: 'SF-Pro'), 8 | headline3: TextStyle(fontFamily: 'SF-Pro'), 9 | headline4: TextStyle(fontFamily: 'SF-Pro'), 10 | headline5: TextStyle(fontFamily: 'SF-Pro'), 11 | headline6: TextStyle(fontFamily: 'SF-Pro'), 12 | subtitle1: TextStyle(fontFamily: 'SF-Pro'), 13 | subtitle2: TextStyle(fontFamily: 'SF-Pro'), 14 | bodyText1: TextStyle(fontFamily: 'SF-Pro'), 15 | bodyText2: TextStyle(fontFamily: 'SF-Pro'), 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/entities/account/extensions.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Defines a set of usesulf extensions on the [MooncakeAccount] data type. 4 | extension AccountExtensions on MooncakeAccount { 5 | /// Tells whether or not this account has liked the given [post]. 6 | bool hasLiked(Post post) { 7 | return post.reactions.containsFrom(this, Constants.LIKE_REACTION); 8 | } 9 | 10 | /// Transforms this instance of [MooncakeAccount] into a [User] instance. 11 | User toUser() { 12 | return User( 13 | address: address, 14 | dtag: dtag, 15 | moniker: moniker, 16 | bio: bio, 17 | profilePicUri: profilePicUri, 18 | coverPicUri: coverPicUri, 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/usecases/account/export.dart: -------------------------------------------------------------------------------- 1 | export 'repository_user.dart'; 2 | export 'usecase_check_login.dart'; 3 | export 'usecase_encrypt_mnemonic.dart'; 4 | export 'usecase_generate_mnemonic.dart'; 5 | export 'usecase_get_account.dart'; 6 | export 'usecase_get_accounts.dart'; 7 | export 'usecase_get_active_account.dart'; 8 | export 'usecase_get_authentication_method.dart'; 9 | export 'usecase_get_mnemonic.dart'; 10 | export 'usecase_decrypt_mnemonic.dart'; 11 | export 'usecase_log_in.dart'; 12 | export 'usecase_logout.dart'; 13 | export 'usecase_refresh_account.dart'; 14 | export 'usecase_save_account.dart'; 15 | export 'usecase_set_authentication_method.dart'; 16 | export 'usecase_set_account_active.dart'; 17 | export 'usecase_save_wallet.dart'; 18 | -------------------------------------------------------------------------------- /test/ui/widgets/posts_list_empty_container/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('PostsListEmptyContainer: Displays export correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: PostsListEmptyContainer(), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | expect(find.text('noPostsYet'), findsOneWidget); 17 | expect( 18 | tester.widget(find.byType(Container)).key, 19 | Key('__postsEmptyContainer__'), 20 | ); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /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 | Flutter/.last_build_id 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | Runner.xcodeproj/project.pbxproj 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /ios/Runner/Runner.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | com.apple.security.app-sandbox 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.personal-information.addressbook 12 | 13 | com.apple.security.personal-information.calendars 14 | 15 | com.apple.security.personal-information.location 16 | 17 | com.apple.security.personal-information.photos-library 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_hide_post.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to easily hide a post from the user view. 6 | class HidePostUseCase { 7 | final PostsRepository _postsRepository; 8 | 9 | HidePostUseCase({ 10 | @required PostsRepository postsRepository, 11 | }) : assert(postsRepository != null), 12 | _postsRepository = postsRepository; 13 | 14 | /// Hides the given [post] from the view of the user. 15 | Future hide(Post post) async { 16 | final hiddenPost = post.copyWith(hidden: true); 17 | await _postsRepository.savePost(hiddenPost); 18 | return hiddenPost; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/usecases/posts/usecase_delete_posts_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | PostsRepository repository; 9 | DeletePostsUseCase deletePostsUseCase; 10 | 11 | setUp(() { 12 | repository = PostsRepositoryMock(); 13 | deletePostsUseCase = DeletePostsUseCase(postsRepository: repository); 14 | }); 15 | 16 | test('delete performs the correct calls', () async { 17 | when(repository.deletePosts()).thenAnswer((_) => Future.value(null)); 18 | 19 | await deletePostsUseCase.delete(); 20 | 21 | verify(repository.deletePosts()).called(1); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /lib/ui/blocs/simple_bloc_delegate.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | 3 | /// Extension of [BlocObserver] that allows to debug all the events, 4 | /// transactions and errors that might verify. 5 | class SimpleBlocObserver extends BlocObserver { 6 | @override 7 | void onEvent(Bloc bloc, Object event) { 8 | super.onEvent(bloc, event); 9 | print(event.toString()); 10 | } 11 | 12 | @override 13 | void onTransition(Bloc bloc, Transition transition) { 14 | super.onTransition(bloc, transition); 15 | print(transition.toString()); 16 | } 17 | 18 | @override 19 | void onError(Cubit cubit, Object error, StackTrace stackTrace) { 20 | super.onError(cubit, error, stackTrace); 21 | print(error.toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/posts_list/widgets/error_post_message/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | class ErrorPostMessage extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | padding: EdgeInsets.only( 9 | left: 10, 10 | right: 10, 11 | top: 15, 12 | bottom: 0, 13 | ), 14 | color: Theme.of(context).colorScheme.secondaryVariant, 15 | child: Text( 16 | PostsLocalizations.of(context).translate(Messages.postUploadError), 17 | textAlign: TextAlign.left, 18 | style: TextStyle(fontSize: 13, color: Colors.white), 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test_resources/posts/post_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "height": "0", 3 | "result": { 4 | "id": "56", 5 | "parent_id": "0", 6 | "message": "Hey, I can see a Dragon around", 7 | "created": "2020-01-14T18:18:56.489519633Z", 8 | "last_edited": "0001-01-01T00:00:00Z", 9 | "allows_comments": true, 10 | "subspace": "desmos", 11 | "creator": "desmos19u88x09tejnzwpsqnyhgjjglneuxghy6g3da2n", 12 | "reactions": [ 13 | { 14 | "owner": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 15 | "value": "🐉" 16 | }, 17 | { 18 | "owner": "desmos14dm0zdemeymhayucp7gchuus3k5m344f3v8nln", 19 | "value": ":star-struck:" 20 | } 21 | ], 22 | "children": [ 23 | "57" 24 | ] 25 | } 26 | } -------------------------------------------------------------------------------- /test/ui/widgets/posts_list_item/widgets/popup_content_tx_success/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/widgets/posts_list_item/widgets/export.dart'; 4 | import '../../../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('PostSuccessPopupContent: Displays export correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: PostSuccessPopupContent(txHash: 'txHash...'), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | expect(find.text('syncSuccessBrowseButton'), findsOneWidget); 17 | expect(find.byType(FlatButton), findsOneWidget); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /test/ui/widgets/post_action_add_reaction/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../../mocks/posts.dart'; 5 | import '../../helper.dart'; 6 | 7 | void main() { 8 | testWidgets('MnemonicVisualizer: Displays export correctly', 9 | (WidgetTester tester) async { 10 | await tester.pumpWidget( 11 | makeTestableWidget( 12 | child: PostAddReactionAction(post: testPost), 13 | ), 14 | ); 15 | 16 | await tester.pumpAndSettle(); 17 | 18 | expect(find.byType(SizedBox), findsWidgets); 19 | expect(find.byType(IconButton), findsWidgets); 20 | 21 | await tester.tap(find.byType(IconButton)); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /test/ui/widgets/posts_list_item/widgets/popup_content_tx_error/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/ui/widgets/posts_list_item/widgets/export.dart'; 3 | import '../../../../helper.dart'; 4 | 5 | void main() { 6 | testWidgets('PostErrorPopupContent: Displays export correctly', 7 | (WidgetTester tester) async { 8 | await tester.pumpWidget( 9 | makeTestableWidget( 10 | child: PostErrorPopupContent(error: 'a big error'), 11 | ), 12 | ); 13 | 14 | await tester.pumpAndSettle(); 15 | expect(find.text('syncErrorTitle'), findsOneWidget); 16 | expect(find.text('syncErrorDesc'), findsOneWidget); 17 | expect(find.text('syncErrorCopyButton'), findsOneWidget); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /test_resources/posts/post_valid_reactions.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "77", 3 | "parent_id": "0", 4 | "message": "Happy birthday Leo! 🎂🎉🎊", 5 | "created": "2020-01-18T19:48:02.552Z", 6 | "last_edited": "0001-01-01T00:00:00Z", 7 | "allows_comments": true, 8 | "subspace": "mooncake", 9 | "creator": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 10 | "reactions": [ 11 | { 12 | "owner": "desmos1z97x0m5zmq0502hha4s0z36hpy9zray3cq2a67", 13 | "value": "🎉" 14 | }, 15 | { 16 | "owner": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 17 | "value": "😃" 18 | }, 19 | { 20 | "owner": "desmos16f9wz7yg44pjfhxyn22kycs0qjy778ng877usl", 21 | "value": "😍" 22 | } 23 | ], 24 | "children": [ 25 | "92" 26 | ] 27 | } -------------------------------------------------------------------------------- /lib/entities/account/account_save_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:meta/meta.dart'; 3 | 4 | /// Represents the result of the action of editing the account. 5 | class AccountSaveResult extends Equatable { 6 | final bool success; 7 | final String error; 8 | 9 | AccountSaveResult({ 10 | @required this.success, 11 | @required this.error, 12 | }) : assert(success != null); 13 | 14 | factory AccountSaveResult.success() { 15 | return AccountSaveResult(success: true, error: null); 16 | } 17 | 18 | factory AccountSaveResult.error(String error) { 19 | return AccountSaveResult(success: false, error: error); 20 | } 21 | 22 | @override 23 | List get props { 24 | return [success, error]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_get_home_remote_events.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to get all the events that should require the user to refresh 5 | /// the home screen of the application. 6 | class GetHomeEventsUseCase { 7 | final PostsRepository _postsRepository; 8 | 9 | GetHomeEventsUseCase({ 10 | @required PostsRepository postsRepository, 11 | }) : assert(postsRepository != null), 12 | _postsRepository = postsRepository; 13 | 14 | /// Returns a [Stream] emitting a new item each time that a new event 15 | /// that should require the user to refresh the home page is emitted. 16 | Stream get stream { 17 | return _postsRepository.homeEventsStream; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/entities/posts/polls/poll_answer.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'poll_answer.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PollAnswer _$PollAnswerFromJson(Map json) { 10 | return PollAnswer( 11 | answer: json['answer'] as int, 12 | user: json['user'] == null 13 | ? null 14 | : User.fromJson(json['user'] as Map), 15 | ); 16 | } 17 | 18 | Map _$PollAnswerToJson(PollAnswer instance) => 19 | { 20 | 'answer': instance.answer, 21 | 'user': instance.user?.toJson(), 22 | }; 23 | -------------------------------------------------------------------------------- /lib/entities/mnemonic/mnemonic_data.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'mnemonic_data.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | MnemonicData _$MnemonicDataFromJson(Map json) { 10 | return MnemonicData( 11 | ivBase64: json['ivBase64'] as String, 12 | encryptedMnemonicBase64: json['encryptedMnemonicBase64'] as String, 13 | ); 14 | } 15 | 16 | Map _$MnemonicDataToJson(MnemonicData instance) => 17 | { 18 | 'ivBase64': instance.ivBase64, 19 | 'encryptedMnemonicBase64': instance.encryptedMnemonicBase64, 20 | }; 21 | -------------------------------------------------------------------------------- /lib/ui/widgets/posts_list_item/widgets/show_post_item_popup/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | 5 | /// Allows to show a popup having the given [content]. 6 | void showPostItemPopup({ 7 | @required BuildContext context, 8 | @required Widget content, 9 | }) { 10 | showDialog( 11 | context: context, 12 | builder: (buildContext) { 13 | return Dialog( 14 | key: PostsKeys.postItemPopup, 15 | shape: RoundedRectangleBorder( 16 | borderRadius: BorderRadius.circular(16), 17 | ), 18 | child: Container( 19 | padding: EdgeInsets.all(16), 20 | child: content, 21 | ), 22 | ); 23 | }, 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /test/ui/screens/user_wallet_screen/widgets/wallet_actions_list/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import '../../../../helper.dart'; 4 | import 'package:mooncake/ui/screens/user_wallet_screen/widgets/export.dart'; 5 | 6 | void main() { 7 | testWidgets('WalletActionsList: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: WalletActionsList(), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | 17 | expect(find.text('walletTitle'), findsOneWidget); 18 | expect(find.text('walletBodyText'), findsOneWidget); 19 | expect(tester.widget(find.byType(Image)).width, 150); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.60' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.3' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.3' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /test/entities/emojis/emojis_utils_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:mooncake/entities/emojis/emoji_utils.dart'; 3 | 4 | void main() { 5 | test('getEmojiCode', () { 6 | expect(EmojiUtils.getEmojiCode('🎉'), equals(':tada:')); 7 | expect(EmojiUtils.getEmojiCode('🍉'), equals(':watermelon:')); 8 | expect(EmojiUtils.getEmojiCode('❤'), equals(':heart:')); 9 | expect(EmojiUtils.getEmojiCode('👍'), equals(':thumbsup:')); 10 | }); 11 | 12 | test('getEmojiRune', () { 13 | expect(EmojiUtils.getEmojiRune(':tada:'), equals('🎉')); 14 | expect(EmojiUtils.getEmojiRune(':watermelon:'), equals('🍉')); 15 | expect(EmojiUtils.getEmojiRune(':heart:'), equals('❤')); 16 | expect(EmojiUtils.getEmojiRune(':thumbsup:'), equals('👍')); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /test/ui/widgets/post_content_message/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter_markdown/flutter_markdown.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../helper.dart'; 5 | import '../../../mocks/posts.dart'; 6 | 7 | void main() { 8 | testWidgets('PostMessage: Displays correctly', (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: PostMessage(post: testPost), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | 17 | expect(find.byType(MarkdownBody), findsOneWidget); 18 | expect( 19 | tester.widget(find.byType(MarkdownBody)).data, 20 | testPost.message.replaceAll('\n', ' \n'), 21 | ); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/forbole/mooncake/Application.kt: -------------------------------------------------------------------------------- 1 | package com.forbole.mooncake 2 | 3 | import io.flutter.app.FlutterApplication 4 | import io.flutter.plugin.common.PluginRegistry 5 | import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin 6 | import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService 7 | 8 | class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback { 9 | override fun onCreate() { 10 | super.onCreate() 11 | FlutterFirebaseMessagingService.setPluginRegistrant(this); 12 | } 13 | 14 | override fun registerWith(registry: PluginRegistry?) { 15 | FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/entities/account/authentication_method_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | 4 | void main() { 5 | group('toJson and fromJson', () { 6 | test('BiometricAuthentication', () { 7 | final auth = BiometricAuthentication(); 8 | final json = auth.toJson(); 9 | final fromJson = AuthenticationMethod.fromJson(json); 10 | expect(fromJson, equals(auth)); 11 | }); 12 | 13 | test('PasswordAuthentication', () { 14 | final auth = PasswordAuthentication( 15 | hashedPassword: '5f4dcc3b5aa765d61d8327deb882cf99', 16 | ); 17 | final json = auth.toJson(); 18 | final fromJson = PasswordAuthentication.fromJson(json); 19 | expect(fromJson, equals(auth)); 20 | }); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /test/ui/widgets/buttons/primary_light_button/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('PrimaryLightButton: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: PrimaryLightButton( 12 | child: Text('pineapples'), 13 | onPressed: () {}, 14 | ), 15 | ), 16 | ); 17 | await tester.pumpAndSettle(); 18 | 19 | expect(find.byType(PrimaryLightButton), findsOneWidget); 20 | expect(find.byType(Text), findsOneWidget); 21 | expect(find.text('pineapples'), findsOneWidget); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | selection.json 12 | 13 | # Vuepress 14 | **/.vuepress/dist/ 15 | 16 | # IntelliJ related 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea/ 21 | 22 | # Flutter/Dart/Pub related 23 | **/doc/api/ 24 | .dart_tool/ 25 | .flutter-plugins* 26 | .packages 27 | .pub-cache/ 28 | .pub/ 29 | build/ 30 | coverage/ 31 | ios/Podfile 32 | ios/Podfile.lock 33 | 34 | # Android releated 35 | *.apk 36 | *.aab 37 | 38 | # Web related 39 | lib/generated_plugin_registrant.dart 40 | node_modules/ 41 | 42 | # Exceptions to above rules. 43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 44 | 45 | # Secret data 46 | **/google-services.json 47 | **/GoogleService-Info.plist 48 | -------------------------------------------------------------------------------- /test/ui/screens/user_wallet_screen/widgets/empty_wallet/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import '../../../../helper.dart'; 4 | import 'package:mooncake/ui/screens/user_wallet_screen/widgets/export.dart'; 5 | 6 | void main() { 7 | testWidgets('EmptyWallet: Displays correctly', (WidgetTester tester) async { 8 | await tester.pumpWidget( 9 | makeTestableWidget( 10 | child: EmptyWallet(), 11 | ), 12 | ); 13 | 14 | await tester.pumpAndSettle(); 15 | 16 | expect(find.text('emptyWalletTitle'), findsOneWidget); 17 | expect(find.text('emptyWalletBody'), findsOneWidget); 18 | expect(find.byType(Image), findsOneWidget); 19 | expect(find.byType(Column), findsOneWidget); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /test/ui/widgets/mnemonic_visualizer/widgets/backup_mnemonic_details/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/widgets/mnemonic_visualizer/widgets/export.dart'; 4 | import '../../../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('BackupMnemonicDetails: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: BackupMnemonicDetails(), 12 | ), 13 | ); 14 | 15 | await tester.pumpAndSettle(); 16 | 17 | expect(find.byType(RichText), findsOneWidget); 18 | expect( 19 | tester.widget(find.byType(Container)).margin, 20 | EdgeInsets.only(bottom: 20), 21 | ); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_refresh_account_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | UserRepository repository; 9 | RefreshAccountUseCase refreshAccountUseCase; 10 | 11 | setUp(() { 12 | repository = UserRepositoryMock(); 13 | refreshAccountUseCase = RefreshAccountUseCase(userRepository: repository); 14 | }); 15 | 16 | test('refresh performs correct calls', () async { 17 | when(repository.refreshAccount('address')) 18 | .thenAnswer((_) => Future.value(null)); 19 | 20 | await refreshAccountUseCase.refresh('address'); 21 | 22 | verify(repository.refreshAccount('address')).called(1); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_biometrics_screen/blocs/biometrics/biometrics_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | /// Represents a generic event that is emitted regarding the biometric screen. 4 | abstract class BiometricsEvent extends Equatable { 5 | const BiometricsEvent(); 6 | 7 | @override 8 | List get props => []; 9 | } 10 | 11 | /// Tells the Bloc to check what type of biometric authentication the 12 | /// device supports. 13 | class CheckAuthenticationType extends BiometricsEvent { 14 | @override 15 | String toString() => 'CheckAuthenticationType'; 16 | } 17 | 18 | /// Tells the Bloc that the user wants to be authenticated. 19 | class AuthenticateWithBiometrics extends BiometricsEvent { 20 | @override 21 | String toString() => 'AuthenticateWithBiometrics'; 22 | } 23 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/posts_list/widgets/posts_list_loading_container/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | /// Represent the screen that is shown to the user when no posts are found. 5 | class PostsLoadingEmptyContainer extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | key: PostsKeys.postsEmptyContainer, 10 | child: Column( 11 | mainAxisSize: MainAxisSize.max, 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | LoadingIndicator(), 15 | SizedBox(height: 16), 16 | Text(PostsLocalizations.of(context).translate(Messages.loadingPosts)) 17 | ], 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/ui/screens/post_details_screen/widgets/post_details_loading/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/widgets/export.dart'; 3 | import 'package:mooncake/ui/localization/export.dart'; 4 | 5 | /// Represents the screen that is shown to the user while the post is loading. 6 | class PostDetailsLoading extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | child: Column( 11 | mainAxisSize: MainAxisSize.max, 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | LoadingIndicator(), 15 | SizedBox(height: 16), 16 | Text(PostsLocalizations.of(context).translate(Messages.loadingPost)), 17 | ], 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/ui/screens/login_screen/widgets/login_popup/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../../../helper.dart'; 5 | import 'package:mooncake/ui/screens/login_screen/widgets/export.dart'; 6 | 7 | void main() { 8 | testWidgets('LoginPopup: Displays correctly', (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: LoginPopup( 12 | content: Text('content'), 13 | ), 14 | ), 15 | ); 16 | 17 | await tester.pumpAndSettle(); 18 | expect(find.byType(GenericPopup), findsOneWidget); 19 | expect(find.byType(CustomPaint), findsWidgets); 20 | expect(find.text('content'), findsOneWidget); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/performance_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Performance report 3 | about: Create a report for a performance issue 4 | title: '' 5 | labels: 'kind/enhancement,type/performance' 6 | assignees: 'RiccardoM' 7 | 8 | --- 9 | 14 | 15 | ## Generic information 16 | - OS name and version: 17 | - Application build code: 18 | - Network type (mobile/Wi-Fi): 19 | 20 | ## Your problem 21 | 22 | -------------------------------------------------------------------------------- /lib/sources/medias/remote/models/ipfs/ipfs_upload_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'ipfs_upload_response.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | IpfsUploadResponse _$IpfsUploadResponseFromJson(Map json) { 10 | return IpfsUploadResponse( 11 | name: json['Name'] as String, 12 | hash: json['Hash'] as String, 13 | size: json['Size'] as String, 14 | ); 15 | } 16 | 17 | Map _$IpfsUploadResponseToJson(IpfsUploadResponse instance) => 18 | { 19 | 'Name': instance.name, 20 | 'Hash': instance.hash, 21 | 'Size': instance.size, 22 | }; 23 | -------------------------------------------------------------------------------- /test/ui/widgets/mnemonic_visualizer/widgets/mnemonic_item/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/widgets/mnemonic_visualizer/widgets/export.dart'; 4 | import '../../../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('MnemonicItem: Displays correctly', (WidgetTester tester) async { 8 | await tester.pumpWidget( 9 | makeTestableWidget( 10 | child: MnemonicItem(index: 0, word: 'apples'), 11 | ), 12 | ); 13 | 14 | await tester.pumpAndSettle(); 15 | 16 | expect(find.byType(Row), findsOneWidget); 17 | expect(find.text('apples'), findsOneWidget); 18 | expect( 19 | tester.widget(find.byType(Text).last).textAlign, 20 | TextAlign.center, 21 | ); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | 8 | jobs: 9 | 10 | build-and-deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 🛎️ 14 | uses: actions/checkout@v2 15 | with: 16 | persist-credentials: false 17 | 18 | - name: Build 🔧 19 | run: | 20 | npm install 21 | npm ci 22 | npm run docs:build 23 | echo 'mooncake.space' > .docs/.vuepress/dist/CNAME 24 | 25 | - name: Deploy 🚀 26 | if: github.ref == 'refs/heads/master' 27 | uses: JamesIves/github-pages-deploy-action@releases/v3 28 | with: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | BRANCH: gh-pages 31 | FOLDER: .docs/.vuepress/dist 32 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/chain_poll_option.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:meta/meta.dart'; 3 | 4 | part 'chain_poll_option.g.dart'; 5 | 6 | /// Represents a single option inside a post poll. 7 | @immutable 8 | @JsonSerializable(explicitToJson: true) 9 | class ChainPollOption { 10 | @JsonKey(name: 'id') 11 | final String id; 12 | 13 | @JsonKey(name: 'text') 14 | final String text; 15 | 16 | ChainPollOption({ 17 | @required this.id, 18 | @required this.text, 19 | }) : assert(id != null), 20 | assert(text != null); 21 | 22 | factory ChainPollOption.fromJson(Map json) { 23 | return _$ChainPollOptionFromJson(json); 24 | } 25 | 26 | Map toJson() { 27 | return _$ChainPollOptionToJson(this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/ui/screens/post_details_screen/widgets/post_details_loading/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | import 'package:flutter/material.dart'; 4 | import '../../../../helper.dart'; 5 | import 'package:mooncake/ui/screens/post_details_screen/widgets/export.dart'; 6 | 7 | void main() { 8 | testWidgets('PostDetailsLoading: Displays correctly', 9 | (WidgetTester tester) async { 10 | await tester.pumpWidget( 11 | makeTestableWidget( 12 | child: PostDetailsLoading(), 13 | ), 14 | ); 15 | 16 | await tester.pump(const Duration(seconds: 3)); 17 | 18 | expect(find.byType(LoadingIndicator), findsOneWidget); 19 | expect(find.byType(Column), findsOneWidget); 20 | expect(find.text('loadingPost'), findsOneWidget); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /test/usecases/settings/usecase_save_setting_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | SettingsRepository repository; 9 | SaveSettingUseCase saveSettingUseCase; 10 | 11 | setUp(() { 12 | repository = SettingsRepositoryMock(); 13 | saveSettingUseCase = SaveSettingUseCase(settingsRepository: repository); 14 | }); 15 | 16 | test('save performs the correct calls', () async { 17 | when(repository.save(any, any)).thenAnswer((_) => Future.value(null)); 18 | 19 | final key = 'key'; 20 | final value = 'value'; 21 | await saveSettingUseCase.save(key: key, value: value); 22 | 23 | verify(repository.save(key, value)).called(1); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## Description 8 | 9 | 10 | ## Checklist 11 | - [ ] Targeted PR against correct branch. 12 | - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. 13 | - [ ] Wrote unit tests. 14 | - [ ] Run flutter format. 15 | - [ ] Updated the documentation. 16 | - [ ] Added an entry to the `CHANGELOG.md` file. 17 | - [ ] Re-reviewed `Files changed` in the Github PR explorer. 18 | -------------------------------------------------------------------------------- /lib/ui/screens/export.dart: -------------------------------------------------------------------------------- 1 | export 'splash_screen/index.dart'; 2 | export 'login_screen/index.dart'; 3 | export 'recover_account_screen/index.dart'; 4 | export 'restore_mnemonic_backup_screen/index.dart'; 5 | export 'export_mnemonic_screen/index.dart'; 6 | export 'home_screen/index.dart'; 7 | export 'post_create_screen/index.dart'; 8 | export 'post_details_screen/index.dart'; 9 | export 'security_set_password_screen/index.dart'; 10 | export 'security_set_biometrics_screen/index.dart'; 11 | export 'security_backup_mnemonic_confirmation_screen/index.dart'; 12 | export 'security_login_password_screen/index.dart'; 13 | export 'security_login_biometrics_screen/index.dart'; 14 | export 'user_wallet_screen/index.dart'; 15 | export 'user_details_screen/index.dart'; 16 | export 'user_account_edit_screen/index.dart'; 17 | export 'lightbox_screen/index.dart'; 18 | -------------------------------------------------------------------------------- /test/usecases/users/usecase_block_user_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | import 'package:mooncake/usecases/usecases.dart'; 5 | 6 | import 'common.dart'; 7 | 8 | void main() { 9 | UsersRepository repository; 10 | BlockUserUseCase blockUserUseCase; 11 | 12 | setUp(() { 13 | repository = UsersRepositoryMock(); 14 | blockUserUseCase = BlockUserUseCase(usersRepository: repository); 15 | }); 16 | 17 | test('block performs correct calls', () async { 18 | when(repository.blockUser(any)).thenAnswer((_) => Future.value(null)); 19 | 20 | final user = User.fromAddress('address'); 21 | await blockUserUseCase.block(user); 22 | 23 | verify(repository.blockUser(user)).called(1); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /lib/entities/posts/reactions/reaction.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'reaction.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Reaction _$ReactionFromJson(Map json) { 10 | return Reaction( 11 | user: json['user'] == null 12 | ? null 13 | : User.fromJson(json['user'] as Map), 14 | value: json['value'] as String, 15 | code: json['short_code'] as String, 16 | ); 17 | } 18 | 19 | Map _$ReactionToJson(Reaction instance) => { 20 | 'user': instance.user?.toJson(), 21 | 'value': instance.value, 22 | 'short_code': instance.code, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/msg_add_post_reaction.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'msg_add_post_reaction.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | MsgAddPostReaction _$MsgAddPostReactionFromJson(Map json) { 10 | return MsgAddPostReaction( 11 | postId: json['post_id'] as String, 12 | reaction: json['reaction'] as String, 13 | user: json['user'] as String, 14 | ); 15 | } 16 | 17 | Map _$MsgAddPostReactionToJson(MsgAddPostReaction instance) => 18 | { 19 | 'post_id': instance.postId, 20 | 'reaction': instance.reaction, 21 | 'user': instance.user, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/msg_answer_poll.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'msg_answer_poll.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | MsgAnswerPoll _$MsgAnswerPollFromJson(Map json) { 10 | return MsgAnswerPoll( 11 | postId: json['post_id'] as String, 12 | answers: (json['answers'] as List)?.map((e) => e as String)?.toList(), 13 | user: json['answerer'] as String, 14 | ); 15 | } 16 | 17 | Map _$MsgAnswerPollToJson(MsgAnswerPoll instance) => 18 | { 19 | 'post_id': instance.postId, 20 | 'answers': instance.answers, 21 | 'answerer': instance.user, 22 | }; 23 | -------------------------------------------------------------------------------- /test/repositories/settings/settings_repository_impl_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:mooncake/repositories/repositories.dart'; 4 | import 'package:mooncake/repositories/settings/settings_repository_impl.dart'; 5 | import 'package:test/test.dart'; 6 | import 'package:mockito/mockito.dart'; 7 | 8 | class MockLocalSettingsSource extends Mock implements LocalSettingsSource {} 9 | 10 | void main() { 11 | final localSource = MockLocalSettingsSource(); 12 | final repository = SettingsRepositoryImpl(localSettingsSource: localSource); 13 | 14 | test('watch returns a stream', () { 15 | final key = 'event'; 16 | final controller = StreamController(); 17 | when(localSource.watch(any)).thenAnswer((_) => controller.stream); 18 | repository.watch(key); 19 | verify(localSource.watch(key)).called(1); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /test/ui/screens/security_set_password_screen/widgets/saving_password_popup_content/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | import '../../../../helper.dart'; 4 | import 'package:mooncake/ui/screens/security_set_password_screen/widgets/export.dart'; 5 | 6 | void main() { 7 | testWidgets('SavingPasswordPopupContent: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: SavingPasswordPopupContent(), 12 | ), 13 | ); 14 | 15 | await tester.pump(const Duration(seconds: 3)); 16 | expect(find.byType(LoadingIndicator), findsOneWidget); 17 | expect(find.text('savingPasswordTitle'), findsOneWidget); 18 | expect(find.text('savingPasswordBody'), findsOneWidget); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /test/usecases/settings/usecase_watch_setting_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:mockito/mockito.dart'; 4 | import 'package:mooncake/usecases/usecases.dart'; 5 | 6 | import 'common.dart'; 7 | 8 | void main() { 9 | SettingsRepository repository; 10 | WatchSettingUseCase watchSettingUseCase; 11 | 12 | setUp(() { 13 | repository = SettingsRepositoryMock(); 14 | watchSettingUseCase = WatchSettingUseCase(settingsRepository: repository); 15 | }); 16 | 17 | test('watch correctly returns a stream', () async { 18 | final controller = StreamController(); 19 | when(repository.watch(any)).thenAnswer((_) => controller.stream); 20 | final key = 'key'; 21 | await watchSettingUseCase.watch(key: key); 22 | verify(repository.watch(key)).called(1); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /lib/repositories/notifications/source_notifications_remote.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the remote source that should be used in order 4 | /// to get the notifications from the server. 5 | abstract class RemoteNotificationsSource { 6 | /// Returns a [Stream] that emits all the new notifications 7 | /// as soon as they are created. 8 | Stream get notificationsStream; 9 | 10 | /// Returns a [Stream] that emits only the notifications that are 11 | /// delivered to the device while the application is in the foreground. 12 | Stream get foregroundStream; 13 | 14 | /// Returns a [Stream] that emits only the notifications that are 15 | /// delivered to the device while the application in in the background. 16 | Stream get backgroundStream; 17 | } 18 | -------------------------------------------------------------------------------- /test/ui/screens/security_set_biometrics_screen/widgets/saving_biometrics_popup_content/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | import '../../../../helper.dart'; 4 | import 'package:mooncake/ui/screens/security_set_biometrics_screen/widgets/export.dart'; 5 | 6 | void main() { 7 | testWidgets('SavingBiometricsPopupContent: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: SavingBiometricsPopupContent(), 12 | ), 13 | ); 14 | await tester.pump(const Duration(seconds: 3)); 15 | expect(find.byType(LoadingIndicator), findsOneWidget); 16 | expect(find.text('savingBiometricsTitle'), findsOneWidget); 17 | expect(find.text('savingBiometricsBody'), findsOneWidget); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/blocs/post_input/post_input_event_images.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:mooncake/entities/entities.dart'; 4 | import './export.dart'; 5 | 6 | /// Event that is emitted upon the user adds an image to the post. 7 | class ImageAdded extends PostInputEvent { 8 | final File file; 9 | 10 | ImageAdded(this.file); 11 | 12 | @override 13 | List get props => [file]; 14 | 15 | @override 16 | String toString() => 'ImageAdded { file: $file }'; 17 | } 18 | 19 | /// Event that is emitted when the user wants to remove an image from a post. 20 | class ImageRemoved extends PostInputEvent { 21 | final PostMedia file; 22 | 23 | ImageRemoved(this.file); 24 | 25 | @override 26 | List get props => [file]; 27 | 28 | @override 29 | String toString() => 'ImageRemoved { file: $file }'; 30 | } 31 | -------------------------------------------------------------------------------- /lib/ui/screens/user_details_screen/widgets/account_app_bar/widgets/draft_button/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | class NewPostButton extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | margin: EdgeInsets.only( 9 | top: 7, 10 | left: 7, 11 | bottom: 7, 12 | right: 10, 13 | ), 14 | child: Material( 15 | shape: CircleBorder(), 16 | color: Colors.grey[700].withOpacity(0.5), // button color 17 | child: SizedBox( 18 | width: 35, 19 | height: 35, 20 | child: Icon( 21 | MooncakeIcons.draft, 22 | color: Colors.white, 23 | size: 20, 24 | ), 25 | ), 26 | ), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'king/new-feature' 6 | assignees: '' 7 | 8 | --- 9 | 15 | 16 | ## Feature description 17 | 18 | 19 | ## Implementation proposal 20 | 21 | 22 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v24/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_get_mnemonic.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily get the mnemonic that is currently stored inside the 5 | /// user device. 6 | /// Please note that this use case exposes a highly secret information, so 7 | /// it should not be used unless the user has been asked explicit consent first. 8 | class GetMnemonicUseCase { 9 | final UserRepository _userRepository; 10 | 11 | GetMnemonicUseCase({ 12 | @required UserRepository userRepository, 13 | }) : assert(userRepository != null), 14 | _userRepository = userRepository; 15 | 16 | /// Returns the mnemonic phrase associated to the account having the 17 | /// given [address]. 18 | Future> get(String address) { 19 | return _userRepository.getMnemonic(address); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/usecases/settings/usecase_get_setting_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | SettingsRepository repository; 9 | GetSettingUseCase getSettingUseCase; 10 | 11 | setUp(() { 12 | repository = SettingsRepositoryMock(); 13 | getSettingUseCase = GetSettingUseCase(settingsRepository: repository); 14 | }); 15 | 16 | test('get performs the correct calls', () async { 17 | final value = 1; 18 | when(repository.get(any)).thenAnswer((_) => Future.value(value)); 19 | 20 | final setting = 'setting'; 21 | final result = await getSettingUseCase.get(key: setting); 22 | expect(result, equals(value)); 23 | 24 | verify(repository.get(setting)).called(1); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /test_resources/chain/node_info_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "node_info": { 3 | "protocol_version": { 4 | "p2p": "7", 5 | "block": "10", 6 | "app": "0" 7 | }, 8 | "id": "8307c16191e249d6d3871ce764262d40d9cf249f", 9 | "listen_addr": "tcp://0.0.0.0:26656", 10 | "network": "morpheus-1001", 11 | "version": "0.32.7", 12 | "channels": "4020212223303800", 13 | "moniker": "validator-node", 14 | "other": { 15 | "tx_index": "on", 16 | "rpc_address": "tcp://0.0.0.0:26657" 17 | } 18 | }, 19 | "application_version": { 20 | "name": "Desmos", 21 | "server_name": "desmosd", 22 | "client_name": "desmoscli", 23 | "version": "0.2.0-5-g9b1c68f", 24 | "commit": "9b1c68fb3779857bd04bb713b497643f0c7f0641", 25 | "build_tags": "netgo ledger", 26 | "go": "go version go1.13.5 linux/amd64" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_save_account_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/entities/account/export.dart'; 4 | import 'package:mooncake/usecases/usecases.dart'; 5 | 6 | import 'common.dart'; 7 | 8 | void main() { 9 | UserRepository repository; 10 | SaveAccountUseCase saveAccountUseCase; 11 | 12 | setUp(() { 13 | repository = UserRepositoryMock(); 14 | saveAccountUseCase = SaveAccountUseCase(userRepository: repository); 15 | }); 16 | 17 | test('save performs correct calls', () async { 18 | when(repository.saveAccount(any)).thenAnswer((_) => Future.value(null)); 19 | 20 | final account = MooncakeAccount.local('address'); 21 | await saveAccountUseCase.save(account); 22 | 23 | verify(repository.saveAccount(account)).called(1); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /lib/ui/screens/user_account_edit_screen/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import 'blocs/export.dart'; 5 | import 'widgets/export.dart'; 6 | 7 | /// Represents the screen that is used when editing the information 8 | /// about the current user profile. 9 | class EditAccountScreen extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text(PostsLocalizations.of(context) 15 | .translate(Messages.editAccountScreenTitle)), 16 | centerTitle: true, 17 | ), 18 | body: BlocProvider( 19 | create: (context) => EditAccountBloc.create(context), 20 | child: AccountEditorBody(), 21 | ), 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_delete_post.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | 5 | /// Allows to delete a locally stored post. 6 | class DeletePostUseCase { 7 | static const canDeleteStatus = [ 8 | PostStatusValue.STORED_LOCALLY, 9 | PostStatusValue.ERRORED 10 | ]; 11 | 12 | final PostsRepository _postsRepository; 13 | 14 | DeletePostUseCase({ 15 | @required PostsRepository postsRepository, 16 | }) : assert(postsRepository != null), 17 | _postsRepository = postsRepository; 18 | 19 | /// Deletes the locally stored post if it hasn't been posted. 20 | Future delete(Post post) async { 21 | if (canDeleteStatus.contains(post.status.value)) { 22 | return _postsRepository.deletePost(post); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_save_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to save the given object as the current user account. 6 | class SaveAccountUseCase { 7 | final UserRepository _userRepository; 8 | 9 | SaveAccountUseCase({ 10 | @required UserRepository userRepository, 11 | }) : assert(userRepository != null), 12 | _userRepository = userRepository; 13 | 14 | /// Saves the given [account] inside the local storage. 15 | /// If [syncRemote] is true, the account will also saved into the remote 16 | /// source as well. 17 | Future save( 18 | MooncakeAccount account, { 19 | bool syncRemote = false, 20 | }) { 21 | return _userRepository.saveAccount(account, syncRemote: syncRemote); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/repositories/notifications/source_notifications_local.dart: -------------------------------------------------------------------------------- 1 | import 'package:mooncake/entities/entities.dart'; 2 | 3 | /// Represents the source that should be used to fetch the notifications 4 | /// from the device. 5 | abstract class LocalNotificationsSource { 6 | /// Returns a [Stream] that emits all the new notifications 7 | /// as soon as they are created. 8 | Stream get liveNotificationsStream; 9 | 10 | /// Returns a [Stream] that emits all the locally stored notifications 11 | /// each time a new one is stored. 12 | Stream get storedNotificationsStream; 13 | 14 | /// Returns the list of all the notifications related to the user. 15 | Future> getNotifications(); 16 | 17 | /// Saves the given [notification] inside the local source. 18 | Future saveNotification(NotificationData notification); 19 | } 20 | -------------------------------------------------------------------------------- /lib/sources/chain/models/msgs/msg_remove_post_reaction.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'msg_remove_post_reaction.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | MsgRemovePostReaction _$MsgRemovePostReactionFromJson( 10 | Map json) { 11 | return MsgRemovePostReaction( 12 | postId: json['post_id'] as String, 13 | reaction: json['reaction'] as String, 14 | user: json['user'] as String, 15 | ); 16 | } 17 | 18 | Map _$MsgRemovePostReactionToJson( 19 | MsgRemovePostReaction instance) => 20 | { 21 | 'post_id': instance.postId, 22 | 'reaction': instance.reaction, 23 | 'user': instance.user, 24 | }; 25 | -------------------------------------------------------------------------------- /test/ui/widgets/buttons/secondary_button/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | import '../../../helper.dart'; 5 | 6 | void main() { 7 | testWidgets('SecondaryButton: Displays correctly', 8 | (WidgetTester tester) async { 9 | await tester.pumpWidget( 10 | makeTestableWidget( 11 | child: SecondaryLightButton( 12 | child: Text('pineapples'), 13 | onPressed: () {}, 14 | ), 15 | ), 16 | ); 17 | await tester.pumpAndSettle(); 18 | 19 | expect(find.byType(FlatButton), findsOneWidget); 20 | expect(find.byType(Text), findsOneWidget); 21 | expect(find.text('pineapples'), findsOneWidget); 22 | expect(tester.widget(find.byType(FlatButton)).color, 23 | Color(0xFF6D4DDB)); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_get_mnemonic_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | UserRepository repository; 9 | GetMnemonicUseCase getMnemonicUseCase; 10 | 11 | setUp(() { 12 | repository = UserRepositoryMock(); 13 | getMnemonicUseCase = GetMnemonicUseCase(userRepository: repository); 14 | }); 15 | 16 | test('get performs correct call', () async { 17 | final mnemonic = ['first', 'second', 'third']; 18 | when(repository.getMnemonic('address')) 19 | .thenAnswer((_) => Future.value(mnemonic)); 20 | 21 | final result = await getMnemonicUseCase.get('address'); 22 | expect(result, equals(mnemonic)); 23 | 24 | verify(repository.getMnemonic('address')).called(1); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_check_login_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | import 'package:mooncake/usecases/usecases.dart'; 5 | 6 | import 'common.dart'; 7 | 8 | void main() { 9 | UserRepository repository; 10 | CheckLoginUseCase checkLoginUseCase; 11 | 12 | setUp(() { 13 | repository = UserRepositoryMock(); 14 | checkLoginUseCase = CheckLoginUseCase(userRepository: repository); 15 | }); 16 | 17 | test('isLoggedIn returns true when the account exists', () async { 18 | final account = MooncakeAccount.local('address'); 19 | when(repository.getActiveAccount()) 20 | .thenAnswer((_) => Future.value(account)); 21 | 22 | expect(await checkLoginUseCase.isLoggedIn(), isTrue); 23 | verify(repository.getActiveAccount()).called(1); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_get_authentication_method.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to get the currently set local authentication method that the 6 | /// user has set. 7 | class GetAuthenticationMethodUseCase { 8 | final UserRepository _userRepository; 9 | 10 | GetAuthenticationMethodUseCase({ 11 | @required UserRepository userRepository, 12 | }) : assert(userRepository != null), 13 | _userRepository = userRepository; 14 | 15 | /// Returns the currently set local authentication method the user has 16 | /// previously set for the account having the given [address]. 17 | /// If no method is set, `null` is returned instead. 18 | Future get(String address) { 19 | return _userRepository.getAuthenticationMethod(address); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_get_accounts_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | import 'package:mockito/mockito.dart'; 5 | import 'package:mooncake/entities/account/export.dart'; 6 | import 'package:mooncake/usecases/usecases.dart'; 7 | 8 | import 'common.dart'; 9 | 10 | void main() { 11 | UserRepository repository; 12 | GetAccountsUseCase usecase; 13 | 14 | setUp(() { 15 | repository = UserRepositoryMock(); 16 | usecase = GetAccountsUseCase(userRepository: repository); 17 | }); 18 | 19 | test('all performs correct calls', () async { 20 | final account = MooncakeAccount.local('address'); 21 | when(repository.getAccounts()).thenAnswer((_) => Future.value([account])); 22 | 23 | final result = await usecase.all(); 24 | expect(result, equals([account])); 25 | 26 | verify(repository.getAccounts()).called(1); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /test/ui/screens/user_wallet_screen/widgets/wallet_header/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import '../../../../helper.dart'; 4 | import 'package:mooncake/ui/screens/user_wallet_screen/widgets/export.dart'; 5 | import 'package:mooncake/entities/entities.dart'; 6 | import 'package:mooncake/ui/ui.dart'; 7 | 8 | void main() { 9 | testWidgets('WalletHeader: Displays correctly', (WidgetTester tester) async { 10 | await tester.pumpWidget( 11 | makeTestableWidget( 12 | child: WalletHeader( 13 | coin: StdCoin(amount: '10000', denom: 'udaric'), 14 | ), 15 | ), 16 | ); 17 | 18 | await tester.pumpAndSettle(); 19 | 20 | expect(find.byType(Column), findsOneWidget); 21 | expect(find.byType(Text), findsNWidgets(2)); 22 | expect(find.byIcon(MooncakeIcons.transactions), findsOneWidget); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/ui/screens/home_screen/widgets/posts_list/widgets/posts_list_syncing_indicator/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/localization/export.dart'; 3 | 4 | /// Used to show the user the fact that activities are being synced. 5 | class PostsListSyncingIndicator extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Column( 9 | mainAxisSize: MainAxisSize.min, 10 | children: [ 11 | SizedBox(height: 3, child: LinearProgressIndicator()), 12 | const SizedBox(height: 4), 13 | Text( 14 | PostsLocalizations.of(context).translate(Messages.syncingActivities), 15 | style: Theme.of(context).textTheme.caption.copyWith( 16 | color: Theme.of(context).accentColor, 17 | ), 18 | ), 19 | const SizedBox(height: 10), 20 | ], 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/ui/widgets/mnemonic_visualizer/widgets/export_mnemonic_button/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:mooncake/ui/ui.dart'; 4 | 5 | class ExportMnemonicButton extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | void _openExportPopup(BuildContext context) { 9 | BlocProvider.of(context).add(ShowExportPopup()); 10 | } 11 | 12 | return Expanded( 13 | child: Align( 14 | alignment: Alignment.topCenter, 15 | child: Container( 16 | margin: EdgeInsets.only(bottom: 15), 17 | child: PrimaryButton( 18 | child: Text(PostsLocalizations.of(context) 19 | .translate(Messages.exportMnemonic)), 20 | onPressed: () => _openExportPopup(context), 21 | ), 22 | ), 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.docs/.vuepress/public/assets/pwa/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /lib/ui/widgets/mnemonic_visualizer/widgets/mnemonic_item/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Allows to display a single mnemonic word inside the list of words. 4 | class MnemonicItem extends StatelessWidget { 5 | final int index; 6 | final String word; 7 | 8 | const MnemonicItem({ 9 | Key key, 10 | @required this.index, 11 | @required this.word, 12 | }) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | padding: EdgeInsets.all(8), 18 | decoration: BoxDecoration( 19 | border: Border.all(color: Theme.of(context).accentColor), 20 | borderRadius: BorderRadius.circular(8), 21 | ), 22 | child: Row( 23 | children: [ 24 | Text(index.toString()), 25 | Expanded(child: Text(word, textAlign: TextAlign.center)), 26 | ], 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/usecases/posts/usecase_hide_post_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import '../../mocks/mocks.dart'; 6 | import 'common.dart'; 7 | 8 | void main() { 9 | PostsRepository repository; 10 | HidePostUseCase hidePostUseCase; 11 | 12 | setUp(() { 13 | repository = PostsRepositoryMock(); 14 | hidePostUseCase = HidePostUseCase(postsRepository: repository); 15 | }); 16 | 17 | test('hide performs correct calls', () async { 18 | when(repository.savePost(any)).thenAnswer((_) => Future.value(null)); 19 | 20 | final post = testPost.copyWith(hidden: false); 21 | 22 | final result = await hidePostUseCase.hide(post); 23 | final hiddenPost = post.copyWith(hidden: true); 24 | expect(result, equals(hiddenPost)); 25 | 26 | verify(repository.savePost(hiddenPost)).called(1); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'king/bug' 6 | assignees: 'RiccardoM' 7 | 8 | --- 9 | 14 | 15 | ## Generic information 16 | - OS name and version: 17 | - Application build code: 18 | - Network type (mobile/Wi-Fi): 19 | 20 | ## Bug description 21 | 22 | 23 | ## Steps to reproduce 24 | 25 | 26 | ## Expected behavior 27 | 28 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_get_active_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | 5 | /// Allows to easily get the information about the currently active account. 6 | class GetActiveAccountUseCase { 7 | final UserRepository _userRepository; 8 | 9 | GetActiveAccountUseCase({ 10 | @required UserRepository userRepository, 11 | }) : assert(userRepository != null), 12 | _userRepository = userRepository; 13 | 14 | /// Returns the currently active account. 15 | Future single() { 16 | return _userRepository.getActiveAccount(); 17 | } 18 | 19 | /// Returns the [Stream] that emits all the [MooncakeAccount] objects 20 | /// as soon as they are marked as being the currently active account. 21 | Stream stream() { 22 | return _userRepository.activeAccountStream; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/usecases/biometrics/usecase_get_available_biometrics.dart: -------------------------------------------------------------------------------- 1 | import 'package:local_auth/local_auth.dart'; 2 | import 'package:meta/meta.dart'; 3 | 4 | /// Allows to easily get the list of biometric authentication types 5 | /// that the current device supports. 6 | class GetAvailableBiometricsUseCase { 7 | final LocalAuthentication _localAuthentication; 8 | 9 | GetAvailableBiometricsUseCase({ 10 | @required LocalAuthentication localAuthentication, 11 | }) : assert(localAuthentication != null), 12 | _localAuthentication = localAuthentication; 13 | 14 | /// Returns a list of enrolled biometrics 15 | /// 16 | /// Returns a [Future] List with the following possibilities: 17 | /// - BiometricType.face 18 | /// - BiometricType.fingerprint 19 | /// - BiometricType.iris (not yet implemented) 20 | Future> get() { 21 | return _localAuthentication.getAvailableBiometrics(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_set_account_active_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/entities/account/export.dart'; 4 | import 'package:mooncake/usecases/usecases.dart'; 5 | 6 | import 'common.dart'; 7 | 8 | void main() { 9 | UserRepository repository; 10 | SetAccountActiveUsecase setAccountActiveUsecase; 11 | 12 | setUp(() { 13 | repository = UserRepositoryMock(); 14 | setAccountActiveUsecase = 15 | SetAccountActiveUsecase(userRepository: repository); 16 | }); 17 | 18 | test('setActive performs correct calls', () async { 19 | when(repository.setActiveAccount(any)) 20 | .thenAnswer((_) => Future.value(null)); 21 | 22 | final account = MooncakeAccount.local('address'); 23 | await setAccountActiveUsecase.setActive(account); 24 | 25 | verify(repository.setActiveAccount(account)).called(1); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_get_home_posts.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to read all the posts that should be seen inside the main page. 6 | class GetHomePostsUseCase { 7 | final PostsRepository _postsRepository; 8 | 9 | GetHomePostsUseCase({@required PostsRepository postsRepository}) 10 | : assert(postsRepository != null), 11 | _postsRepository = postsRepository; 12 | 13 | /// Returns the posts that should be seen inside the main screen. 14 | Stream> stream(int limit) { 15 | return _postsRepository.getHomePostsStream(limit); 16 | } 17 | 18 | /// Refreshes the home posts by downloading them from the remote 19 | /// repository. 20 | Future> get({int start = 0, int limit = 50}) { 21 | return _postsRepository.getHomePosts(start: start, limit: limit); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/ui/widgets/sync_snackbar/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | /// Represents the snackbar that is shown during the synchronization 5 | /// of new posts into the chain 6 | class SyncSnackBar extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | padding: EdgeInsets.all(16), 11 | color: Theme.of(context).colorScheme.primary, 12 | child: Row( 13 | children: [ 14 | Icon( 15 | FontAwesomeIcons.cloudUploadAlt, 16 | size: 16, 17 | color: Colors.white, 18 | ), 19 | const SizedBox(width: 16), 20 | Text( 21 | PostsLocalizations.of(context) 22 | .translate(Messages.syncingActivities), 23 | style: TextStyle(color: Colors.white), 24 | ), 25 | ], 26 | ), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/usecases/account/usecase_logout.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | /// Allows to easily log out the user from the application. 5 | class LogoutUseCase { 6 | final UserRepository _userRepository; 7 | 8 | LogoutUseCase({@required UserRepository userRepository}) 9 | : assert(userRepository != null), 10 | _userRepository = userRepository; 11 | 12 | /// Performs the logout of the account having the given [address]. 13 | /// After logging out the account, all of its data is going to be deleted 14 | /// from the local storage. 15 | Future logout(String address) { 16 | return _userRepository.logout(address); 17 | } 18 | 19 | /// Log outs all the accounts from the application. 20 | /// This means deleting all the data of all the accounts from 21 | /// the local storage. 22 | Future logoutAll() { 23 | return _userRepository.deleteData(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tool/generator.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'generator.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Selection _$SelectionFromJson(Map json) { 10 | return Selection( 11 | (json['icons'] as List) 12 | ?.map( 13 | (e) => e == null ? null : Icon.fromJson(e as Map)) 14 | ?.toList(), 15 | ); 16 | } 17 | 18 | Icon _$IconFromJson(Map json) { 19 | return Icon( 20 | json['properties'] == null 21 | ? null 22 | : Properties.fromJson(json['properties'] as Map), 23 | ); 24 | } 25 | 26 | Properties _$PropertiesFromJson(Map json) { 27 | return Properties( 28 | json['name'] as String, 29 | json['code'] as int, 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /lib/repositories/settings/settings_repository_impl.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:mooncake/repositories/settings/source_settings_local.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Implementation of [SettingsRepository] 6 | class SettingsRepositoryImpl extends SettingsRepository { 7 | final LocalSettingsSource _localSettingsSource; 8 | 9 | SettingsRepositoryImpl({ 10 | @required LocalSettingsSource localSettingsSource, 11 | }) : assert(localSettingsSource != null), 12 | _localSettingsSource = localSettingsSource; 13 | 14 | @override 15 | Future save(String key, value) async { 16 | return _localSettingsSource.save(key, value); 17 | } 18 | 19 | @override 20 | Future get(String key) async { 21 | return _localSettingsSource.get(key); 22 | } 23 | 24 | @override 25 | Stream watch(String key) { 26 | return _localSettingsSource.watch(key); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/ui/screens/user_details_screen/widgets/account_app_bar/widgets/menu_button/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | class MenuButton extends StatelessWidget { 5 | // final Icon icon; 6 | // final Function onTap; 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | margin: EdgeInsets.all(10), 11 | child: Material( 12 | shape: CircleBorder(), 13 | color: Colors.grey[700].withOpacity(0.5), // button color 14 | child: InkWell( 15 | child: SizedBox( 16 | width: 50, 17 | height: 50, 18 | child: Icon( 19 | MooncakeIcons.menu, 20 | color: Colors.white, 21 | size: 15, 22 | )), 23 | onTap: () { 24 | Scaffold.of(context).openDrawer(); 25 | }, 26 | ), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/usecases/posts/usecase_update_post.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to sync all the posts that have been created offline as well as 6 | /// all the likes and unlikes that have been set to posts. 7 | class UpdatePostUseCase { 8 | static const canUpdateStatus = [ 9 | PostStatusValue.STORED_LOCALLY, 10 | PostStatusValue.ERRORED 11 | ]; 12 | 13 | final PostsRepository _postsRepository; 14 | 15 | UpdatePostUseCase({ 16 | @required PostsRepository postsRepository, 17 | }) : assert(postsRepository != null), 18 | _postsRepository = postsRepository; 19 | 20 | /// Updates post that has not been posted to the chain 21 | Future update(Post post) async { 22 | if (canUpdateStatus.contains(post.status.value)) { 23 | return _postsRepository.savePost(post); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_encrypt_mnemonic_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mooncake/usecases/usecases.dart'; 3 | 4 | void main() { 5 | final encryptMnemonicUseCase = EncryptMnemonicUseCase(); 6 | 7 | test('encryption never returns the same value twice', () async { 8 | final password = 'password'; 9 | final mnemonic = [ 10 | 'first', 11 | 'second', 12 | 'third', 13 | 'fourth', 14 | 'fifth', 15 | 'sixth', 16 | 'seventh', 17 | 'eight', 18 | 'ninth', 19 | 'tenth', 20 | ]; 21 | 22 | final encrypted = []; 23 | for (var i = 0; i < 100; i++) { 24 | encrypted.add(await encryptMnemonicUseCase.encrypt(mnemonic, password)); 25 | } 26 | expect(encrypted, isNotEmpty); 27 | 28 | // Remove duplicates and check length 29 | final encryptedSet = encrypted.toSet(); 30 | expect(encrypted.length, equals(encryptedSet.length)); 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /lib/ui/screens/post_create_screen/widgets/create_post_content/widgets/post_poll_creator/utils/common.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Returns the decoration that is used on all poll input fields. 4 | Decoration getInputOutline(BuildContext context) { 5 | return BoxDecoration( 6 | border: Border.all( 7 | width: 0.5, 8 | color: Theme.of(context).colorScheme.onError, 9 | ), 10 | borderRadius: BorderRadius.all(Radius.circular(4)), 11 | ); 12 | } 13 | 14 | InputDecoration getInputDecoration(BuildContext context, String hint) { 15 | return InputDecoration( 16 | hintText: hint, 17 | hintStyle: TextStyle( 18 | color: Theme.of(context).colorScheme.onError, 19 | ), 20 | border: InputBorder.none, 21 | focusedErrorBorder: InputBorder.none, 22 | focusedBorder: InputBorder.none, 23 | errorBorder: InputBorder.none, 24 | enabledBorder: InputBorder.none, 25 | disabledBorder: InputBorder.none, 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /test/ui/widgets/post_content/widgets/link_preview/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | import '../../../../helper.dart'; 5 | import 'package:mooncake/ui/widgets/post_content/widgets/export.dart'; 6 | 7 | void main() { 8 | testWidgets('PostReactionAction: Displays export correctly', 9 | (WidgetTester tester) async { 10 | var linkPreview = RichLinkPreview( 11 | title: 'null', 12 | description: 'null', 13 | image: '', 14 | appleIcon: 'null', 15 | favIcon: 'null', 16 | url: ''); 17 | 18 | await tester.pumpWidget(makeTestableWidget( 19 | child: LinkPreview( 20 | preview: linkPreview, 21 | ), 22 | )); 23 | 24 | await tester.pumpAndSettle(); 25 | 26 | expect(find.byType(GestureDetector), findsOneWidget); 27 | expect(find.text('😢'), findsNothing); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_logout_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import 'common.dart'; 6 | 7 | void main() { 8 | UserRepository repository; 9 | LogoutUseCase logoutUseCase; 10 | 11 | setUp(() { 12 | repository = UserRepositoryMock(); 13 | logoutUseCase = LogoutUseCase(userRepository: repository); 14 | }); 15 | 16 | test('logout performs correct calls', () async { 17 | when(repository.logout('address')).thenAnswer((_) => Future.value(null)); 18 | 19 | await logoutUseCase.logout('address'); 20 | 21 | verify(repository.logout('address')).called(1); 22 | }); 23 | 24 | test('logoutAll performs correct calls', () async { 25 | when(repository.deleteData()).thenAnswer((_) => Future.value(null)); 26 | 27 | await logoutUseCase.logoutAll(); 28 | 29 | verify(repository.deleteData()).called(1); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/usecases/account/usecase_save_wallet_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:mockito/mockito.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | import '../../mocks/mocks.dart'; 6 | import 'common.dart'; 7 | 8 | void main() { 9 | UserRepository repository; 10 | SaveWalletUseCase saveWalletUseCase; 11 | 12 | setUp(() { 13 | repository = UserRepositoryMock(); 14 | saveWalletUseCase = SaveWalletUseCase(userRepository: repository); 15 | }); 16 | 17 | group('saveWallet works properly', () { 18 | test('when no funding is necessary', () async { 19 | final wallet = MockWallet(); 20 | final mnemonic = 'mnemonic'; 21 | when(repository.saveWallet(mnemonic)) 22 | .thenAnswer((_) => Future.value(wallet)); 23 | 24 | await saveWalletUseCase.saveWallet(mnemonic); 25 | 26 | verifyInOrder([ 27 | repository.saveWallet(mnemonic), 28 | ]); 29 | }); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /lib/entities/user/user.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'user.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | User _$UserFromJson(Map json) { 10 | return User( 11 | address: json['address'] as String, 12 | dtag: json['dtag'] as String, 13 | moniker: json['moniker'] as String, 14 | bio: json['bio'] as String, 15 | profilePicUri: json['profile_pic'] as String, 16 | coverPicUri: json['cover_pic'] as String, 17 | ); 18 | } 19 | 20 | Map _$UserToJson(User instance) => { 21 | 'address': instance.address, 22 | 'dtag': instance.dtag, 23 | 'moniker': instance.moniker, 24 | 'bio': instance.bio, 25 | 'profile_pic': instance.profilePicUri, 26 | 'cover_pic': instance.coverPicUri, 27 | }; 28 | -------------------------------------------------------------------------------- /lib/ui/screens/security_set_biometrics_screen/widgets/saving_biometrics_popup_content/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mooncake/ui/ui.dart'; 3 | 4 | /// Represents the content of the 5 | class SavingBiometricsPopupContent extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Column( 9 | children: [ 10 | Text( 11 | PostsLocalizations.of(context) 12 | .translate(Messages.savingBiometricsTitle), 13 | style: Theme.of(context).textTheme.headline6, 14 | ), 15 | const SizedBox(height: 10), 16 | Text(PostsLocalizations.of(context) 17 | .translate(Messages.savingBiometricsBody)), 18 | const SizedBox(height: 20), 19 | Row( 20 | mainAxisSize: MainAxisSize.min, 21 | children: [ 22 | LoadingIndicator(), 23 | ], 24 | ), 25 | ], 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/usecases/notifications/usecase_get_notifications.dart: -------------------------------------------------------------------------------- 1 | import 'package:meta/meta.dart'; 2 | import 'package:mooncake/entities/entities.dart'; 3 | import 'package:mooncake/usecases/usecases.dart'; 4 | 5 | /// Allows to retrieve the currently stored notifications as well as all 6 | /// the notifications that are created during time. 7 | class GetNotificationsUseCase { 8 | final NotificationsRepository _repository; 9 | 10 | GetNotificationsUseCase({ 11 | @required NotificationsRepository repository, 12 | }) : assert(repository != null), 13 | _repository = repository; 14 | 15 | /// Returns the list of notifications that are currently available. 16 | Future> single() { 17 | return _repository.getNotifications(); 18 | } 19 | 20 | /// Returns a [Stream] that emits all the new notifications 21 | /// that are created during time. 22 | Stream stream() { 23 | return _repository.liveNotificationsStream; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/ui/widgets/post_content/widgets/post_poll_content/widgets/post_poll_option_item/index_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mooncake/entities/entities.dart'; 4 | import '../../../../../../helper.dart'; 5 | import '../../../../../../../mocks/posts.dart'; 6 | import 'package:mooncake/ui/widgets/post_content/widgets/post_poll_content/widgets/export.dart'; 7 | 8 | void main() { 9 | testWidgets('PostPollOptionItem: Displays export correctly', 10 | (WidgetTester tester) async { 11 | var option = PollOption(id: 1, text: 'apples'); 12 | 13 | await tester.pumpWidget(makeTestableWidget( 14 | child: PostPollOptionItem( 15 | post: testPost, 16 | option: option, 17 | index: 1, 18 | ), 19 | )); 20 | 21 | await tester.pumpAndSettle(); 22 | 23 | expect(find.byType(FlatButton), findsOneWidget); 24 | expect(find.text('apples'), findsOneWidget); 25 | }); 26 | } 27 | --------------------------------------------------------------------------------