From ca637c5114e269a4e9494d0bef855b06fcfb79a9 Mon Sep 17 00:00:00 2001 From: Xinto Date: Sat, 31 Oct 2020 23:45:39 +0400 Subject: [PATCH] manager redesign --- app/build.gradle | 45 ++--- app/src/main/AndroidManifest.xml | 21 +- .../vanced/manager/adapter/AppListAdapter.kt | 84 ++++++++ .../manager/adapter/ChangelogAdapter.kt | 38 ---- .../vanced/manager/adapter/GetNotifAdapter.kt | 60 ++++++ .../com/vanced/manager/adapter/LinkAdapter.kt | 77 ++++++++ .../manager/adapter/SelectAppsAdapter.kt | 56 ++++++ .../vanced/manager/adapter/SponsorAdapter.kt | 57 ++++++ .../vanced/manager/adapter/VancedPrefArray.kt | 35 ++++ .../vanced/manager/adapter/VariantAdapter.kt | 88 --------- .../main/java/com/vanced/manager/core/App.kt | 27 ++- .../core/downloader/MicrogDownloader.kt | 36 ++-- .../core/downloader/MusicDownloader.kt | 40 ++-- .../core/downloader/VancedDownloader.kt | 69 ++++--- .../core/installer/AppInstallerService.kt | 10 +- .../core/installer/SplitInstallerService.kt | 49 ----- .../com/vanced/manager/model/AppListModel.kt | 12 ++ .../com/vanced/manager/model/DataModel.kt | 19 +- .../com/vanced/manager/model/LinkModel.kt | 8 + .../com/vanced/manager/model/NotifModel.kt | 8 + .../com/vanced/manager/model/ProgressModel.kt | 12 +- .../vanced/manager/model/SelectAppModel.kt | 8 + .../com/vanced/manager/model/SponsorModel.kt | 9 + .../vanced/manager/model/VancedPrefModel.kt | 6 + .../com/vanced/manager/ui/MainActivity.kt | 23 ++- .../com/vanced/manager/ui/WelcomeActivity.kt | 24 +++ .../vanced/manager/ui/core/EmptyPreference.kt | 50 +++++ .../vanced/manager/ui/core/ItemDecoration.kt | 38 ++++ .../manager/ui/core/PreferenceCategory.kt | 33 ++++ .../manager/ui/core/PreferenceSwitch.kt | 112 +++++++++++ .../manager/ui/core/SplashScreenActivity.kt | 12 +- .../manager/ui/dialogs/AppDownloadDialog.kt | 88 +++++++++ .../manager/ui/dialogs/AppInfoDialog.kt | 38 ++++ .../manager/ui/dialogs/DialogContainer.kt | 20 +- .../InstallationFilesDetectedDialog.kt | 51 +++++ .../ui/dialogs/ManagerAccentColorDialog.kt | 45 +++++ .../ui/dialogs/ManagerLanguageDialog.kt | 64 ++++++ .../manager/ui/dialogs/ManagerThemeDialog.kt | 44 +++++ .../manager/ui/dialogs/ManagerUpdateDialog.kt | 89 +++++++++ .../ui/dialogs/ManagerVariantDialog.kt | 44 +++++ .../manager/ui/dialogs/SelectAppsDialog.kt | 50 +++++ .../URLChangeDialog.kt} | 8 +- .../VancedLanguageSelectionDialog.kt} | 38 ++-- .../ui/dialogs/VancedPreferencesDialog.kt | 82 ++++++++ .../ChosenPreferenceDialogFragment.kt | 59 ------ .../ui/fragments/DevSettingsFragment.kt | 18 +- .../manager/ui/fragments/GrantRootFragment.kt | 53 +++++ .../manager/ui/fragments/HomeFragment.kt | 166 ++++++++++------ .../ui/fragments/SelectAppsFragment.kt | 53 +++++ .../manager/ui/fragments/SettingsFragment.kt | 179 ++++++++--------- .../ui/fragments/UpdateCheckFragment.kt | 66 ------- .../fragments/VancedThemeSelectionFragment.kt | 40 ---- .../manager/ui/fragments/WelcomeFragment.kt | 32 +++ .../manager/ui/viewmodels/HomeViewModel.kt | 135 ++++++------- .../ui/viewmodels/HomeViewModelFactory.kt | 4 +- .../ui/viewmodels/SettingsViewModel.kt | 10 + .../ui/viewmodels/SettingsViewModelFactory.kt | 13 ++ .../java/com/vanced/manager/utils/AppUtils.kt | 22 ++- .../vanced/manager/utils/DownloadHelper.kt | 81 ++++---- .../com/vanced/manager/utils/Extensions.kt | 18 ++ .../manager/utils/LanguageContextWrapper.kt | 3 +- .../vanced/manager/utils/LanguageHelper.kt | 52 ++++- .../com/vanced/manager/utils/PackageHelper.kt | 115 +++++++++-- .../com/vanced/manager/utils/ThemeHelper.kt | 8 +- app/src/main/res/anim/tablayout_enter.xml | 9 - app/src/main/res/anim/tablayout_exit.xml | 10 - app/src/main/res/animator/welcome_exit.xml | 19 ++ .../main/res/animator/welcome_pop_enter.xml | 19 ++ app/src/main/res/drawable/arrow_down.xml | 9 - .../main/res/drawable/category_background.xml | 14 ++ app/src/main/res/drawable/discord.xml | 8 - app/src/main/res/drawable/ic_adguard.xml | 16 ++ ...ngs.xml => ic_app_settings_black_24dp.xml} | 6 +- .../res/drawable/ic_baseline_clear_24.xml | 13 -- ...4.xml => ic_baseline_navigate_next_36.xml} | 8 +- .../drawable/ic_baseline_navigate_next_48.xml | 10 + .../res/drawable/ic_baseline_pause_24.xml | 13 -- app/src/main/res/drawable/ic_brave.xml | 14 ++ app/src/main/res/drawable/ic_brave_logo.xml | 9 - .../drawable/ic_cloud_upload_black_24dp.xml | 9 - .../res/drawable/ic_delete_black_24dp.xml | 4 +- app/src/main/res/drawable/ic_discord.xml | 14 ++ .../main/res/drawable/ic_done_black_24dp.xml | 9 - app/src/main/res/drawable/ic_github.xml | 12 ++ app/src/main/res/drawable/ic_instagram.xml | 15 ++ app/src/main/res/drawable/ic_launch_text.xml | 24 +++ app/src/main/res/drawable/ic_magisk.xml | 4 + app/src/main/res/drawable/ic_microg.xml | 4 +- app/src/main/res/drawable/ic_music.xml | 6 +- app/src/main/res/drawable/ic_pause_resume.xml | 12 -- app/src/main/res/drawable/ic_reddit.xml | 17 +- .../ic_secret_settings_black_24dp.xml | 10 - app/src/main/res/drawable/ic_telegram.xml | 11 ++ app/src/main/res/drawable/ic_twitter.xml | 11 ++ app/src/main/res/drawable/ic_vanced.xml | 4 +- app/src/main/res/drawable/ic_vanced_nobg.xml | 6 - app/src/main/res/drawable/ic_website.xml | 16 ++ app/src/main/res/drawable/ic_youtube.xml | 16 ++ app/src/main/res/drawable/telegram.xml | 8 - app/src/main/res/drawable/twitter.xml | 8 - app/src/main/res/font/roboto_medium.xml | 7 + app/src/main/res/layout/activity_main.xml | 32 +-- app/src/main/res/layout/activity_welcome.xml | 22 +++ .../main/res/layout/dialog_app_download.xml | 94 +++++++++ app/src/main/res/layout/dialog_app_info.xml | 61 ++++++ app/src/main/res/layout/dialog_custom_url.xml | 52 +++++ .../dialog_installation_files_detected.xml | 39 ++++ .../dialog_installation_preferences.xml | 75 +++++++ .../layout/dialog_manager_accent_color.xml | 73 +++++++ .../res/layout/dialog_manager_language.xml | 38 ++++ .../main/res/layout/dialog_manager_theme.xml | 59 ++++++ .../main/res/layout/dialog_manager_update.xml | 73 +++++++ .../res/layout/dialog_manager_variant.xml | 54 +++++ .../main/res/layout/dialog_select_apps.xml | 35 ++++ app/src/main/res/layout/fragment_about.xml | 6 +- .../layout/fragment_chosen_preferences.xml | 69 ------- .../main/res/layout/fragment_custom_url.xml | 66 ------- .../main/res/layout/fragment_grant_root.xml | 62 ++++++ app/src/main/res/layout/fragment_home.xml | 88 +++++++-- app/src/main/res/layout/fragment_main.xml | 29 --- .../main/res/layout/fragment_select_apps.xml | 43 ++++ app/src/main/res/layout/fragment_settings.xml | 101 ++++++++++ .../main/res/layout/fragment_update_check.xml | 82 -------- .../fragment_vanced_language_selection.xml | 96 +++------ .../fragment_vanced_theme_selection.xml | 15 +- app/src/main/res/layout/fragment_welcome.xml | 36 ++++ .../res/layout/include_about_app_devs.xml | 31 +-- .../main/res/layout/include_about_header.xml | 14 +- .../main/res/layout/include_about_sources.xml | 86 ++++---- .../res/layout/include_about_vanced_devs.xml | 29 +-- .../main/res/layout/include_changelogs.xml | 72 ------- app/src/main/res/layout/include_microg.xml | 187 ------------------ app/src/main/res/layout/include_music.xml | 176 ----------------- .../main/res/layout/include_useful_links.xml | 43 ---- app/src/main/res/layout/include_vanced.xml | 181 ----------------- .../main/res/layout/include_vanced_medias.xml | 110 ----------- app/src/main/res/layout/view_app.xml | 152 ++++++++++++++ app/src/main/res/layout/view_app_checkbox.xml | 57 ++++++ app/src/main/res/layout/view_changelog.xml | 12 -- app/src/main/res/layout/view_home.xml | 95 --------- .../res/layout/view_notification_setting.xml | 21 ++ app/src/main/res/layout/view_preference.xml | 24 +++ .../res/layout/view_preference_category.xml | 9 + .../res/layout/view_preference_switch.xml | 44 +++++ app/src/main/res/layout/view_social_link.xml | 45 +++++ app/src/main/res/layout/view_sponsor.xml | 67 +++++++ app/src/main/res/menu/toolbar_menu.xml | 19 +- .../main/res/navigation/mobile_navigation.xml | 52 ----- .../res/navigation/welcome_navigation.xml | 42 ++++ app/src/main/res/values-af-rZA/strings.xml | 6 +- app/src/main/res/values-ar-rSA/strings.xml | 6 +- app/src/main/res/values-bn-rBD/strings.xml | 6 +- app/src/main/res/values-bn-rIN/strings.xml | 6 +- app/src/main/res/values-ca-rES/strings.xml | 6 +- app/src/main/res/values-cs-rCZ/strings.xml | 6 +- app/src/main/res/values-da-rDK/strings.xml | 6 +- app/src/main/res/values-de-rDE/strings.xml | 6 +- app/src/main/res/values-el-rGR/strings.xml | 6 +- app/src/main/res/values-es-rES/strings.xml | 6 +- app/src/main/res/values-fi-rFI/strings.xml | 6 +- app/src/main/res/values-fr-rFR/strings.xml | 6 +- app/src/main/res/values-hi-rIN/strings.xml | 6 +- app/src/main/res/values-hu-rHU/strings.xml | 6 +- app/src/main/res/values-in-rID/strings.xml | 6 +- app/src/main/res/values-it-rIT/strings.xml | 6 +- app/src/main/res/values-iw-rIL/strings.xml | 6 +- app/src/main/res/values-ja-rJP/strings.xml | 6 +- app/src/main/res/values-ka-rGE/strings.xml | 6 +- app/src/main/res/values-ko-rKR/strings.xml | 6 +- app/src/main/res/values-nl-rNL/strings.xml | 6 +- app/src/main/res/values-no-rNO/strings.xml | 6 +- app/src/main/res/values-pa-rIN/strings.xml | 6 +- app/src/main/res/values-pl-rPL/strings.xml | 6 +- app/src/main/res/values-pt-rBR/strings.xml | 6 +- app/src/main/res/values-pt-rPT/strings.xml | 6 +- app/src/main/res/values-ro-rRO/strings.xml | 6 +- app/src/main/res/values-ru-rRU/strings.xml | 6 +- app/src/main/res/values-si-rLK/strings.xml | 6 +- app/src/main/res/values-sr-rSP/strings.xml | 6 +- app/src/main/res/values-sv-rSE/strings.xml | 6 +- app/src/main/res/values-ta-rIN/strings.xml | 6 +- app/src/main/res/values-tr-rTR/strings.xml | 6 +- app/src/main/res/values-uk-rUA/strings.xml | 6 +- app/src/main/res/values-v23/themes.xml | 11 +- app/src/main/res/values-vi-rVN/strings.xml | 6 +- app/src/main/res/values-zh-rCN/strings.xml | 6 +- app/src/main/res/values-zh-rTW/strings.xml | 6 +- app/src/main/res/values/arrays.xml | 10 + app/src/main/res/values/attrs.xml | 24 +++ app/src/main/res/values/dimens.xml | 4 + app/src/main/res/values/preloaded_fonts.xml | 1 + app/src/main/res/values/resources.xml | 6 +- app/src/main/res/values/strings.xml | 46 +++-- app/src/main/res/values/styles.xml | 140 ++++++++++--- app/src/main/res/values/themes.xml | 22 ++- app/src/main/res/xml/dev_settings.xml | 2 +- app/src/main/res/xml/preferences.xml | 85 -------- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 199 files changed, 4274 insertions(+), 2631 deletions(-) create mode 100644 app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt delete mode 100644 app/src/main/java/com/vanced/manager/adapter/ChangelogAdapter.kt create mode 100644 app/src/main/java/com/vanced/manager/adapter/GetNotifAdapter.kt create mode 100644 app/src/main/java/com/vanced/manager/adapter/LinkAdapter.kt create mode 100644 app/src/main/java/com/vanced/manager/adapter/SelectAppsAdapter.kt create mode 100644 app/src/main/java/com/vanced/manager/adapter/SponsorAdapter.kt create mode 100644 app/src/main/java/com/vanced/manager/adapter/VancedPrefArray.kt delete mode 100644 app/src/main/java/com/vanced/manager/adapter/VariantAdapter.kt delete mode 100644 app/src/main/java/com/vanced/manager/core/installer/SplitInstallerService.kt create mode 100644 app/src/main/java/com/vanced/manager/model/AppListModel.kt create mode 100644 app/src/main/java/com/vanced/manager/model/LinkModel.kt create mode 100644 app/src/main/java/com/vanced/manager/model/NotifModel.kt create mode 100644 app/src/main/java/com/vanced/manager/model/SelectAppModel.kt create mode 100644 app/src/main/java/com/vanced/manager/model/SponsorModel.kt create mode 100644 app/src/main/java/com/vanced/manager/model/VancedPrefModel.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/WelcomeActivity.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/core/EmptyPreference.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/core/ItemDecoration.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/core/PreferenceCategory.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/core/PreferenceSwitch.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ManagerAccentColorDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ManagerLanguageDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ManagerThemeDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/ManagerVariantDialog.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/SelectAppsDialog.kt rename app/src/main/java/com/vanced/manager/ui/{fragments/URLChangeFragment.kt => dialogs/URLChangeDialog.kt} (89%) rename app/src/main/java/com/vanced/manager/ui/{fragments/VancedLanguageSelectionFragment.kt => dialogs/VancedLanguageSelectionDialog.kt} (67%) create mode 100644 app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt delete mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/ChosenPreferenceDialogFragment.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/GrantRootFragment.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/SelectAppsFragment.kt delete mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/UpdateCheckFragment.kt delete mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/VancedThemeSelectionFragment.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/fragments/WelcomeFragment.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/viewmodels/SettingsViewModel.kt create mode 100644 app/src/main/java/com/vanced/manager/ui/viewmodels/SettingsViewModelFactory.kt create mode 100644 app/src/main/java/com/vanced/manager/utils/Extensions.kt delete mode 100644 app/src/main/res/anim/tablayout_enter.xml delete mode 100644 app/src/main/res/anim/tablayout_exit.xml create mode 100644 app/src/main/res/animator/welcome_exit.xml create mode 100644 app/src/main/res/animator/welcome_pop_enter.xml delete mode 100644 app/src/main/res/drawable/arrow_down.xml create mode 100644 app/src/main/res/drawable/category_background.xml delete mode 100644 app/src/main/res/drawable/discord.xml create mode 100644 app/src/main/res/drawable/ic_adguard.xml rename app/src/main/res/drawable/{ic_microg_settings.xml => ic_app_settings_black_24dp.xml} (90%) delete mode 100644 app/src/main/res/drawable/ic_baseline_clear_24.xml rename app/src/main/res/drawable/{ic_baseline_resume_24.xml => ic_baseline_navigate_next_36.xml} (53%) create mode 100644 app/src/main/res/drawable/ic_baseline_navigate_next_48.xml delete mode 100644 app/src/main/res/drawable/ic_baseline_pause_24.xml create mode 100644 app/src/main/res/drawable/ic_brave.xml delete mode 100644 app/src/main/res/drawable/ic_brave_logo.xml delete mode 100644 app/src/main/res/drawable/ic_cloud_upload_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_discord.xml delete mode 100644 app/src/main/res/drawable/ic_done_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_github.xml create mode 100644 app/src/main/res/drawable/ic_instagram.xml create mode 100644 app/src/main/res/drawable/ic_launch_text.xml create mode 100644 app/src/main/res/drawable/ic_magisk.xml delete mode 100644 app/src/main/res/drawable/ic_pause_resume.xml delete mode 100644 app/src/main/res/drawable/ic_secret_settings_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_telegram.xml create mode 100644 app/src/main/res/drawable/ic_twitter.xml delete mode 100644 app/src/main/res/drawable/ic_vanced_nobg.xml create mode 100644 app/src/main/res/drawable/ic_website.xml create mode 100644 app/src/main/res/drawable/ic_youtube.xml delete mode 100644 app/src/main/res/drawable/telegram.xml delete mode 100644 app/src/main/res/drawable/twitter.xml create mode 100644 app/src/main/res/font/roboto_medium.xml create mode 100644 app/src/main/res/layout/activity_welcome.xml create mode 100644 app/src/main/res/layout/dialog_app_download.xml create mode 100644 app/src/main/res/layout/dialog_app_info.xml create mode 100644 app/src/main/res/layout/dialog_custom_url.xml create mode 100644 app/src/main/res/layout/dialog_installation_files_detected.xml create mode 100644 app/src/main/res/layout/dialog_installation_preferences.xml create mode 100644 app/src/main/res/layout/dialog_manager_accent_color.xml create mode 100644 app/src/main/res/layout/dialog_manager_language.xml create mode 100644 app/src/main/res/layout/dialog_manager_theme.xml create mode 100644 app/src/main/res/layout/dialog_manager_update.xml create mode 100644 app/src/main/res/layout/dialog_manager_variant.xml create mode 100644 app/src/main/res/layout/dialog_select_apps.xml delete mode 100644 app/src/main/res/layout/fragment_chosen_preferences.xml delete mode 100644 app/src/main/res/layout/fragment_custom_url.xml create mode 100644 app/src/main/res/layout/fragment_grant_root.xml delete mode 100644 app/src/main/res/layout/fragment_main.xml create mode 100644 app/src/main/res/layout/fragment_select_apps.xml create mode 100644 app/src/main/res/layout/fragment_settings.xml delete mode 100644 app/src/main/res/layout/fragment_update_check.xml create mode 100644 app/src/main/res/layout/fragment_welcome.xml delete mode 100644 app/src/main/res/layout/include_changelogs.xml delete mode 100644 app/src/main/res/layout/include_microg.xml delete mode 100644 app/src/main/res/layout/include_music.xml delete mode 100644 app/src/main/res/layout/include_useful_links.xml delete mode 100644 app/src/main/res/layout/include_vanced.xml delete mode 100644 app/src/main/res/layout/include_vanced_medias.xml create mode 100644 app/src/main/res/layout/view_app.xml create mode 100644 app/src/main/res/layout/view_app_checkbox.xml delete mode 100644 app/src/main/res/layout/view_changelog.xml delete mode 100644 app/src/main/res/layout/view_home.xml create mode 100644 app/src/main/res/layout/view_notification_setting.xml create mode 100644 app/src/main/res/layout/view_preference.xml create mode 100644 app/src/main/res/layout/view_preference_category.xml create mode 100644 app/src/main/res/layout/view_preference_switch.xml create mode 100644 app/src/main/res/layout/view_social_link.xml create mode 100644 app/src/main/res/layout/view_sponsor.xml create mode 100644 app/src/main/res/navigation/welcome_navigation.xml delete mode 100644 app/src/main/res/xml/preferences.xml diff --git a/app/build.gradle b/app/build.gradle index 860af252..20312a14 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,13 +20,12 @@ android { applicationId "com.vanced.manager" minSdkVersion 21 targetSdkVersion 30 - versionCode 131 - versionName "1.3.1 (Arcturus)" + versionCode 200 + versionName "2.0.0 (.nomagisk)" vectorDrawables.useSupportLibrary = true buildConfigField "String[]", "MANAGER_LANGUAGES", "{" + surroundWithQuotes(langs) + "}" - buildConfigField "String[]", "MANAGER_LANGUAGE_NAMES", "{" + surroundWithQuotes(getLanguageNames()) + "}" } lintOptions { @@ -83,20 +82,6 @@ def getLanguages() { return langs.toArray() } -def getLanguageNames() { - List langnames = new ArrayList() - for (int i = 0; i < langs.size(); i++) { - if (langs[i].length() > 2) { - Locale loc = new Locale(langs[i].substring(0, langs[i].length() - 3), langs[i].substring(langs[i].length() - 2)) - langnames.add(loc.getDisplayLanguage(loc).capitalize() + " (" + loc.getDisplayCountry(loc).capitalize() + ")") - } else { - Locale loc = new Locale(langs[i]) - langnames.add(loc.getDisplayLanguage(loc).capitalize()) - } - } - return langnames.toArray() -} - def surroundWithQuotes(Object[] arr) { String[] dummyArr = arr for (int i = 0; i < arr.length; i++) { @@ -114,31 +99,33 @@ dependencies { // AndroidX implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.browser:browser:1.2.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.1' - implementation 'androidx.core:core-ktx:1.3.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.3' + implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.fragment:fragment-ktx:1.2.5' implementation 'androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' - implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' - implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.1' implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'com.google.android.material:material:1.3.0-alpha02' + implementation 'com.google.android.material:material:1.3.0-alpha03' // Other implementation 'com.beust:klaxon:5.3' implementation 'com.crowdin.platform:mobile-sdk:1.1.6' + implementation 'com.github.florent37:viewtooltip:1.2.2' implementation 'com.github.kittinunf.fuel:fuel:2.2.3' implementation 'com.github.kittinunf.fuel:fuel-coroutines:2.2.3' implementation 'com.github.kittinunf.fuel:fuel-json:2.2.3' - implementation 'com.squareup.okhttp3:logging-interceptor:4.8.1' - implementation 'com.github.topjohnwu.libsu:core:3.0.1' - implementation 'com.github.topjohnwu.libsu:io:3.0.1' - implementation 'com.google.firebase:firebase-messaging:20.2.4' - implementation 'com.google.firebase:firebase-perf:19.0.8' + implementation 'com.github.topjohnwu.libsu:core:3.0.2' + implementation 'com.github.topjohnwu.libsu:io:3.0.2' + implementation 'com.google.android:flexbox:2.0.1' + implementation 'com.google.firebase:firebase-messaging:21.0.0' + implementation 'com.google.firebase:firebase-perf:19.0.9' + implementation 'com.google.firebase:firebase-analytics-ktx:18.0.0' + implementation 'com.google.firebase:firebase-crashlytics:17.2.2' implementation 'com.mindorks.android:prdownloader:0.6.0' - implementation 'com.google.firebase:firebase-analytics-ktx:17.5.0' - implementation 'com.google.firebase:firebase-crashlytics:17.2.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.8.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4f38c80b..4f94bb8f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - @@ -14,6 +13,7 @@ + @@ -40,22 +40,26 @@ - + + + + android:exported="true" + android:label="@string/app_name" + android:theme="@style/DarkTheme.Blue" /> @@ -79,10 +83,9 @@ android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_name" /> - - + \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt new file mode 100644 index 00000000..9adbdc4c --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt @@ -0,0 +1,84 @@ +package com.vanced.manager.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.FragmentActivity +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.recyclerview.widget.RecyclerView +import com.github.florent37.viewtooltip.ViewTooltip +import com.vanced.manager.R +import com.vanced.manager.databinding.ViewAppBinding +import com.vanced.manager.model.DataModel +import com.vanced.manager.ui.dialogs.AppInfoDialog +import com.vanced.manager.ui.viewmodels.HomeViewModel + +class AppListAdapter( + private val context: FragmentActivity, + private val viewModel: HomeViewModel, + private val tooltip: ViewTooltip +) : RecyclerView.Adapter() { + + val apps = mutableListOf() + val dataModels = mutableListOf() + private val rootDataModels = mutableListOf() + private val prefs = getDefaultSharedPreferences(context) + private var itemCount = 0 + + private val isRoot = prefs.getString("vanced_variant", "nonroot") == "root" + + inner class ListViewHolder(private val binding: ViewAppBinding) : RecyclerView.ViewHolder(binding.root) { + val appCard = binding.appCard + + fun bind(position: Int) { + binding.viewModel = viewModel + binding.dataModel = if (isRoot) rootDataModels[position] else dataModels[position] + binding.app = apps[position] + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder { + val view = ViewAppBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return ListViewHolder(view) + } + + override fun onBindViewHolder(holder: ListViewHolder, position: Int) { + holder.bind(position) + + holder.appCard.setOnClickListener { + tooltip.close() + AppInfoDialog( + apps[position], + dataModels[position]?.appIcon, + dataModels[position]?.changelog?.get() + ).show(context.supportFragmentManager, "info") + } + } + + override fun getItemCount(): Int = itemCount + + init { + + if (prefs.getBoolean("enable_vanced", true)) { + dataModels.add(viewModel.vanced.get()) + rootDataModels.add(viewModel.vancedRoot.get()) + apps.add(context.getString(R.string.vanced)) + itemCount++ + } + + if (prefs.getBoolean("enable_music", false)) { + dataModels.add(viewModel.music.get()) + rootDataModels.add(viewModel.musicRoot.get()) + apps.add(context.getString(R.string.music)) + itemCount++ + } + + if (!isRoot) { + dataModels.add(viewModel.microg.get()) + apps.add(context.getString(R.string.microg)) + itemCount++ + } + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/ChangelogAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/ChangelogAdapter.kt deleted file mode 100644 index fe9ba7ab..00000000 --- a/app/src/main/java/com/vanced/manager/adapter/ChangelogAdapter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.vanced.manager.adapter - -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView -import com.vanced.manager.R -import com.vanced.manager.ui.viewmodels.HomeViewModel - -class ChangelogAdapter(private val variant: String, viewModel: HomeViewModel?): RecyclerView.Adapter() { - - private val nonrootChangelogs = arrayOf(viewModel?.vanced?.get()?.changelog?.get(), viewModel?.music?.get()?.changelog?.get(), viewModel?.microg?.get()?.changelog?.get(), viewModel?.manager?.get()?.changelog?.get()) - private val rootChangelogs = arrayOf(viewModel?.vanced?.get()?.changelog?.get(), viewModel?.manager?.get()?.changelog?.get()) - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChangelogViewHolder { - val layoutInflater = LayoutInflater.from(parent.context) - val view = layoutInflater.inflate(R.layout.view_changelog, parent, false) - - return ChangelogViewHolder(view) - } - - override fun getItemCount(): Int = if (variant == "root") 2 else 4 - - override fun onBindViewHolder(holder: ChangelogViewHolder, position: Int) { - holder.changelog.text = - if (variant == "root") - rootChangelogs[position] - else - nonrootChangelogs[position] - - } - - open class ChangelogViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val changelog: TextView = itemView.findViewById(R.id.changelog_text) - } - -} diff --git a/app/src/main/java/com/vanced/manager/adapter/GetNotifAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/GetNotifAdapter.kt new file mode 100644 index 00000000..c174a3be --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/GetNotifAdapter.kt @@ -0,0 +1,60 @@ +package com.vanced.manager.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.google.firebase.messaging.FirebaseMessaging +import com.vanced.manager.R +import com.vanced.manager.databinding.ViewNotificationSettingBinding +import com.vanced.manager.model.NotifModel + +class GetNotifAdapter(context: Context) : RecyclerView.Adapter() { + + private val vanced = NotifModel( + "Vanced-Update", + context.getString(R.string.push_notifications, context.getString(R.string.vanced)), + context.getString(R.string.push_notifications_summary, context.getString(R.string.vanced)), + "vanced_notifs" + ) + private val music = NotifModel( + "MicroG-Update", + context.getString(R.string.push_notifications, context.getString(R.string.music)), + context.getString(R.string.push_notifications_summary, context.getString(R.string.music)), + "music_notifs" + ) + private val microg = NotifModel( + "Music-Update", + context.getString(R.string.push_notifications, context.getString(R.string.microg)), + context.getString(R.string.push_notifications_summary, context.getString(R.string.microg)), + "microg_notifs" + ) + + private val apps = arrayOf(vanced, music, microg) + + inner class GetNotifViewHolder(val binding: ViewNotificationSettingBinding) : RecyclerView.ViewHolder(binding.root) { + val switch = binding.notifSwitch + + fun bind(position: Int) { + binding.app = apps[position] + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GetNotifViewHolder { + val view = ViewNotificationSettingBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return GetNotifViewHolder(view) + } + + override fun onBindViewHolder(holder: GetNotifViewHolder, position: Int) { + holder.bind(position) + holder.switch.setOnCheckedListener { _, isChecked -> + when (isChecked) { + true -> FirebaseMessaging.getInstance().subscribeToTopic(apps[position].topic) + false -> FirebaseMessaging.getInstance().unsubscribeFromTopic(apps[position].topic) + } + } + } + + override fun getItemCount(): Int = 3 + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/LinkAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/LinkAdapter.kt new file mode 100644 index 00000000..92107ec9 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/LinkAdapter.kt @@ -0,0 +1,77 @@ +package com.vanced.manager.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.vanced.manager.R +import com.vanced.manager.databinding.ViewSocialLinkBinding +import com.vanced.manager.model.LinkModel +import com.vanced.manager.ui.viewmodels.HomeViewModel + +class LinkAdapter(context: Context, private val viewModel: HomeViewModel) : RecyclerView.Adapter() { + + private val instagram = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_instagram), + "https://instagram.com/vanced.youtube" + ) + + private val youtube = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_youtube), + "https://youtube.com/c/YouTubeVanced" + ) + + private val github = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_github), + "https://github.com/YTVanced/VancedManager" + ) + + private val website = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_website), + "https://vancedapp.com" + ) + + private val telegram = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_telegram), + "https://t.me/joinchat/AAAAAEHf-pi4jH1SDlAL4w" + ) + + private val twitter = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_twitter), + "https://twitter.com/YTVanced" + ) + + private val discord = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_discord), + "https://discord.gg/WCGNdRruzb" + ) + + private val reddit = LinkModel( + ContextCompat.getDrawable(context, R.drawable.ic_reddit), + "https://www.reddit.com/r/Vanced/" + ) + + val links = arrayOf(instagram, youtube, github, website, telegram, twitter, discord, reddit) + + inner class LinkViewHolder(private val binding: ViewSocialLinkBinding) : RecyclerView.ViewHolder(binding.root) { + + fun bind(position: Int) { + binding.viewModel = viewModel + binding.linkModel = links[position] + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkViewHolder { + val view = ViewSocialLinkBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return LinkViewHolder(view) + } + + override fun onBindViewHolder(holder: LinkViewHolder, position: Int) { + holder.bind(position) + } + + override fun getItemCount(): Int = links.size + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/SelectAppsAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/SelectAppsAdapter.kt new file mode 100644 index 00000000..6ef4e171 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/SelectAppsAdapter.kt @@ -0,0 +1,56 @@ +package com.vanced.manager.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.recyclerview.widget.RecyclerView +import com.vanced.manager.R +import com.vanced.manager.databinding.ViewAppCheckboxBinding +import com.vanced.manager.model.SelectAppModel + +class SelectAppsAdapter(context: Context) : RecyclerView.Adapter() { + + private val prefs by lazy { getDefaultSharedPreferences(context) } + + private val vanced = SelectAppModel( + context.getString(R.string.vanced), + "YouTube Vanced is the stock Android YouTube App, but better!", + "vanced", + prefs.getBoolean("enable_vanced", true) + ) + + private val music = SelectAppModel( + context.getString(R.string.music), + "Vanced, but for YouTube Music!\nrelatively less feature rich but fulfils your needs.", + "music", + prefs.getBoolean("enable_music", false) + ) + + val apps = arrayOf(vanced, music) + + inner class SelectAppsViewHolder(binding: ViewAppCheckboxBinding) : RecyclerView.ViewHolder(binding.root) { + val appName = binding.appCheckboxText + val appDescription = binding.appCheckboxDescription + val appCard = binding.appCheckboxBg + val checkbox = binding.appCheckbox + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SelectAppsViewHolder { + val view = ViewAppCheckboxBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return SelectAppsViewHolder(view) + } + + override fun onBindViewHolder(holder: SelectAppsViewHolder, position: Int) { + holder.appName.text = apps[position].appName + holder.appDescription.text = apps[position].appDescription + holder.checkbox.isChecked = apps[position].isChecked + holder.appCard.setOnClickListener { + holder.checkbox.isChecked = !holder.checkbox.isChecked + apps[position].isChecked = !apps[position].isChecked + } + } + + override fun getItemCount(): Int = 2 + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/SponsorAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/SponsorAdapter.kt new file mode 100644 index 00000000..f2a6a2f2 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/SponsorAdapter.kt @@ -0,0 +1,57 @@ +package com.vanced.manager.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.vanced.manager.R +import com.vanced.manager.databinding.ViewSponsorBinding +import com.vanced.manager.model.SponsorModel +import com.vanced.manager.ui.viewmodels.HomeViewModel + +class SponsorAdapter(context: Context, private val viewModel: HomeViewModel) : RecyclerView.Adapter() { + + private val brave = SponsorModel( + ContextCompat.getDrawable(context, R.drawable.ic_brave), + "Brave", + "https://vancedapp.com/brave" + ) + + private val adguard = SponsorModel( + ContextCompat.getDrawable(context, R.drawable.ic_adguard), + "AdGuard", + "https://vancedapp.com/adguard" + ) + + val sponsors = arrayOf(brave, adguard) + + inner class LinkViewHolder(private val binding: ViewSponsorBinding) : RecyclerView.ViewHolder(binding.root) { + //val cardBg = binding.linkBg + //val descText = binding.linkAppDescription + fun bind(position: Int) { + binding.viewModel = viewModel + binding.sponsor = sponsors[position] + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LinkViewHolder { + val view = ViewSponsorBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return LinkViewHolder(view) + } + + override fun onBindViewHolder(holder: LinkViewHolder, position: Int) { + //holder.cardBg.setCardBackgroundColor() + holder.bind(position) +// val lp = holder.cardBg +// if (lp is FlexboxLayoutManager.LayoutParams) { +// val flexboxLp = lp as FlexboxLayoutManager.LayoutParams +// flexboxLp.flexGrow = 1.0f +// flexboxLp.alignSelf = AlignItems.STRETCH +// } + } + + override fun getItemCount(): Int = 2 + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/VancedPrefArray.kt b/app/src/main/java/com/vanced/manager/adapter/VancedPrefArray.kt new file mode 100644 index 00000000..434a417f --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/VancedPrefArray.kt @@ -0,0 +1,35 @@ +package com.vanced.manager.adapter + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import com.vanced.manager.model.VancedPrefModel + +class VancedPrefArray(context: Context, textViewResourceId: Int, private val values: Array) : ArrayAdapter(context, textViewResourceId, values) { + + override fun getCount(): Int { + return values.size + } + + override fun getItem(position: Int): VancedPrefModel? { + return values[position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val label = super.getView(position, convertView, parent) as TextView + label.text = values[position].name + return label + } + + override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { + val label = super.getDropDownView(position, convertView, parent) as TextView + label.text = values[position].name + return label + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/VariantAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/VariantAdapter.kt deleted file mode 100644 index edd82ca6..00000000 --- a/app/src/main/java/com/vanced/manager/adapter/VariantAdapter.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.vanced.manager.adapter - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.view.animation.AccelerateDecelerateInterpolator -import android.widget.Toast -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.tabs.TabLayoutMediator -import com.vanced.manager.R -import com.vanced.manager.databinding.ViewHomeBinding -import com.vanced.manager.ui.viewmodels.HomeViewModel - -class VariantAdapter(private val viewModel: HomeViewModel, private val context: Context) : RecyclerView.Adapter() { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VariantAdapterHolder { - val view = ViewHomeBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return VariantAdapterHolder(view, context) - } - - override fun onBindViewHolder(holder: VariantAdapterHolder, position: Int) { - val variants = arrayOf("nonroot", "root") - holder.bind(variants[position], viewModel) - } - - override fun getItemCount(): Int = 2 - - class VariantAdapterHolder(private val homeBinding: ViewHomeBinding, private val context: Context) : RecyclerView.ViewHolder(homeBinding.root) { - private var isExpanded: Boolean = false - - fun bind(variant: String, viewModel: HomeViewModel) { - with (homeBinding) { - this.variant = variant - this.viewModel = viewModel - - with(includeChangelogsLayout) { - changelogButton.setOnClickListener { - with (includeChangelogsLayout) { - viewpager.visibility = if (isExpanded) View.GONE else View.VISIBLE - tablayout.visibility = if (isExpanded) View.GONE else View.VISIBLE - changelogButton.animate().apply { - rotation(if (isExpanded) 0F else 180F) - interpolator = AccelerateDecelerateInterpolator() - } - isExpanded = !isExpanded - } - } - viewpager.adapter = ChangelogAdapter(variant, viewModel) - val nonrootTitles = arrayOf("Vanced", "Music", "microG", "Manager") - val rootTitles = arrayOf("Vanced", "Manager") - - TabLayoutMediator(tablayout, viewpager) { tab, position -> - tab.text = - if (variant == "root") { - rootTitles[position] - } else { - nonrootTitles[position] - } - }.attach() - } - - includeVancedLayout.vancedCard.setOnLongClickListener { - versionToast("Vanced", viewModel.vanced.get()?.installedVersionName?.get()!!) - true - } - - includeMusicLayout.musicCard.setOnLongClickListener { - versionToast("Music", viewModel.music.get()?.installedVersionName?.get()!!) - true - } - - includeMicrogLayout.microgCard.setOnLongClickListener { - versionToast("MicroG", viewModel.microg.get()?.installedVersionName?.get()!!) - true - } - } - } - private fun versionToast(name: String, app: String?) { - val clip = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clip.setPrimaryClip(ClipData.newPlainText(name, app)) - Toast.makeText(context, context.getString(R.string.version_toast, name), Toast.LENGTH_LONG).show() - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/App.kt b/app/src/main/java/com/vanced/manager/core/App.kt index 79b6b04c..c759ffff 100644 --- a/app/src/main/java/com/vanced/manager/core/App.kt +++ b/app/src/main/java/com/vanced/manager/core/App.kt @@ -11,6 +11,9 @@ import com.crowdin.platform.data.remote.NetworkType import com.downloader.PRDownloader import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.JsonHelper.getJson +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking open class App: Application() { @@ -34,13 +37,25 @@ open class App: Application() { } - open fun loadJsonAsync() { - val latest = runBlocking { getJson("${getDefaultSharedPreferences(this@App).getString("install_url", baseUrl)}/latest.json") } + open fun loadJsonAsync() = CoroutineScope(Dispatchers.IO).launch { + val latest = getJson("${getDefaultSharedPreferences(this@App).getString("install_url", baseUrl)}/latest.json") - vanced.set(latest?.obj("vanced")) - music.set(latest?.obj("music")) - microg.set(latest?.obj("microg")) - manager.set(latest?.obj("manager")) + vanced.apply { + set(latest?.obj("vanced")) + notifyChange() + } + music.apply { + set(latest?.obj("music")) + notifyChange() + } + microg.apply { + set(latest?.obj("microg")) + notifyChange() + } + manager.apply { + set(latest?.obj("manager")) + notifyChange() + } } override fun onConfigurationChanged(newConfig: Configuration) { diff --git a/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt index 044c2dc3..3b435ef9 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloader.kt @@ -1,14 +1,12 @@ package com.vanced.manager.core.downloader import android.content.Context -import android.widget.Toast import com.downloader.Error import com.downloader.OnDownloadListener import com.downloader.PRDownloader import com.vanced.manager.R import com.vanced.manager.core.App -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.microgProgress -import com.vanced.manager.utils.AppUtils.mutableInstall +import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.InternetTools.getFileNameFromUrl import com.vanced.manager.utils.PackageHelper.install import kotlinx.coroutines.CoroutineScope @@ -17,39 +15,37 @@ import kotlinx.coroutines.launch object MicrogDownloader { - fun downloadMicrog(context: Context) { + fun downloadMicrog( + context: Context, + ) { CoroutineScope(Dispatchers.IO).launch { val url = (context.applicationContext as App).microg.get()?.string("url") - microgProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("apk")?.path, "microg.apk") + downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk") .build() - .setOnStartOrResumeListener { - mutableInstall.value = true - microgProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })) - microgProgress.get()?.showDownloadBar?.set(true) + .setOnStartOrResumeListener { + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })) } - .setOnCancelListener { - mutableInstall.value = false - microgProgress.get()?.showDownloadBar?.set(false) - } .setOnProgressListener { progress -> - microgProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) + downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) } .start(object : OnDownloadListener { override fun onDownloadComplete() { - install("microg", "${context.getExternalFilesDir("apk")}/microg.apk", context) - microgProgress.get()?.showDownloadBar?.set(false) - microgProgress.get()?.showInstallCircle?.set(true) + startMicrogInstall(context) } override fun onError(error: Error?) { - mutableInstall.value = false - microgProgress.get()?.showDownloadBar?.set(false) - Toast.makeText(context, context.getString(R.string.error_downloading, "microG"), Toast.LENGTH_SHORT).show() + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "microG")) } }) } } + fun startMicrogInstall(context: Context) { + downloadProgress.get()?.installing?.set(true) + downloadProgress.get()?.reset() + install("${context.getExternalFilesDir("microg")}/microg.apk", context) + } + } diff --git a/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt index ee507377..646dd4de 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/MusicDownloader.kt @@ -1,14 +1,14 @@ package com.vanced.manager.core.downloader import android.content.Context -import android.widget.Toast +import androidx.preference.PreferenceManager.getDefaultSharedPreferences import com.downloader.Error import com.downloader.OnDownloadListener import com.downloader.PRDownloader import com.vanced.manager.R import com.vanced.manager.core.App -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.musicProgress -import com.vanced.manager.utils.AppUtils.mutableInstall +import com.vanced.manager.utils.DownloadHelper.downloadProgress +import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.getFileNameFromUrl import com.vanced.manager.utils.PackageHelper.install import kotlinx.coroutines.CoroutineScope @@ -17,35 +17,29 @@ import kotlinx.coroutines.launch object MusicDownloader { + private var variant: String? = null + fun downloadMusic(context: Context){ CoroutineScope(Dispatchers.IO).launch { - val url = "https://vanced.app/api/v1/music/v${(context.applicationContext as App).music.get()?.string("version")}.apk" + val prefs = getDefaultSharedPreferences(context) + variant = prefs.getString("vanced_variant", "nonroot") + val url = "${prefs.getString("install_url", baseUrl)}/music/v${(context.applicationContext as App).music.get()?.string("version")}.apk" - musicProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("apk")?.path, "music.apk") + downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("music/$variant")?.path, "music.apk") .build() - .setOnStartOrResumeListener { - mutableInstall.value = true - musicProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) - musicProgress.get()?.showDownloadBar?.set(true) + .setOnStartOrResumeListener { + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) } .setOnProgressListener { progress -> - musicProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) - } - .setOnCancelListener { - mutableInstall.value = false - musicProgress.get()?.showDownloadBar?.set(false) + downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) } .start(object : OnDownloadListener { override fun onDownloadComplete() { - install("music", "${context.getExternalFilesDir("apk")}/music.apk", context) - musicProgress.get()?.showDownloadBar?.set(false) - musicProgress.get()?.showInstallCircle?.set(true) + startMusicInstall(context) } override fun onError(error: Error?) { - mutableInstall.value = false - musicProgress.get()?.showDownloadBar?.set(false) - Toast.makeText(context, context.getString(R.string.error_downloading, "Music"), Toast.LENGTH_SHORT).show() + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music")) } }) @@ -53,4 +47,10 @@ object MusicDownloader { } + fun startMusicInstall(context: Context) { + downloadProgress.get()?.installing?.set(true) + downloadProgress.get()?.reset() + install("${context.getExternalFilesDir("music/$variant")}/music.apk", context) + } + } diff --git a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt index d8c46a97..7e78695c 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt @@ -3,7 +3,6 @@ package com.vanced.manager.core.downloader import android.content.Context import android.content.SharedPreferences import android.os.Build -import android.widget.Toast import androidx.preference.PreferenceManager.getDefaultSharedPreferences import com.downloader.Error import com.downloader.OnDownloadListener @@ -12,12 +11,12 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.logEvent import com.vanced.manager.R import com.vanced.manager.core.App -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.vancedProgress -import com.vanced.manager.utils.AppUtils.mutableInstall import com.vanced.manager.utils.AppUtils.vancedRootPkg +import com.vanced.manager.utils.DownloadHelper.downloadProgress import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.getFileNameFromUrl +import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages import com.vanced.manager.utils.PackageHelper.getPkgVerCode import com.vanced.manager.utils.PackageHelper.installVanced import com.vanced.manager.utils.PackageHelper.installVancedRoot @@ -40,24 +39,28 @@ object VancedDownloader { private var installUrl: String? = null private var variant: String? = null private var theme: String? = null - private var lang: Array? = null + private var lang: MutableList? = null private lateinit var themePath: String private var count: Int = 0 + private var succesfulLangCount: Int = 0 private var hashUrl = "" private var vancedVersionCode = 0 private var vancedVersion: String? = null - fun downloadVanced(context: Context){ + private var downloadPath: String? = null + + fun downloadVanced(context: Context) { val app = context.applicationContext as App - File(context.getExternalFilesDir("apks")?.path as String).deleteRecursively() defPrefs = getDefaultSharedPreferences(context) installUrl = defPrefs.getString("install_url", baseUrl) prefs = context.getSharedPreferences("installPrefs", Context.MODE_PRIVATE) variant = defPrefs.getString("vanced_variant", "nonroot") - lang = prefs.getString("lang", "en")?.split(", ")?.toTypedArray() + downloadPath = context.getExternalFilesDir("vanced/$variant")?.path + File(downloadPath.toString()).deleteRecursively() + lang = prefs.getString("lang", getDefaultVancedLanguages(app))?.split(", ")?.toMutableList() theme = prefs.getString("theme", "dark") vancedVersion = app.vanced.get()?.string("version") themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme" @@ -69,6 +72,7 @@ object VancedDownloader { Build.SUPPORTED_ABIS.contains("arm64-v8a") -> "arm64_v8a" else -> "armeabi_v7a" } + count = 0 vancedVersionCode = app.vanced.get()?.int("versionCode") ?: 0 downloadSplits(context) @@ -89,19 +93,13 @@ object VancedDownloader { else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?") } - vancedProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("apks")?.path, getFileNameFromUrl(url)) + downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url)) .build() - .setOnStartOrResumeListener { - mutableInstall.value = true - vancedProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) - vancedProgress.get()?.showDownloadBar?.set(true) + .setOnStartOrResumeListener { + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url))) } .setOnProgressListener { progress -> - vancedProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) - } - .setOnCancelListener { - mutableInstall.value = false - vancedProgress.get()?.showDownloadBar?.set(false) + downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt()) } .start(object : OnDownloadListener { override fun onDownloadComplete() { @@ -112,7 +110,7 @@ object VancedDownloader { if (downloadStockCheck(context)) downloadSplits(context, "arch") else - prepareInstall(variant!!, context) + startVancedInstall(context) } else downloadSplits(context, "theme") } else @@ -122,10 +120,11 @@ object VancedDownloader { "dpi" -> downloadSplits(context, "lang") "lang" -> { count++ + succesfulLangCount++ if (count < lang?.count()!!) downloadSplits(context, "lang") else - prepareInstall(variant!!, context) + startVancedInstall(context) } } @@ -133,22 +132,24 @@ object VancedDownloader { override fun onError(error: Error?) { if (type == "lang") { count++ - if (count < lang?.count()!!) - downloadSplits(context, "lang") - else - prepareInstall(variant!!, context) + when { + count < lang?.count()!! -> downloadSplits(context, "lang") + succesfulLangCount == 0 -> { + lang?.add("en") + downloadSplits(context, "lang") + } + else -> startVancedInstall(context) + } + } else { - count = 0 - mutableInstall.value = false - vancedProgress.get()?.showDownloadBar?.set(false) - Toast.makeText(context, context.getString(R.string.error_downloading, getFileNameFromUrl(url)), Toast.LENGTH_SHORT).show() + downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, getFileNameFromUrl(url))) } } }) } } - private fun downloadStockCheck(context: Context) :Boolean { + fun downloadStockCheck(context: Context): Boolean { return try { getPkgVerCode(vancedRootPkg, context.packageManager) != vancedVersionCode } catch (e: Exception) { @@ -161,18 +162,16 @@ object VancedDownloader { } private fun validateTheme(context: Context): Boolean { - val themeS = context.getExternalFilesDir("apks")?.path + "/${theme}.apk" - val themeF = File(themeS) + val themeF = File(downloadPath, "${theme}.apk") runBlocking { getSha256(theme!!, context) } return checkSHA256(sha256Val!!,themeF) } - private fun prepareInstall(variant: String, context: Context) { - count = 0 - vancedProgress.get()?.showDownloadBar?.set(false) - vancedProgress.get()?.showInstallCircle?.set(true) + fun startVancedInstall(context: Context, variant: String? = this.variant) { + downloadProgress.get()?.installing?.set(true) + downloadProgress.get()?.reset() FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) { - param("vanced_variant", variant) + variant?.let { param("vanced_variant", it) } theme?.let { param("vanced_theme", it) } } if (variant == "root") diff --git a/app/src/main/java/com/vanced/manager/core/installer/AppInstallerService.kt b/app/src/main/java/com/vanced/manager/core/installer/AppInstallerService.kt index 1e89b453..033dfd17 100644 --- a/app/src/main/java/com/vanced/manager/core/installer/AppInstallerService.kt +++ b/app/src/main/java/com/vanced/manager/core/installer/AppInstallerService.kt @@ -5,16 +5,13 @@ import android.content.Intent import android.content.pm.PackageInstaller import android.os.IBinder import android.util.Log -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.microgProgress -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.musicProgress -import com.vanced.manager.utils.AppUtils.mutableInstall +import com.vanced.manager.utils.AppUtils.sendCloseDialog import com.vanced.manager.utils.AppUtils.sendFailure import com.vanced.manager.utils.AppUtils.sendRefresh class AppInstallerService: Service() { override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { - val app = intent.getStringExtra("app") when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) { PackageInstaller.STATUS_PENDING_USER_ACTION -> { Log.d(TAG, "Requesting user confirmation for installation") @@ -28,13 +25,12 @@ class AppInstallerService: Service() { } PackageInstaller.STATUS_SUCCESS -> { Log.d(TAG, "Installation succeed") - if (app == "microg") microgProgress.get()?.showInstallCircle?.set(false) else musicProgress.get()?.showInstallCircle?.set(false) - mutableInstall.postValue(false) + sendCloseDialog(this) sendRefresh(this) } else -> { + sendCloseDialog(this) sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999), this) - if (app == "microg") microgProgress.get()?.showInstallCircle?.set(false) else musicProgress.get()?.showInstallCircle?.set(false) } } stopSelf() diff --git a/app/src/main/java/com/vanced/manager/core/installer/SplitInstallerService.kt b/app/src/main/java/com/vanced/manager/core/installer/SplitInstallerService.kt deleted file mode 100644 index 0e95fb3d..00000000 --- a/app/src/main/java/com/vanced/manager/core/installer/SplitInstallerService.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.vanced.manager.core.installer - -import android.app.Service -import android.content.Intent -import android.content.pm.PackageInstaller -import android.os.IBinder -import android.util.Log -import com.vanced.manager.ui.viewmodels.HomeViewModel.Companion.vancedProgress -import com.vanced.manager.utils.AppUtils.mutableInstall -import com.vanced.manager.utils.AppUtils.sendFailure -import com.vanced.manager.utils.AppUtils.sendRefresh - -class SplitInstallerService: Service() { - - override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { - when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) { - PackageInstaller.STATUS_PENDING_USER_ACTION -> { - Log.d(TAG, "Requesting user confirmation for installation") - val confirmationIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT) - confirmationIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - try { - startActivity(confirmationIntent) - } catch (e: Exception) { - } - } - PackageInstaller.STATUS_SUCCESS -> { - Log.d(TAG, "Installation succeed") - vancedProgress.get()?.showInstallCircle?.set(false) - mutableInstall.postValue(false) - sendRefresh(this) - } - else -> { - sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999), this) - vancedProgress.get()?.showInstallCircle?.set(false) - } - } - stopSelf() - return START_NOT_STICKY - } - - override fun onBind(intent: Intent?): IBinder? { - return null - } - - companion object{ - const val TAG = "VMInstall" - } - -} diff --git a/app/src/main/java/com/vanced/manager/model/AppListModel.kt b/app/src/main/java/com/vanced/manager/model/AppListModel.kt new file mode 100644 index 00000000..b0892888 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/AppListModel.kt @@ -0,0 +1,12 @@ +package com.vanced.manager.model + +import android.graphics.drawable.Drawable + +data class AppListModel( + val icon: Drawable?, + val appName: String?, + val remoteVersion: String?, + val installedVersion: String?, + val changelog: String?, + val pkg: String? +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/model/DataModel.kt b/app/src/main/java/com/vanced/manager/model/DataModel.kt index c6d3370d..6b43120e 100644 --- a/app/src/main/java/com/vanced/manager/model/DataModel.kt +++ b/app/src/main/java/com/vanced/manager/model/DataModel.kt @@ -4,6 +4,7 @@ import android.content.Context import android.graphics.drawable.Drawable import android.os.Build import androidx.core.content.ContextCompat +import androidx.databinding.Observable import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableField import androidx.databinding.ObservableInt @@ -16,8 +17,10 @@ import kotlinx.coroutines.launch open class DataModel( private val jsonObject: ObservableField, - private val appPkg: String, - private val context: Context + private val context: Context, + val appPkg: String, + val appName: String, + val appIcon: Drawable? ) { private val versionCode = ObservableInt() @@ -27,7 +30,7 @@ open class DataModel( val versionName = ObservableField() val installedVersionName = ObservableField() val buttonTxt = ObservableField() - val buttonIcon = ObservableField() + //val buttonIcon = ObservableField() val changelog = ObservableField() fun fetch() = CoroutineScope(Dispatchers.IO).launch { @@ -37,12 +40,18 @@ open class DataModel( versionCode.set(jsonObject.get()?.int("versionCode") ?: 0) installedVersionCode.set(getPkgVersionCode(isAppInstalled.get(), appPkg)) buttonTxt.set(compareInt(installedVersionCode.get(), versionCode.get())) - buttonIcon.set(compareIntDrawable(installedVersionCode.get(), versionCode.get())) + //buttonIcon.set(compareIntDrawable(installedVersionCode.get(), versionCode.get())) changelog.set(jsonObject.get()?.string("changelog") ?: context.getString(R.string.unavailable)) } init { fetch() + jsonObject.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() { + override fun onPropertyChanged(sender: Observable?, propertyId: Int) { + fetch() + } + + }) } private fun getPkgVersionName(toCheck: Boolean, pkg: String): String { @@ -82,5 +91,5 @@ open class DataModel( else -> ContextCompat.getDrawable(context, R.drawable.ic_download) } } - + } diff --git a/app/src/main/java/com/vanced/manager/model/LinkModel.kt b/app/src/main/java/com/vanced/manager/model/LinkModel.kt new file mode 100644 index 00000000..b342fd4d --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/LinkModel.kt @@ -0,0 +1,8 @@ +package com.vanced.manager.model + +import android.graphics.drawable.Drawable + +data class LinkModel( + val linkIcon: Drawable?, + val linkUrl: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/model/NotifModel.kt b/app/src/main/java/com/vanced/manager/model/NotifModel.kt new file mode 100644 index 00000000..7c4256a0 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/NotifModel.kt @@ -0,0 +1,8 @@ +package com.vanced.manager.model + +data class NotifModel( + val topic: String, + val switchTitle: String, + val switchSummary: String, + val key: String +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt index ebbcfc77..23840c68 100644 --- a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt +++ b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt @@ -8,16 +8,18 @@ open class ProgressModel { val downloadProgress = ObservableInt() val downloadingFile = ObservableField() - val showInstallCircle = ObservableBoolean() - val showDownloadBar = ObservableBoolean() + val installing = ObservableBoolean() var currentDownload: Int = 0 - init { + fun reset() { downloadProgress.set(0) downloadingFile.set("") - showInstallCircle.set(false) - showDownloadBar.set(false) + } + + init { + installing.set(false) + reset() } } diff --git a/app/src/main/java/com/vanced/manager/model/SelectAppModel.kt b/app/src/main/java/com/vanced/manager/model/SelectAppModel.kt new file mode 100644 index 00000000..18117db1 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/SelectAppModel.kt @@ -0,0 +1,8 @@ +package com.vanced.manager.model + +data class SelectAppModel( + val appName: String, + val appDescription: String, + val tag: String, + var isChecked: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/model/SponsorModel.kt b/app/src/main/java/com/vanced/manager/model/SponsorModel.kt new file mode 100644 index 00000000..43398111 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/SponsorModel.kt @@ -0,0 +1,9 @@ +package com.vanced.manager.model + +import android.graphics.drawable.Drawable + +data class SponsorModel( + val logo: Drawable?, + val name: String, + val url: String +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/model/VancedPrefModel.kt b/app/src/main/java/com/vanced/manager/model/VancedPrefModel.kt new file mode 100644 index 00000000..eab9fc8d --- /dev/null +++ b/app/src/main/java/com/vanced/manager/model/VancedPrefModel.kt @@ -0,0 +1,6 @@ +package com.vanced.manager.model + +data class VancedPrefModel( + val name: String, + val value: String +) \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/MainActivity.kt b/app/src/main/java/com/vanced/manager/ui/MainActivity.kt index c57b01c1..7ce6a380 100644 --- a/app/src/main/java/com/vanced/manager/ui/MainActivity.kt +++ b/app/src/main/java/com/vanced/manager/ui/MainActivity.kt @@ -20,10 +20,9 @@ import com.google.firebase.messaging.FirebaseMessaging import com.vanced.manager.R import com.vanced.manager.databinding.ActivityMainBinding import com.vanced.manager.ui.dialogs.DialogContainer +import com.vanced.manager.ui.dialogs.ManagerUpdateDialog import com.vanced.manager.ui.fragments.HomeFragmentDirections import com.vanced.manager.ui.fragments.SettingsFragmentDirections -import com.vanced.manager.ui.fragments.UpdateCheckFragment -import com.vanced.manager.utils.AppUtils.installing import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.LanguageContextWrapper import com.vanced.manager.utils.PackageHelper @@ -53,15 +52,14 @@ class MainActivity : AppCompatActivity() { with(binding) { lifecycleOwner = this@MainActivity - setSupportActionBar(homeToolbar) - homeToolbar.setupWithNavController(this@MainActivity.navHost, AppBarConfiguration(this@MainActivity.navHost.graph)) + setSupportActionBar(toolbar) + toolbar.setupWithNavController(this@MainActivity.navHost, AppBarConfiguration(this@MainActivity.navHost.graph)) } navHost.addOnDestinationChangedListener { _, currFrag: NavDestination, _ -> setDisplayHomeAsUpEnabled(currFrag.id != R.id.home_fragment) } - initDialogs() - + initDialogs(intent.getBooleanExtra("firstLaunch", false)) } override fun onBackPressed() { @@ -70,7 +68,7 @@ class MainActivity : AppCompatActivity() { } private fun setDisplayHomeAsUpEnabled(isNeeded: Boolean) { - binding.homeToolbar.navigationIcon = if (isNeeded) ContextCompat.getDrawable(this, R.drawable.ic_keyboard_backspace_black_24dp) else null + binding.toolbar.navigationIcon = if (isNeeded) ContextCompat.getDrawable(this, R.drawable.ic_keyboard_backspace_black_24dp) else null } override fun onPause() { @@ -85,8 +83,6 @@ class MainActivity : AppCompatActivity() { } override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (installing.value!!) - return false when (item.itemId) { android.R.id.home -> { @@ -101,6 +97,9 @@ class MainActivity : AppCompatActivity() { navHost.navigate(HomeFragmentDirections.toSettingsFragment()) return true } + R.id.toolbar_update_manager -> { + ManagerUpdateDialog(false).show(supportFragmentManager, "manager_update") + } R.id.dev_settings -> { navHost.navigate(SettingsFragmentDirections.toDevSettingsFragment()) return true @@ -126,13 +125,13 @@ class MainActivity : AppCompatActivity() { finish() } - private fun initDialogs() { + private fun initDialogs(firstLaunch: Boolean) { val prefs = getDefaultSharedPreferences(this) val variant = prefs.getString("vanced_variant", "nonroot") prefs.getBoolean("show_root_dialog", true) when { - prefs.getBoolean("firstStart", true) -> { + firstLaunch -> { DialogContainer.showSecurityDialog(this) with(FirebaseMessaging.getInstance()) { subscribeToTopic("Vanced-Update") @@ -158,7 +157,7 @@ class MainActivity : AppCompatActivity() { private fun checkUpdates() { if (InternetTools.isUpdateAvailable(this)) { - UpdateCheckFragment().show(supportFragmentManager, "UpdateCheck") + ManagerUpdateDialog(false).show(supportFragmentManager, "UpdateCheck") } } diff --git a/app/src/main/java/com/vanced/manager/ui/WelcomeActivity.kt b/app/src/main/java/com/vanced/manager/ui/WelcomeActivity.kt new file mode 100644 index 00000000..58f8abe8 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/WelcomeActivity.kt @@ -0,0 +1,24 @@ +package com.vanced.manager.ui + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.databinding.DataBindingUtil +import androidx.navigation.findNavController +import com.vanced.manager.R +import com.vanced.manager.databinding.ActivityWelcomeBinding + +class WelcomeActivity : AppCompatActivity() { + + private lateinit var binding: ActivityWelcomeBinding + private val navHost by lazy { findNavController(R.id.welcome_navhost) } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome) + } + + override fun onBackPressed() { + if (!navHost.popBackStack()) + finish() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/EmptyPreference.kt b/app/src/main/java/com/vanced/manager/ui/core/EmptyPreference.kt new file mode 100644 index 00000000..762d8211 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/EmptyPreference.kt @@ -0,0 +1,50 @@ +package com.vanced.manager.ui.core + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.FrameLayout +import com.vanced.manager.R +import kotlinx.android.synthetic.main.view_preference.view.* + +class EmptyPreference @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, + defStyleRes: Int = 0 +) : FrameLayout(context, attrs, defStyle, defStyleRes) { + + init { + LayoutInflater.from(context).inflate(R.layout.view_preference, this, true) + initAttrs(context, attrs) + } + + fun setTitle(newTitle: String) { + preference_title.text = newTitle + } + + fun setSummary(newSummary: String) { + preference_summary.text = newSummary + preference_summary.visibility = View.VISIBLE + preference_title.setPadding(0, 0, 0, 0) + } + + private fun initAttrs(context: Context, attrs: AttributeSet?) { + attrs?.let { mAttrs -> + val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.EmptyPreference, 0, 0) + val title = typedArray.getText(R.styleable.EmptyPreference_preference_title) + val summary = typedArray.getText(R.styleable.EmptyPreference_preference_summary) + if (summary != null) { + preference_summary.text = summary + } else { + preference_summary.visibility = View.GONE + preference_title.setPadding(0, 12, 0, 12) + } + preference_title.text = title + typedArray.recycle() + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/ItemDecoration.kt b/app/src/main/java/com/vanced/manager/ui/core/ItemDecoration.kt new file mode 100644 index 00000000..b73caf65 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/ItemDecoration.kt @@ -0,0 +1,38 @@ +package com.vanced.manager.ui.core + +import android.graphics.Canvas +import android.graphics.Rect +import android.graphics.drawable.Drawable +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +class ItemDecoration(private val line: Drawable?) : RecyclerView.ItemDecoration() { + + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + with(outRect) { + top = 4 + bottom = 4 + } + } + + override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { + val dividerLeft = parent.paddingLeft + val dividerRight = parent.width - parent.paddingRight + + val childCount = parent.childCount + (0..childCount - 2).forEach { + val child = parent.getChildAt(it) + val params = child.layoutParams as RecyclerView.LayoutParams + val dividerTop: Int = child.bottom + params.bottomMargin + val dividerBottom: Int = dividerTop + line!!.intrinsicHeight + line.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) + line.draw(c) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/PreferenceCategory.kt b/app/src/main/java/com/vanced/manager/ui/core/PreferenceCategory.kt new file mode 100644 index 00000000..ecc1dbd6 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/PreferenceCategory.kt @@ -0,0 +1,33 @@ +package com.vanced.manager.ui.core + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.LinearLayout +import com.vanced.manager.R +import kotlinx.android.synthetic.main.view_preference_category.view.* + +class PreferenceCategory @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : LinearLayout(context, attrs, defStyle) { + + init { + LayoutInflater.from(context).inflate(R.layout.view_preference_category, this, true) + initAttrs(context, attrs) + setPadding(0, 4, 0, 0) + orientation = VERTICAL + } + + private fun initAttrs(context: Context, attrs: AttributeSet?) { + attrs.let { mAttrs -> + val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.PreferenceCategory, 0, 0) + val title = typedArray.getText(R.styleable.PreferenceCategory_category_title) + + category_title.text = title + typedArray.recycle() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/PreferenceSwitch.kt b/app/src/main/java/com/vanced/manager/ui/core/PreferenceSwitch.kt new file mode 100644 index 00000000..18d8b81b --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/core/PreferenceSwitch.kt @@ -0,0 +1,112 @@ +package com.vanced.manager.ui.core + +import android.content.Context +import android.util.AttributeSet +import android.util.Log +import android.view.LayoutInflater +import android.widget.CompoundButton +import android.widget.FrameLayout +import androidx.databinding.BindingAdapter +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.vanced.manager.R +import kotlinx.android.synthetic.main.view_preference_switch.view.* + +class PreferenceSwitch @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, + defStyleRes: Int = 0 +) : FrameLayout(context, attrs, defStyle, defStyleRes) { + + private val prefs by lazy { getDefaultSharedPreferences(context) } + private var prefKey: String = "" + private var defValue: Boolean = false + private var mListener: OnCheckedListener? = null + + init { + LayoutInflater.from(context).inflate(R.layout.view_preference_switch, this, true) + initAttrs(context, attrs) + } + + override fun onFinishInflate() { + super.onFinishInflate() + preference_switch.isChecked = prefs.getBoolean(prefKey, defValue) + setOnClickListener { + preference_switch.isChecked = !preference_switch.isChecked + Log.d("clickTest", "clicked") + } + preference_switch.setOnCheckedChangeListener { buttonView, isChecked -> + prefs.edit().putBoolean(prefKey, isChecked).apply() + mListener?.onChecked(buttonView, isChecked) + } + } + + fun setOnCheckedListener(method: (buttonView: CompoundButton, isChecked: Boolean) -> Unit) { + mListener = object : OnCheckedListener{ + override fun onChecked(buttonView: CompoundButton, isChecked: Boolean) { + method(buttonView, isChecked) + } + } + } + + fun setOnCheckedListener(listener: OnCheckedListener?) { + mListener = listener + } + + private fun initAttrs(context: Context, attrs: AttributeSet?) { + attrs?.let { mAttrs -> + val typedArray = context.obtainStyledAttributes(mAttrs, R.styleable.PreferenceSwitch, 0, 0) + val title = typedArray.getText(R.styleable.PreferenceSwitch_switch_title) + val summary = typedArray.getText(R.styleable.PreferenceSwitch_switch_summary) + val key = typedArray.getText(R.styleable.PreferenceSwitch_switch_key) + val value = typedArray.getBoolean(R.styleable.PreferenceSwitch_switch_def_value, false) + + if (key != null) + prefKey = key.toString() + + defValue = value + preference_switch_title.text = title + + if (summary != null) { + preference_switch_summary.text = summary + } + + typedArray.recycle() + } + } + + interface OnCheckedListener { + fun onChecked(buttonView: CompoundButton, isChecked: Boolean) + } + + companion object { + + @JvmStatic + @BindingAdapter("app:switch_title") + fun setTitle(view: PreferenceSwitch, newTitle: String) { + view.preference_switch_title.text = newTitle + } + + @JvmStatic + @BindingAdapter("app:switch_summary") + fun setSummary(view: PreferenceSwitch, newSummary: String) { + view.preference_switch_summary.text = newSummary + } + + @JvmStatic + @BindingAdapter("app:switch_key") + fun setKey(view: PreferenceSwitch, newKey: String) { + view.prefKey = newKey + view.preference_switch.isChecked = view.prefs.getBoolean(view.prefKey, view.defValue) + } + + @JvmStatic + @BindingAdapter("app:switch_def_val") + fun setDefaultValue(view: PreferenceSwitch, newVal: Boolean) { + view.defValue = newVal + view.preference_switch.isChecked = view.prefs.getBoolean(view.prefKey, view.defValue) + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/core/SplashScreenActivity.kt b/app/src/main/java/com/vanced/manager/ui/core/SplashScreenActivity.kt index 7d2b5f83..bb585070 100644 --- a/app/src/main/java/com/vanced/manager/ui/core/SplashScreenActivity.kt +++ b/app/src/main/java/com/vanced/manager/ui/core/SplashScreenActivity.kt @@ -3,14 +3,22 @@ package com.vanced.manager.ui.core import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import androidx.preference.PreferenceManager.getDefaultSharedPreferences import com.vanced.manager.ui.MainActivity +import com.vanced.manager.ui.WelcomeActivity class SplashScreenActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - startActivity(Intent(this@SplashScreenActivity, MainActivity::class.java)) - finish() + if (getDefaultSharedPreferences(this).getBoolean("firstLaunch", true)) { + startActivity(Intent(this@SplashScreenActivity, WelcomeActivity::class.java)) + finish() + } else { + startActivity(Intent(this@SplashScreenActivity, MainActivity::class.java)) + finish() + } + } } diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt new file mode 100644 index 00000000..9815d7bb --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/AppDownloadDialog.kt @@ -0,0 +1,88 @@ +package com.vanced.manager.ui.dialogs + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.DialogFragment +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.downloader.PRDownloader +import com.vanced.manager.R +import com.vanced.manager.core.downloader.MicrogDownloader.downloadMicrog +import com.vanced.manager.core.downloader.MusicDownloader.downloadMusic +import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced +import com.vanced.manager.databinding.DialogAppDownloadBinding +import com.vanced.manager.utils.DownloadHelper.downloadProgress + +class AppDownloadDialog( + private val app: String, + private val installing: Boolean = false +) : DialogFragment() { + + private lateinit var binding: DialogAppDownloadBinding + + private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } + + private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + when (intent.action) { + CLOSE_DIALOG -> dismiss() + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + if (dialog != null && dialog?.window != null) { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + } + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_app_download, container, false) + binding.progress = downloadProgress.get() + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + isCancelable = false + binding.appDownloadHeader.text = requireActivity().getString(R.string.installing_app, app) + binding.appDownloadCancel.setOnClickListener { + if (downloadProgress.get()?.installing?.get() == true) + return@setOnClickListener + + PRDownloader.cancel(downloadProgress.get()!!.currentDownload) + dismiss() + } + if (!installing) { + when (app) { + requireActivity().getString(R.string.vanced) -> downloadVanced(requireActivity()) + requireActivity().getString(R.string.music) -> downloadMusic(requireActivity()) + requireActivity().getString(R.string.microg) -> downloadMicrog(requireActivity()) + } + } + } + + override fun onResume() { + super.onResume() + registerReceiver() + } + + private fun registerReceiver() { + val intentFilter = IntentFilter() + intentFilter.addAction(CLOSE_DIALOG) + localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) + } + + companion object { + const val CLOSE_DIALOG = "close_dialog" + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt new file mode 100644 index 00000000..126d90ae --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/AppInfoDialog.kt @@ -0,0 +1,38 @@ +package com.vanced.manager.ui.dialogs + +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.DialogFragment +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogAppInfoBinding + +class AppInfoDialog( + private val appName: String?, + private val appIcon: Drawable?, + private val changelog: String? +) : DialogFragment() { + + private lateinit var binding: DialogAppInfoBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + if (dialog != null && dialog?.window != null) { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + } + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_app_info, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.aboutAppName.text = requireActivity().getString(R.string.about_app, appName) + binding.aboutAppImage.setImageDrawable(appIcon) + binding.aboutAppChangelog.text = changelog + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/DialogContainer.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/DialogContainer.kt index a1fc44bb..ac234807 100644 --- a/app/src/main/java/com/vanced/manager/ui/dialogs/DialogContainer.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/DialogContainer.kt @@ -8,10 +8,8 @@ import androidx.core.content.ContextCompat.startActivity import androidx.preference.PreferenceManager import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.vanced.manager.R -import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced import com.vanced.manager.utils.InternetTools.openUrl import com.vanced.manager.utils.MiuiHelper -import com.vanced.manager.utils.PackageHelper.installVanced object DialogContainer { @@ -36,7 +34,7 @@ object DialogContainer { show() } val prefs = PreferenceManager.getDefaultSharedPreferences(context) - prefs.edit().putBoolean("firstStart", false).apply() + prefs.edit().putBoolean("firstLaunch", false).apply() } private fun showMiuiDialog(context: Context) { @@ -57,22 +55,6 @@ object DialogContainer { } } - //TODO - fun installOrDownload(context: Context) { - MaterialAlertDialogBuilder(context).apply { - setTitle("") - setMessage("") - setNegativeButton("") { dialog, _ -> - downloadVanced(context) - dialog.dismiss() - } - setPositiveButton(context.getString(R.string.button_reinstall)) { dialog, _ -> - installVanced(context) - dialog.dismiss() - } - } - } - fun statementFalse(context: Context) { MaterialAlertDialogBuilder(context).apply { setTitle("Wait what?") diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt new file mode 100644 index 00000000..d4ca4efe --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/InstallationFilesDetectedDialog.kt @@ -0,0 +1,51 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.vanced.manager.R +import com.vanced.manager.core.downloader.MicrogDownloader.startMicrogInstall +import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall +import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall +import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding +import com.vanced.manager.utils.Extensions.show + +class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() { + + private lateinit var binding: DialogInstallationFilesDetectedBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_installation_files_detected, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.installationDetectedTitle.text = requireActivity().getString(R.string.app_install_files_detected, app) + binding.installationDetectedSummary.text = requireActivity().getString(R.string.app_install_files_detected_summary, app) + + binding.installationDetectedRedownload.setOnClickListener { + dismiss() + AppDownloadDialog(app).show(requireActivity()) + } + + binding.installationDetectedInstall.setOnClickListener { + when (app) { + requireActivity().getString(R.string.vanced) -> startVancedInstall(requireActivity(), getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot")) + requireActivity().getString(R.string.music) -> startMusicInstall(requireActivity()) + requireActivity().getString(R.string.microg) -> startMicrogInstall(requireActivity()) + } + AppDownloadDialog(app, true).show(requireActivity()) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerAccentColorDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerAccentColorDialog.kt new file mode 100644 index 00000000..ba90cf7c --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerAccentColorDialog.kt @@ -0,0 +1,45 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.radiobutton.MaterialRadioButton +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogManagerAccentColorBinding +import com.vanced.manager.utils.Extensions.getCheckedButtonTag + +class ManagerAccentColorDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogManagerAccentColorBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_accent_color, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val accent = prefs.getString("manager_accent", "Blue") + view.findViewWithTag(accent).isChecked = true + binding.accentSave.setOnClickListener { + val newPref = binding.accentRadiogroup.getCheckedButtonTag() + if (accent != newPref) { + prefs.edit().putString("manager_accent", newPref).apply() + dismiss() + requireActivity().recreate() + } else { + dismiss() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerLanguageDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerLanguageDialog.kt new file mode 100644 index 00000000..a794eea3 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerLanguageDialog.kt @@ -0,0 +1,64 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT +import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.radiobutton.MaterialRadioButton +import com.vanced.manager.BuildConfig.MANAGER_LANGUAGES +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogManagerLanguageBinding +import com.vanced.manager.utils.Extensions.getCheckedButtonTag +import com.vanced.manager.utils.LanguageHelper.getLanguageFormat +import java.util.* + +class ManagerLanguageDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogManagerLanguageBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_language, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + addRadioButtons() + val language = prefs.getString("manager_lang", "System Default") + view.findViewWithTag(language).isChecked = true + binding.languageSave.setOnClickListener { + val newPref = binding.languageRadiogroup.getCheckedButtonTag() + if (language != newPref) { + prefs.edit().putString("manager_lang", newPref).apply() + dismiss() + requireActivity().recreate() + } else { + dismiss() + } + } + } + + private fun addRadioButtons() { + requireActivity().runOnUiThread { + (arrayOf("System Default") + MANAGER_LANGUAGES).forEach { lang -> + val button = MaterialRadioButton(requireActivity()).apply { + text = getLanguageFormat(requireActivity(), lang) + textSize = 18f + tag = lang + } + binding.languageRadiogroup.addView(button, MATCH_PARENT, WRAP_CONTENT) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerThemeDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerThemeDialog.kt new file mode 100644 index 00000000..d33348b5 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerThemeDialog.kt @@ -0,0 +1,44 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.radiobutton.MaterialRadioButton +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogManagerThemeBinding +import com.vanced.manager.utils.Extensions.getCheckedButtonTag + +class ManagerThemeDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogManagerThemeBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_theme, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val theme = prefs.getString("manager_theme", "System Default") + view.findViewWithTag(theme).isChecked = true + binding.themeSave.setOnClickListener { + val newPref = binding.themeRadiogroup.getCheckedButtonTag() + if (theme != newPref) { + prefs.edit().putString("manager_theme", newPref).apply() + dismiss() + requireActivity().recreate() + } else { + dismiss() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt new file mode 100644 index 00000000..52462e76 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerUpdateDialog.kt @@ -0,0 +1,89 @@ +package com.vanced.manager.ui.dialogs + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.DialogFragment +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.downloader.PRDownloader +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogManagerUpdateBinding +import com.vanced.manager.utils.DownloadHelper.downloadManager +import com.vanced.manager.utils.DownloadHelper.downloadProgress +import com.vanced.manager.utils.InternetTools.isUpdateAvailable + +class ManagerUpdateDialog( + private val forceUpdate: Boolean +) : DialogFragment() { + + private lateinit var binding: DialogManagerUpdateBinding + + private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } + + private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + when (intent.action) { + CLOSE_DIALOG -> dismiss() + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + if (dialog != null && dialog?.window != null) { + dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + } + isCancelable = false + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_update, container, false) + binding.progress = downloadProgress.get() + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if (forceUpdate) { + binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) + downloadManager(requireActivity()) + } else + checkUpdates() + + binding.managerUpdateCancel.setOnClickListener { + PRDownloader.cancel(downloadProgress.get()!!.currentDownload) + dismiss() + } + } + + override fun onResume() { + super.onResume() + registerReceiver() + } + + private fun checkUpdates() { + if (isUpdateAvailable(requireActivity())) { + binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient) + downloadManager(requireActivity()) + } else + binding.managerUpdatePatient.text = requireActivity().getString(R.string.update_not_found) + } + + private fun registerReceiver() { + val intentFilter = IntentFilter() + intentFilter.addAction(CLOSE_DIALOG) + localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter) + } + + companion object { + const val CLOSE_DIALOG = "close_dialog" + } + +} diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerVariantDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerVariantDialog.kt new file mode 100644 index 00000000..2f7452bd --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/ManagerVariantDialog.kt @@ -0,0 +1,44 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.radiobutton.MaterialRadioButton +import com.vanced.manager.R +import com.vanced.manager.databinding.DialogManagerVariantBinding +import com.vanced.manager.utils.Extensions.getCheckedButtonTag + +class ManagerVariantDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogManagerVariantBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_manager_variant, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val variant = prefs.getString("vanced_variant", "nonroot") + view.findViewWithTag(variant).isChecked = true + binding.variantSave.setOnClickListener { + val newPref = binding.variantRadiogroup.getCheckedButtonTag() + if (variant != newPref) { + prefs.edit().putString("vanced_variant", newPref).apply() + dismiss() + requireActivity().recreate() + } else { + dismiss() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/SelectAppsDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/SelectAppsDialog.kt new file mode 100644 index 00000000..89a9da5c --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/SelectAppsDialog.kt @@ -0,0 +1,50 @@ +package com.vanced.manager.ui.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.recyclerview.widget.LinearLayoutManager +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.vanced.manager.R +import com.vanced.manager.adapter.SelectAppsAdapter +import com.vanced.manager.databinding.DialogSelectAppsBinding + +class SelectAppsDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogSelectAppsBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_select_apps, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val ad = SelectAppsAdapter(requireActivity()) + binding.selectAppsRecycler.apply { + layoutManager = LinearLayoutManager(requireActivity()) + adapter = ad + setHasFixedSize(true) + } + binding.selectAppsSave.setOnClickListener { + if (ad.apps.all { app -> !app.isChecked }) { + Toast.makeText(requireActivity(), R.string.select_at_least_one_app, Toast.LENGTH_SHORT).show() + return@setOnClickListener + } + ad.apps.forEach { app -> + prefs.edit().putBoolean("enable_${app.tag}", app.isChecked).apply() + } + dismiss() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt similarity index 89% rename from app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt rename to app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt index 3edf1d4a..b46599c4 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/URLChangeDialog.kt @@ -1,4 +1,4 @@ -package com.vanced.manager.ui.fragments +package com.vanced.manager.ui.dialogs import android.graphics.Color import android.graphics.drawable.ColorDrawable @@ -14,7 +14,7 @@ import com.google.android.material.button.MaterialButton import com.vanced.manager.R import com.vanced.manager.utils.InternetTools.baseUrl -class URLChangeFragment : DialogFragment() { +class URLChangeDialog : DialogFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -23,7 +23,7 @@ class URLChangeFragment : DialogFragment() { if (dialog != null && dialog?.window != null) { dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) } - return inflater.inflate(R.layout.fragment_custom_url, container, false) + return inflater.inflate(R.layout.dialog_custom_url, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -39,7 +39,7 @@ class URLChangeFragment : DialogFragment() { saveUrl(finalUrl) } - view.findViewById(R.id.url_reset).setOnClickListener {saveUrl(baseUrl)} + view.findViewById(R.id.url_reset).setOnClickListener { saveUrl(baseUrl) } } private fun saveUrl(url: String) { diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/VancedLanguageSelectionFragment.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedLanguageSelectionDialog.kt similarity index 67% rename from app/src/main/java/com/vanced/manager/ui/fragments/VancedLanguageSelectionFragment.kt rename to app/src/main/java/com/vanced/manager/ui/dialogs/VancedLanguageSelectionDialog.kt index 4781a893..5c842e7b 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/VancedLanguageSelectionFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedLanguageSelectionDialog.kt @@ -1,6 +1,7 @@ -package com.vanced.manager.ui.fragments +package com.vanced.manager.ui.dialogs import android.content.Context +import android.content.DialogInterface import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -8,28 +9,28 @@ import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.widget.LinearLayout +import android.widget.Toast import androidx.core.content.res.ResourcesCompat -import androidx.fragment.app.Fragment -import androidx.navigation.findNavController +import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.button.MaterialButton import com.google.android.material.checkbox.MaterialCheckBox import com.vanced.manager.R import com.vanced.manager.core.App -import com.vanced.manager.core.downloader.VancedDownloader.downloadVanced +import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.* -class VancedLanguageSelectionFragment : Fragment() { +class VancedLanguageSelectionDialog : BottomSheetDialogFragment() { private lateinit var langs: MutableList + private val prefs by lazy { requireActivity().getSharedPreferences("installPrefs", Context.MODE_PRIVATE) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - activity?.title = getString(R.string.install) return inflater.inflate(R.layout.fragment_vanced_language_selection, container, false) } @@ -40,33 +41,35 @@ class VancedLanguageSelectionFragment : Fragment() { langs = app.vanced.get()?.array("langs")?.value ?: mutableListOf("null") loadBoxes(view.findViewById(R.id.lang_button_ll)) view.findViewById(R.id.vanced_install_finish).setOnClickListener { - val chosenLangs = mutableListOf("en") + val chosenLangs = mutableListOf() if (!langs.contains("null")) langs.forEach { lang -> if (view.findViewWithTag(lang).isChecked) { chosenLangs.add(lang) } } - with(requireActivity()) { - getSharedPreferences("installPrefs", Context.MODE_PRIVATE)?.edit()?.apply { - putString("lang", chosenLangs.joinToString())?.apply() - putBoolean("valuesModified", true).apply() - } - downloadVanced(requireActivity()) + + if (chosenLangs.isEmpty()) { + Toast.makeText(requireActivity(), R.string.select_at_least_one_lang, Toast.LENGTH_SHORT).show() + return@setOnClickListener } - view.findNavController().navigate(R.id.action_installTo_homeFragment) + + prefs?.edit()?.putString("lang", chosenLangs.joinToString())?.apply() + dismiss() } } @ExperimentalStdlibApi private fun loadBoxes(ll: LinearLayout) { CoroutineScope(Dispatchers.Main).launch { - if (this@VancedLanguageSelectionFragment::langs.isInitialized) { + val langPrefs = prefs.getString("lang", getDefaultVancedLanguages(requireActivity())) + if (this@VancedLanguageSelectionDialog::langs.isInitialized) { if (!langs.contains("null")) { langs.forEach { lang -> val loc = Locale(lang) val box: MaterialCheckBox = MaterialCheckBox(requireActivity()).apply { tag = lang + isChecked = langPrefs!!.contains(lang) text = loc.getDisplayLanguage(loc).capitalize(Locale.ROOT) textSize = 18F typeface = ResourcesCompat.getFont(requireActivity(), R.font.exo_bold) @@ -79,4 +82,9 @@ class VancedLanguageSelectionFragment : Fragment() { } } + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + VancedPreferencesDialog().show(requireActivity().supportFragmentManager, "") + } + } diff --git a/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt new file mode 100644 index 00000000..2f2397cc --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/dialogs/VancedPreferencesDialog.kt @@ -0,0 +1,82 @@ +package com.vanced.manager.ui.dialogs + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.AdapterView.OnItemSelectedListener +import androidx.databinding.DataBindingUtil +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.vanced.manager.R +import com.vanced.manager.adapter.VancedPrefArray +import com.vanced.manager.databinding.DialogInstallationPreferencesBinding +import com.vanced.manager.model.VancedPrefModel +import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages +import java.util.* + +class VancedPreferencesDialog : BottomSheetDialogFragment() { + + private lateinit var binding: DialogInstallationPreferencesBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.dialog_installation_preferences, container, false) + return binding.root + } + + @ExperimentalStdlibApi + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val prefs = requireActivity().getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + val langPrefs = prefs.getString("lang", getDefaultVancedLanguages(requireActivity()))?.split(", ")?.toTypedArray() + val showLang = mutableListOf() + if (langPrefs != null) { + for (lang in langPrefs) { + val loc = Locale(lang) + showLang.add(loc.getDisplayLanguage(loc).capitalize(Locale.ROOT)) + } + } + + val darkTheme = VancedPrefModel( + requireActivity().getString(R.string.install_light_dark), + "dark" + ) + + val blackTheme = VancedPrefModel( + requireActivity().getString(R.string.install_light_black), + "black" + ) + + val adapter = arrayOf(darkTheme, blackTheme) + binding.themeSpinner.adapter = VancedPrefArray(requireActivity(), android.R.layout.simple_spinner_dropdown_item, adapter) + binding.themeSpinner.setSelection(if (prefs.getString("theme", "dark") == "dark") 0 else 1) + + binding.openLanguageSelector.setOnClickListener { + dismiss() + VancedLanguageSelectionDialog().show(requireActivity().supportFragmentManager, "") + } + + binding.chosenLang.text = requireActivity().getString(R.string.chosen_lang, showLang) + + binding.themeSpinner.onItemSelectedListener = object : OnItemSelectedListener { + + override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { + prefs.edit().putString("theme", adapter[position].value).apply() + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + return + } + } + + binding.chosenPrefsInstall.setOnClickListener { + dismiss() + AppDownloadDialog(requireActivity().getString(R.string.vanced)).show(requireActivity().supportFragmentManager, "InstallVanced") + } + } +} diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/ChosenPreferenceDialogFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/ChosenPreferenceDialogFragment.kt deleted file mode 100644 index 7eeab6f3..00000000 --- a/app/src/main/java/com/vanced/manager/ui/fragments/ChosenPreferenceDialogFragment.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.vanced.manager.ui.fragments - -import android.content.Context -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.content.edit -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.DialogFragment -import com.vanced.manager.R -import com.vanced.manager.databinding.FragmentChosenPreferencesBinding -import java.util.* - -class ChosenPreferenceDialogFragment : DialogFragment() { - - private lateinit var binding: FragmentChosenPreferencesBinding - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - dialog?.window?.apply { setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) } - binding = DataBindingUtil.inflate(inflater, R.layout.fragment_chosen_preferences, container, false) - return binding.root - } - - @ExperimentalStdlibApi - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val prefs = requireActivity().getSharedPreferences("installPrefs", Context.MODE_PRIVATE) - val langPrefs = prefs.getString("lang", "en")?.split(", ")?.toTypedArray() - val newPrefs = mutableListOf() - if (langPrefs != null) { - for (lang in langPrefs) { - val loc = Locale(lang) - newPrefs.add(loc.getDisplayLanguage(loc).capitalize(Locale.ROOT)) - } - } - - - - binding.chosenTheme.text = requireActivity().getString(R.string.chosen_theme, prefs.getString("theme", "dark")?.capitalize(Locale.ROOT)) - binding.chosenLang.text = requireActivity().getString(R.string.chosen_lang, newPrefs.joinToString()) - - binding.chosenPrefsClose.setOnClickListener { dismiss() } - binding.chosenPrefsReset.setOnClickListener { - prefs.edit { - putString("theme", "dark") - putString("lang", "en") - putBoolean("valuesModified", false) - } - dismiss() - } - } -} diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/DevSettingsFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/DevSettingsFragment.kt index 3d90d34f..5cc26f52 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/DevSettingsFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/DevSettingsFragment.kt @@ -8,38 +8,40 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import com.vanced.manager.R -import com.vanced.manager.ui.MainActivity -import com.vanced.manager.utils.DownloadHelper.downloadManager +import com.vanced.manager.ui.WelcomeActivity +import com.vanced.manager.ui.dialogs.ManagerUpdateDialog +import com.vanced.manager.ui.dialogs.URLChangeDialog class DevSettingsFragment: PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.dev_settings, rootKey) - val ftSwitch: Preference? = findPreference("firststart_switch") + val ftSwitch: Preference? = findPreference("firstlaunch_switch") val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext()) ftSwitch?.setOnPreferenceClickListener { AlertDialog.Builder(requireContext()) - .setTitle("FirstStart activated") + .setTitle("FirstLaunch activated") .setMessage("boolean will be activated on next app start") .setPositiveButton("Restart") { _, _ -> run { - startActivity(Intent(requireContext(), MainActivity::class.java)) + startActivity(Intent(requireContext(), WelcomeActivity::class.java)) activity?.finish() } } .create() .show() - prefs.edit().putBoolean("firstStart", true).apply() + prefs.edit().putBoolean("firstLaunch", true).apply() + prefs.edit().putBoolean("show_changelog_tooltip", true).apply() true } findPreference("install_url")?.setOnPreferenceClickListener { - URLChangeFragment().show(childFragmentManager.beginTransaction(), "Install URL") + URLChangeDialog().show(childFragmentManager.beginTransaction(), "Install URL") true } @@ -56,7 +58,7 @@ class DevSettingsFragment: PreferenceFragmentCompat() { val forceUpdate: Preference? = findPreference("force_update") forceUpdate?.setOnPreferenceClickListener { - downloadManager(true, requireActivity()) + ManagerUpdateDialog(true).show(requireActivity().supportFragmentManager, "update_manager") true } diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/GrantRootFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/GrantRootFragment.kt new file mode 100644 index 00000000..ae7e03f3 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/fragments/GrantRootFragment.kt @@ -0,0 +1,53 @@ +package com.vanced.manager.ui.fragments + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.topjohnwu.superuser.Shell +import com.vanced.manager.R +import com.vanced.manager.databinding.FragmentGrantRootBinding +import com.vanced.manager.ui.MainActivity + +class GrantRootFragment : Fragment(), View.OnClickListener { + + private lateinit var binding: FragmentGrantRootBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_grant_root, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.grantRootFinishFab.setOnClickListener(this) + binding.grantRootFab.setOnClickListener(this) + } + + override fun onClick(v: View?) { + when (v?.id) { + R.id.grant_root_fab -> { + if (Shell.rootAccess()) { + getDefaultSharedPreferences(requireActivity()).edit().putString("vanced_variant", "root").apply() + } else { + Toast.makeText(requireActivity(), R.string.root_not_granted, Toast.LENGTH_SHORT).show() + } + } + R.id.grant_root_finish_fab -> { + val intent = Intent(requireActivity(), MainActivity::class.java) + intent.putExtra("firstLaunch", true) + startActivity(intent) + requireActivity().finish() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/HomeFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/HomeFragment.kt index 66f0ac11..4662d84a 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/HomeFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/HomeFragment.kt @@ -6,24 +6,25 @@ import android.content.Intent import android.content.IntentFilter import android.os.Bundle import android.view.* -import android.view.animation.AnimationUtils -import android.widget.Toast +import androidx.core.content.res.ResourcesCompat import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.navigation.findNavController -import androidx.preference.PreferenceManager.getDefaultSharedPreferences -import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayoutMediator -import com.topjohnwu.superuser.Shell +import androidx.preference.PreferenceManager +import androidx.recyclerview.widget.LinearLayoutManager +import com.github.florent37.viewtooltip.ViewTooltip +import com.google.android.flexbox.FlexboxLayoutManager +import com.google.android.flexbox.JustifyContent import com.vanced.manager.R -import com.vanced.manager.adapter.VariantAdapter +import com.vanced.manager.adapter.AppListAdapter +import com.vanced.manager.adapter.LinkAdapter +import com.vanced.manager.adapter.SponsorAdapter import com.vanced.manager.databinding.FragmentHomeBinding import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder import com.vanced.manager.ui.viewmodels.HomeViewModel import com.vanced.manager.ui.viewmodels.HomeViewModelFactory -import com.vanced.manager.utils.AppUtils.installing open class HomeFragment : Fragment() { @@ -32,26 +33,28 @@ open class HomeFragment : Fragment() { HomeViewModelFactory(requireActivity()) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) } + private val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(requireActivity()) } + private lateinit var tooltip: ViewTooltip - private val tabListener = object : TabLayout.OnTabSelectedListener { - - override fun onTabSelected(tab: TabLayout.Tab) { - if (tab.position == 1 && !Shell.rootAccess()) { - Toast.makeText(requireActivity(), getString(R.string.root_not_granted), Toast.LENGTH_SHORT).show() - } - val variant = if (tab.position == 1) "root" else "nonroot" - getDefaultSharedPreferences(requireActivity()).edit().putString("vanced_variant", variant).apply() - } - - override fun onTabUnselected(tab: TabLayout.Tab) { - return - } - - override fun onTabReselected(tab: TabLayout.Tab) { - return - } - - } +// private val tabListener = object : TabLayout.OnTabSelectedListener { +// +// override fun onTabSelected(tab: TabLayout.Tab) { +// if (tab.position == 1 && !Shell.rootAccess()) { +// Toast.makeText(requireActivity(), getString(R.string.root_not_granted), Toast.LENGTH_SHORT).show() +// } +// val variant = if (tab.position == 1) "root" else "nonroot" +// getDefaultSharedPreferences(requireActivity()).edit().putString("vanced_variant", variant).apply() +// } +// +// override fun onTabUnselected(tab: TabLayout.Tab) { +// return +// } +// +// override fun onTabReselected(tab: TabLayout.Tab) { +// return +// } +// +// } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -67,36 +70,79 @@ open class HomeFragment : Fragment() { super.onViewCreated(view, savedInstanceState) viewModel.navigateDestination.observe(viewLifecycleOwner, { val content = it.getContentIfNotHandled() - if(content != null){ + if (content != null){ view.findNavController().navigate(content) } }) with(binding) { - mainViewpager.adapter = VariantAdapter(viewModel, requireActivity()) - TabLayoutMediator(mainTablayout, mainViewpager) { tab, position -> - val variants = arrayOf("nonroot", "root") - tab.text = variants[position] - }.attach() - mainTablayout.getTabAt(if (getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot") == "root") 1 else 0)?.select() + viewModel = this@HomeFragment.viewModel + + tooltip = ViewTooltip + .on(recyclerAppList) + .position(ViewTooltip.Position.TOP) + .autoHide(false, 0) + .color(ResourcesCompat.getColor(requireActivity().resources, R.color.Twitter, null)) + .withShadow(false) + .corner(25) + .onHide { + prefs.edit().putBoolean("show_changelog_tooltip", false).apply() + } + .text(requireActivity().getString(R.string.app_changelog_tooltip)) + + if (prefs.getBoolean("show_changelog_tooltip", true)) { + tooltip.show() + } + + recyclerAppList.apply { + layoutManager = LinearLayoutManager(requireActivity()) + adapter = AppListAdapter(requireActivity(), this@HomeFragment.viewModel, tooltip) + setHasFixedSize(true) + } + + recyclerSponsors.apply { + val lm = FlexboxLayoutManager(requireActivity()) + lm.justifyContent = JustifyContent.SPACE_EVENLY + layoutManager = lm + setHasFixedSize(true) + adapter = SponsorAdapter(requireActivity(), this@HomeFragment.viewModel) + } + + recyclerLinks.apply { + val lm = FlexboxLayoutManager(requireActivity()) + lm.justifyContent = JustifyContent.SPACE_EVENLY + layoutManager = lm + setHasFixedSize(true) + adapter = LinkAdapter(requireActivity(), this@HomeFragment.viewModel) + } } - installing.observe(viewLifecycleOwner, { value -> - if (value) hideTab() else showTab() - }) +// with(binding) { +// mainViewpager.adapter = VariantAdapter(viewModel, requireActivity()) +// TabLayoutMediator(mainTablayout, mainViewpager) { tab, position -> +// val variants = arrayOf("nonroot", "root") +// tab.text = variants[position] +// }.attach() +// mainTablayout.getTabAt(if (getDefaultSharedPreferences(requireActivity()).getString("vanced_variant", "nonroot") == "root") 1 else 0)?.select() +// } + +// installing.observe(viewLifecycleOwner, { value -> +// if (value) hideTab() else showTab() +// }) } override fun onPause() { super.onPause() localBroadcastManager.unregisterReceiver(broadcastReceiver) - binding.mainTablayout.removeOnTabSelectedListener(tabListener) + tooltip.close() + //binding.mainTablayout.removeOnTabSelectedListener(tabListener) } override fun onResume() { super.onResume() registerReceivers() - binding.mainTablayout.addOnTabSelectedListener(tabListener) + // binding.mainTablayout.addOnTabSelectedListener(tabListener) } private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { @@ -108,27 +154,27 @@ open class HomeFragment : Fragment() { } } - private fun hideTab() { - val tabHide = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_exit) - with(binding) { - if (mainTablayout.visibility != View.GONE) { - mainTablayout.startAnimation(tabHide) - mainTablayout.visibility = View.GONE - } - mainViewpager.isUserInputEnabled = false - } - } - - private fun showTab() { - val tabShow = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_enter) - with(binding) { - if (mainTablayout.visibility != View.VISIBLE) { - mainTablayout.visibility = View.VISIBLE - mainTablayout.startAnimation(tabShow) - } - mainViewpager.isUserInputEnabled = true - } - } +// private fun hideTab() { +// val tabHide = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_exit) +// with(binding) { +// if (mainTablayout.visibility != View.GONE) { +// mainTablayout.startAnimation(tabHide) +// mainTablayout.visibility = View.GONE +// } +// mainViewpager.isUserInputEnabled = false +// } +// } +// +// private fun showTab() { +// val tabShow = AnimationUtils.loadAnimation(requireActivity(), R.anim.tablayout_enter) +// with(binding) { +// if (mainTablayout.visibility != View.VISIBLE) { +// mainTablayout.visibility = View.VISIBLE +// mainTablayout.startAnimation(tabShow) +// } +// mainViewpager.isUserInputEnabled = true +// } +// } private fun registerReceivers() { val intentFilter = IntentFilter() diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/SelectAppsFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/SelectAppsFragment.kt new file mode 100644 index 00000000..66c2f616 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/ui/fragments/SelectAppsFragment.kt @@ -0,0 +1,53 @@ +package com.vanced.manager.ui.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.recyclerview.widget.LinearLayoutManager +import com.vanced.manager.R +import com.vanced.manager.adapter.SelectAppsAdapter +import com.vanced.manager.databinding.FragmentSelectAppsBinding + +class SelectAppsFragment : Fragment() { + + private lateinit var binding: FragmentSelectAppsBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_select_apps, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val selectAdapter = SelectAppsAdapter(requireActivity()) + val prefs = getDefaultSharedPreferences(requireActivity()) + binding.selectAppsRecycler.apply { + layoutManager = LinearLayoutManager(requireActivity()) + setHasFixedSize(true) + adapter = selectAdapter + } + + binding.selectAppsFab.setOnClickListener { + if (selectAdapter.apps.all { app -> !app.isChecked }) { + Toast.makeText(requireActivity(), R.string.select_at_least_one_app, Toast.LENGTH_SHORT).show() + return@setOnClickListener + } + + selectAdapter.apps.forEach { app -> + prefs.edit().putBoolean("enable_${app.tag}", app.isChecked).apply() + } + + findNavController().navigate(SelectAppsFragmentDirections.selectAppsToGrantRoot()) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt index 95493daa..8e1240d6 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/SettingsFragment.kt @@ -1,134 +1,113 @@ package com.vanced.manager.ui.fragments import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater +import android.view.* import android.widget.Toast -import androidx.preference.* +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import androidx.recyclerview.widget.LinearLayoutManager import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.crashlytics.FirebaseCrashlytics -import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.perf.FirebasePerformance -import com.vanced.manager.BuildConfig.MANAGER_LANGUAGES -import com.vanced.manager.BuildConfig.MANAGER_LANGUAGE_NAMES import com.vanced.manager.R +import com.vanced.manager.adapter.GetNotifAdapter +import com.vanced.manager.databinding.FragmentSettingsBinding +import com.vanced.manager.ui.dialogs.* import com.vanced.manager.utils.LanguageHelper.getLanguageFormat import java.io.File -class SettingsFragment : PreferenceFragmentCompat() { +class SettingsFragment : Fragment() { - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.preferences, rootKey) + private lateinit var binding: FragmentSettingsBinding + private val prefs by lazy { getDefaultSharedPreferences(requireActivity()) } - activity?.title = getString(R.string.title_settings) + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { setHasOptionsMenu(true) + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_settings, container, false) + return binding.root + } - findPreference("update_check")?.setOnPreferenceClickListener { - UpdateCheckFragment().show(childFragmentManager.beginTransaction(), "Update Center") - true + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.notificationsRecycler.apply { + layoutManager = LinearLayoutManager(requireActivity()) + adapter = GetNotifAdapter(requireActivity()) } - findPreference("vanced_notifs")?.apply { - title = getString(R.string.push_notifications, "Vanced") - summary = getString(R.string.push_notifications_summary, "Vanced") - setOnPreferenceChangeListener { _, newValue -> - when (newValue) { - true -> FirebaseMessaging.getInstance().subscribeToTopic("Vanced-Update") - false -> FirebaseMessaging.getInstance().unsubscribeFromTopic("Vanced-Update") - } - true + binding.firebase.setOnCheckedListener { _, isChecked -> + FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(isChecked) + FirebasePerformance.getInstance().isPerformanceCollectionEnabled = isChecked + FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(isChecked) + } + + binding.managerVariant.apply { + prefs.getString("vanced_variant", "nonrooot")?.let { setSummary(it) } + setOnClickListener { + ManagerVariantDialog().show(requireActivity().supportFragmentManager, "") } } - findPreference("microg_notifs")?.apply { - title = getString(R.string.push_notifications, "microG") - summary = getString(R.string.push_notifications_summary, "microG") - setOnPreferenceChangeListener { _, newValue -> - when (newValue) { - true -> FirebaseMessaging.getInstance().subscribeToTopic("MicroG-Update") - false -> FirebaseMessaging.getInstance().unsubscribeFromTopic("MicroG-Update") - } - true - } - } - - findPreference("firebase_analytics")?.setOnPreferenceChangeListener { _, newValue -> - FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(newValue as Boolean) - FirebasePerformance.getInstance().isPerformanceCollectionEnabled = newValue - FirebaseAnalytics.getInstance(requireActivity()).setAnalyticsCollectionEnabled(newValue) - true - } - - val themePref = preferenceScreen.sharedPreferences.getString("theme_mode", "Follow System") - findPreference("theme_mode")?.apply { - summary = when (themePref) { - "Light" -> getString(R.string.theme_light) - "Dark" -> getString(R.string.theme_dark) - else -> getString(R.string.theme_follow) - } - - setOnPreferenceChangeListener { _, newValue -> - if (themePref != newValue) { - requireActivity().recreate() - return@setOnPreferenceChangeListener true - } - false - } - } - - val accentPref = preferenceScreen.sharedPreferences.getString("accent_color", "Blue") - findPreference("accent_color")?.apply { - summary = when (accentPref) { - "Blue" -> getString(R.string.accent_blue) - "Red" -> getString(R.string.accent_red) - "Green" -> getString(R.string.accent_green) - "Yellow" -> getString(R.string.accent_yellow) - else -> getString(R.string.accent_purple) - } - - setOnPreferenceChangeListener { _, newValue -> - if (accentPref != newValue) { - requireActivity().recreate() - return@setOnPreferenceChangeListener true - } - false - } - } - - val langPref = preferenceScreen.sharedPreferences.getString("manager_lang", "System Default") - preferenceScreen.findPreference("manager_lang")?.apply { - summary = langPref?.let { getLanguageFormat(requireActivity(), it) } - entries = arrayOf(getString(R.string.system_default)) + MANAGER_LANGUAGE_NAMES - entryValues = arrayOf("System Default") + MANAGER_LANGUAGES - - setOnPreferenceChangeListener { _, newValue -> - if (langPref != newValue) { - requireActivity().recreate() - return@setOnPreferenceChangeListener true - } - false - } - } - - findPreference("vanced_chosen_modes")?.setOnPreferenceClickListener { - ChosenPreferenceDialogFragment().show(childFragmentManager.beginTransaction(), "Chosen Preferences") - true - } - - findPreference("clear_files")?.setOnPreferenceClickListener { + binding.clearFiles.setOnClickListener { with(requireActivity()) { listOf("apk", "apks").forEach { dir -> File(getExternalFilesDir(dir)?.path as String).deleteRecursively() } Toast.makeText(this, getString(R.string.cleared_files), Toast.LENGTH_SHORT).show() } - true + } + + val themePref = prefs.getString("manager_theme", "System Default") + binding.managerTheme.apply { + setSummary( + when (themePref) { + "Light" -> getString(R.string.theme_light) + "Dark" -> getString(R.string.theme_dark) + else -> getString(R.string.system_default) + } + ) + setOnClickListener { + ManagerThemeDialog().show(requireActivity().supportFragmentManager, "") + } + } + + val accentPref = prefs.getString("manager_accent", "Blue") + binding.managerAccentColor.apply { + setSummary( + when (accentPref) { + "Blue" -> getString(R.string.accent_blue) + "Red" -> getString(R.string.accent_red) + "Green" -> getString(R.string.accent_green) + "Yellow" -> getString(R.string.accent_yellow) + else -> getString(R.string.accent_purple) + } + ) + setOnClickListener { + ManagerAccentColorDialog().show(requireActivity().supportFragmentManager, "") + } + } + + val langPref = prefs.getString("manager_lang", "System Default") + binding.managerLanguage.apply { + setSummary(getLanguageFormat(requireActivity(), langPref!!)) + setOnClickListener { + ManagerLanguageDialog().show(requireActivity().supportFragmentManager, "") + } + } + + binding.selectApps.setOnClickListener { + SelectAppsDialog().show(requireActivity().supportFragmentManager, "") } } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - val devSettings = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("devSettings", false) + val devSettings = getDefaultSharedPreferences(requireActivity()).getBoolean("devSettings", false) if (devSettings) { inflater.inflate(R.menu.dev_settings_menu, menu) } diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/UpdateCheckFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/UpdateCheckFragment.kt deleted file mode 100644 index 0ddc5905..00000000 --- a/app/src/main/java/com/vanced/manager/ui/fragments/UpdateCheckFragment.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.vanced.manager.ui.fragments - -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.TextView -import androidx.fragment.app.DialogFragment -import com.google.android.material.button.MaterialButton -import com.vanced.manager.R -import com.vanced.manager.utils.DownloadHelper.downloadManager -import com.vanced.manager.utils.InternetTools.isUpdateAvailable - -class UpdateCheckFragment : DialogFragment() { - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - if (dialog != null && dialog?.window != null) { - dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - } - return inflater.inflate(R.layout.fragment_update_check, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - checkUpdates() - view.findViewById