From 709b32fd757429ec15930603684b2790c4a18c7d Mon Sep 17 00:00:00 2001 From: jlplks Date: Wed, 20 Nov 2024 15:17:58 -0700 Subject: [PATCH] MBL-1739: Support Android 15 (#2143) * MLB-1740: Fix Circle CI Pipeline to work with sdk 35 (Android 15) (#2141) * Android sdk 35 - Change compile and target SDK to version 35 - change tag for CircleCI from 2024.01.1 to 2024.09.1 * downgrade tag to 2024.08.1 * 2024.07.1 * update gradle version * add JDK_VERSION to executor environment * UPGRADE VERSIONS Kotlin version from 1.8.10 1.8.22 Jacoco_version from 0.8.8 to 0.8.11 compose version from 1.4.3 to 1.4.8 setted java 17 on the circle ci environment * add validate java version on circle ci pipeline * force java 17 on circle ci * fix typo * explicity install java 17 * specify jvm 17 on gradle * force assembleExternalRelease to use java 17 * Fix lint external release * change name of intent on ThreadView model Changed the name for function intent and PublishSubject intent so it be more clear to read * code more clean * fix ktlint * MBL-1673 [Android 15] Update Views to be compatible with edge to edge enforcement (#2131) * Manage edge to edege - Created utility to manage edge to edge on different screens - fixed composable screens - fixed other screens with the utility * Manage edge to edge in all the screens - Manage edge to edge behavior for all the screens - modify solution * Fix last screens * Fix ktlint tests * fix KTLint * Fix test againt * MBL-1825 Fix 'Back this project' component on Project activity (UI) (#2159) * Fix pledge_container UI height bug on android 15 * fix ktlint * set fitsSystemWindows to false on AppBarLayout on activity_proyect_page * set fitsystemwinfows false * fix thread * fix comments threads --------- Co-authored-by: Isabel Martin --- .circleci/config.yml | 30 +- app/build.gradle | 5 +- .../libs/loadmore/ApolloPaginateV2.kt | 1 - .../ui/activities/AccountActivity.kt | 88 ++- .../ui/activities/ActivityFeedActivity.kt | 13 +- .../ui/activities/ChangeEmailActivity.kt | 21 +- .../ui/activities/CommentsActivity.kt | 6 + .../ui/activities/CreatorBioActivity.kt | 6 +- .../ui/activities/DiscoveryActivity.kt | 19 +- .../ui/activities/EditProfileActivity.kt | 11 +- .../ui/activities/EditorialActivity.kt | 6 +- .../FacebookConfirmationActivity.kt | 16 +- .../kickstarter/ui/activities/HelpActivity.kt | 14 +- .../ui/activities/HelpSettingsActivity.kt | 6 + .../ui/activities/MessageCreatorActivity.kt | 6 +- .../ui/activities/MessageThreadsActivity.kt | 6 +- .../ui/activities/MessagesActivity.kt | 5 + .../ui/activities/NewsletterActivity.kt | 88 ++- .../ui/activities/NotificationsActivity.kt | 102 ++- .../PaymentMethodsSettingsActivity.kt | 5 + .../ui/activities/PrivacyActivity.kt | 5 + .../ui/activities/ProfileActivity.kt | 11 +- .../ProjectNotificationSettingsActivity.kt | 6 + .../ui/activities/ProjectPageActivity.kt | 238 +++++-- .../ui/activities/ProjectSocialActivity.kt | 5 + .../ui/activities/ProjectUpdatesActivity.kt | 5 + .../ui/activities/ReportProjectActivity.kt | 3 + .../ui/activities/SetPasswordActivity.kt | 1 + .../ui/activities/SettingsActivity.kt | 5 + .../ui/activities/SurveyResponseActivity.kt | 5 + .../ui/activities/ThanksActivity.kt | 5 + .../ui/activities/ThreadActivity.kt | 5 + .../ui/activities/UpdateActivity.kt | 6 +- .../ui/activities/VideoActivity.kt | 5 + .../ui/activities/WebViewActivity.kt | 5 + .../compose/ChangePasswordScreen.kt | 2 + .../ui/activities/compose/FormularyScreen.kt | 2 + .../compose/PreLaunchProjectPageScreen.kt | 2 + .../activities/compose/ReportProjectScreen.kt | 110 ++- .../compose/login/CreatePasswordScreen.kt | 2 + .../compose/login/LoginToutScreen.kt | 2 + .../compose/login/ResetPasswordScreen.kt | 2 + .../compose/login/SetPasswordScreen.kt | 2 + .../compose/projectpage/AddOnsScreen.kt | 5 +- .../compose/projectpage/AiDisclosureScreen.kt | 2 + .../compose/projectpage/CheckoutScreen.kt | 2 + ...ProjectPledgeButtonAndFragmentContainer.kt | 5 +- .../projectpage/RewardCarouselScreen.kt | 5 +- .../activities/compose/search/SearchScreen.kt | 2 + .../ui/toolbars/compose/ToolBar.kt | 1 + .../com/kickstarter/utils/WindowInsetsUtil.kt | 54 ++ .../kickstarter/viewmodels/ThreadViewModel.kt | 2 +- app/src/main/res/layout/activity_account.xml | 5 +- .../main/res/layout/activity_edit_profile.xml | 437 ++++++------ .../main/res/layout/activity_feed_layout.xml | 40 +- .../main/res/layout/activity_feed_toolbar.xml | 35 +- .../res/layout/activity_help_settings.xml | 6 +- .../main/res/layout/activity_newsletter.xml | 441 ++++++------ .../res/layout/activity_notifications.xml | 663 +++++++++--------- .../main/res/layout/activity_project_page.xml | 10 +- app/src/main/res/layout/discovery_layout.xml | 3 +- app/src/main/res/layout/help_layout.xml | 26 +- app/src/main/res/layout/pledge_container.xml | 2 +- app/src/main/res/layout/profile_layout.xml | 230 +++--- .../project_notification_settings_layout.xml | 32 +- app/src/main/res/layout/settings_layout.xml | 6 +- .../viewmodels/ThreadViewModelTest.kt | 8 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 68 files changed, 1759 insertions(+), 1153 deletions(-) create mode 100644 app/src/main/java/com/kickstarter/utils/WindowInsetsUtil.kt diff --git a/.circleci/config.yml b/.circleci/config.yml index 18da278292..3e5a150864 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ base_job: &base_job executor: name: android/android-machine resource-class: xlarge - tag: 2024.01.1 #https://circleci.com/developer/images/image/cimg/android + tag: 2024.07.1 #https://circleci.com/developer/images/image/cimg/android working_directory: "~/project" environment: TERM: dumb @@ -27,13 +27,17 @@ jobs: - v5-android-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} - v5-android- - run: make bootstrap-circle - - run: ./gradlew dependencies + - run: + name: Install dependencies + command: ./gradlew dependencies - save_cache: key: v5-android-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} paths: - ~/.gradle - ~/.android - - run: ./gradlew assembleExternalRelease + - run: + name: Assemble Release + command: ./gradlew assembleExternalRelease -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 - persist_to_workspace: root: ~/project paths: @@ -49,11 +53,19 @@ jobs: - v5-android- - attach_workspace: at: ~/project - - run: ./gradlew checkstyle - - run: ./gradlew ktlint - - run: ./gradlew lintExternalRelease - run: - command: ./gradlew jacocoExternalDebugReport -PdisablePreDex + name: Check Style + command: ./gradlew checkstyle + - run: + name: KTLint + command: ./gradlew ktlint + + - run: + name: Lint External Release + command: ./gradlew lintExternalRelease -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 + - run: + name: Jacoco External Debug Report + command: ./gradlew jacocoExternalDebugReport -PdisablePreDex -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 no_output_timeout: 30m - store_artifacts: path: app/build/reports @@ -94,7 +106,9 @@ jobs: name: Config Emulator for Screenshot test command: ./script/emulator/screenshot_config_emulator.sh # Temporary JDK 17 workaround https://github.com/pedrovgs/Shot/issues/268 until https://github.com/pedrovgs/Shot/pull/292 is merged - - run: ./gradlew internalDebugExecuteScreenshotTests -Dorg.gradle.jvmargs="--add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED" + - run: + name: Internal Debug Execute Screenshot Tests + command: ./gradlew internalDebugExecuteScreenshotTests -Dorg.gradle.jvmargs="--add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED" -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 - android/save-gradle-cache: cache-prefix: v1a - store_artifacts: diff --git a/app/build.gradle b/app/build.gradle index 3debf57c1f..266f2c73be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,10 +52,10 @@ if (file('signing.gradle').exists()) { android { defaultConfig { - compileSdk 34 + compileSdk = 35 applicationId "com.kickstarter" minSdkVersion 24 - targetSdkVersion 34 + targetSdk = 35 testApplicationId "com.kickstarter.internal.debug.test" testInstrumentationRunner "com.kickstarter.screenshoot.testing.KSScreenShotTestRunner" @@ -198,6 +198,7 @@ repositories { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'androidx.core:core-ktx:1.13.1' implementation 'androidx.annotation:annotation:1.3.0' implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.cardview:cardview:1.0.0' diff --git a/app/src/main/java/com/kickstarter/libs/loadmore/ApolloPaginateV2.kt b/app/src/main/java/com/kickstarter/libs/loadmore/ApolloPaginateV2.kt index 3c578c17db..c1833715df 100644 --- a/app/src/main/java/com/kickstarter/libs/loadmore/ApolloPaginateV2.kt +++ b/app/src/main/java/com/kickstarter/libs/loadmore/ApolloPaginateV2.kt @@ -9,7 +9,6 @@ import io.reactivex.functions.Function import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.PublishSubject import java.net.MalformedURLException -import java.util.ArrayList class ApolloPaginateV2( val nextPage: Observable, diff --git a/app/src/main/java/com/kickstarter/ui/activities/AccountActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/AccountActivity.kt index 15e9d5a131..3c7666e553 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/AccountActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/AccountActivity.kt @@ -17,6 +17,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.getPaymentMethodsIntent import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.AccountViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -59,7 +60,6 @@ class AccountActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - disposables = CompositeDisposable() val env = this.getEnvironment()?.let { env -> @@ -68,7 +68,10 @@ class AccountActivity : AppCompatActivity() { } binding = ActivityAccountBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) @@ -84,7 +87,11 @@ class AccountActivity : AppCompatActivity() { this.viewModel.outputs.email() .observeOn(AndroidSchedulers.mainThread()) .subscribe { - binding.createPasswordTextView.text = this.ksString.format(getString(R.string.Youre_connected_via_Facebook_email_Create_a_password_for_this_account), "email", it) + binding.createPasswordTextView.text = this.ksString.format( + getString(R.string.Youre_connected_via_Facebook_email_Create_a_password_for_this_account), + "email", + it + ) } .addToDisposable(disposables) @@ -113,14 +120,53 @@ class AccountActivity : AppCompatActivity() { this.viewModel.outputs.success() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { showSnackbar(binding.accountContainer, R.string.Got_it_your_changes_have_been_saved) } + .subscribe { + showSnackbar( + binding.accountContainer, + R.string.Got_it_your_changes_have_been_saved + ) + } .addToDisposable(disposables) - binding.createPasswordRow.setOnClickListener { startActivity(Intent(this, CreatePasswordActivity::class.java)) } - binding.changeEmailRow.setOnClickListener { startActivity(Intent(this, ChangeEmailActivity::class.java)) } - binding.changePasswordRow.setOnClickListener { startActivity(Intent(this, ChangePasswordActivity::class.java)) } - binding.paymentMethodsRow.setOnClickListener { startActivity(Intent().getPaymentMethodsIntent(this)) } - binding.privacyRow.setOnClickListener { startActivity(Intent(this, PrivacyActivity::class.java)) } + binding.createPasswordRow.setOnClickListener { + startActivity( + Intent( + this, + CreatePasswordActivity::class.java + ) + ) + } + binding.changeEmailRow.setOnClickListener { + startActivity( + Intent( + this, + ChangeEmailActivity::class.java + ) + ) + } + binding.changePasswordRow.setOnClickListener { + startActivity( + Intent( + this, + ChangePasswordActivity::class.java + ) + ) + } + binding.paymentMethodsRow.setOnClickListener { + startActivity( + Intent().getPaymentMethodsIntent( + this + ) + ) + } + binding.privacyRow.setOnClickListener { + startActivity( + Intent( + this, + PrivacyActivity::class.java + ) + ) + } } override fun onDestroy() { @@ -186,17 +232,23 @@ class AccountActivity : AppCompatActivity() { arrayAdapter.setDropDownViewResource(R.layout.item_spinner_dropdown) binding.currencySpinner.adapter = arrayAdapter - binding.currencySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onNothingSelected(parent: AdapterView<*>?) {} - - override fun onItemSelected(parent: AdapterView<*>?, view: View?, postion: Int, id: Long) { - currentCurrencySelection?.let { - if (supportedCurrencies.indexOf(it) != postion) { - newCurrencySelection = supportedCurrencies[postion] - lazyFollowingOptOutConfirmationDialog().show() + binding.currencySpinner.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) {} + + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + postion: Int, + id: Long + ) { + currentCurrencySelection?.let { + if (supportedCurrencies.indexOf(it) != postion) { + newCurrencySelection = supportedCurrencies[postion] + lazyFollowingOptOutConfirmationDialog().show() + } } } } - } } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/ActivityFeedActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ActivityFeedActivity.kt index c520894322..8e7c76d802 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ActivityFeedActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ActivityFeedActivity.kt @@ -26,6 +26,7 @@ import com.kickstarter.ui.data.LoginReason import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.startActivityWithTransition +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ActivityFeedViewModel.ActivityFeedViewModel import com.kickstarter.viewmodels.ActivityFeedViewModel.Factory import io.reactivex.android.schedulers.AndroidSchedulers @@ -36,7 +37,6 @@ class ActivityFeedActivity : AppCompatActivity() { private var currentUser: CurrentUserTypeV2? = null private var recyclerViewPaginator: RecyclerViewPaginatorV2? = null private lateinit var binding: ActivityFeedLayoutBinding - private lateinit var viewModelFactory: Factory private val viewModel: ActivityFeedViewModel by viewModels { viewModelFactory @@ -47,7 +47,10 @@ class ActivityFeedActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityFeedLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) @@ -65,7 +68,11 @@ class ActivityFeedActivity : AppCompatActivity() { binding.recyclerView.layoutManager = LinearLayoutManager(this@ActivityFeedActivity) - recyclerViewPaginator = RecyclerViewPaginatorV2(binding.recyclerView, { viewModel.inputs.nextPage() }, viewModel.outputs.isFetchingActivities()) + recyclerViewPaginator = RecyclerViewPaginatorV2( + binding.recyclerView, + { viewModel.inputs.nextPage() }, + viewModel.outputs.isFetchingActivities() + ) binding.activityFeedSwipeRefreshLayout.setOnRefreshListener { viewModel.outputs.isFetchingActivities() diff --git a/app/src/main/java/com/kickstarter/ui/activities/ChangeEmailActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ChangeEmailActivity.kt index 6841e314e6..ac21ca73fa 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ChangeEmailActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ChangeEmailActivity.kt @@ -17,6 +17,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.extensions.onChange import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ChangeEmailViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -41,7 +42,10 @@ class ChangeEmailActivity : AppCompatActivity() { } binding = ActivityChangeEmailBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) setSupportActionBar(binding.changeEmailActivityToolbar.changeEmailToolbar) @@ -62,7 +66,10 @@ class ChangeEmailActivity : AppCompatActivity() { this.viewModel.outputs.emailErrorIsVisible() .observeOn(AndroidSchedulers.mainThread()) .filter { it } - .subscribe { binding.newEmailContainer.error = getString(R.string.Email_must_be_a_valid_email_address) } + .subscribe { + binding.newEmailContainer.error = + getString(R.string.Email_must_be_a_valid_email_address) + } .addToDisposable(disposables) this.viewModel.outputs.emailErrorIsVisible() @@ -124,7 +131,14 @@ class ChangeEmailActivity : AppCompatActivity() { this.viewModel.outputs.warningTextColor() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.emailWarningTextView.setTextColor(ContextCompat.getColor(this@ChangeEmailActivity, it)) } + .subscribe { + binding.emailWarningTextView.setTextColor( + ContextCompat.getColor( + this@ChangeEmailActivity, + it + ) + ) + } .addToDisposable(disposables) this.viewModel.outputs.verificationEmailButtonText() @@ -142,6 +156,7 @@ class ChangeEmailActivity : AppCompatActivity() { imm.hideSoftInputFromWindow(binding.newEmail.windowToken, 0) true } + else -> super.onOptionsItemSelected(item) } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/CommentsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/CommentsActivity.kt index 6adad65882..a8fe04e087 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/CommentsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/CommentsActivity.kt @@ -30,6 +30,7 @@ import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.hideKeyboard import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.views.OnCommentComposerViewClickedListener +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.CommentsViewModel.CommentsViewModel import com.kickstarter.viewmodels.CommentsViewModel.Factory import io.reactivex.disposables.CompositeDisposable @@ -56,7 +57,12 @@ class CommentsActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityCommentsLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) val view: View = binding.root + setContentView(view) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/CreatorBioActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/CreatorBioActivity.kt index 7f03f32df1..6dcb88c72a 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/CreatorBioActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/CreatorBioActivity.kt @@ -13,6 +13,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.models.Project import com.kickstarter.ui.IntentKey import com.kickstarter.ui.extensions.finishWithAnimation +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.CreatorBioViewModel.CreatorBioViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -28,7 +29,10 @@ class CreatorBioActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityCreatorBioBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) this.getEnvironment()?.let { env -> viewModelFactory = CreatorBioViewModel.Factory(env, intent = intent) env diff --git a/app/src/main/java/com/kickstarter/ui/activities/DiscoveryActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/DiscoveryActivity.kt index 91d5eaf9c3..46f6861541 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/DiscoveryActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/DiscoveryActivity.kt @@ -35,6 +35,7 @@ import com.kickstarter.ui.extensions.startActivityWithTransition import com.kickstarter.ui.fragments.ConsentManagementDialogFragment import com.kickstarter.ui.fragments.DiscoveryFragment import com.kickstarter.ui.fragments.DiscoveryFragment.Companion.newInstance +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.DiscoveryViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -57,6 +58,10 @@ class DiscoveryActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = DiscoveryLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) getEnvironment()?.let { env -> viewModelFactory = DiscoveryViewModel.Factory(env) @@ -71,14 +76,17 @@ class DiscoveryActivity : AppCompatActivity() { viewModel.provideIntent(intent) // TODO: Replace with compose implementation - val nightModeFlags = this.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) + val nightModeFlags = + this.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) viewModel.setDarkTheme( when (nightModeFlags) { - Configuration.UI_MODE_NIGHT_YES -> { true } + Configuration.UI_MODE_NIGHT_YES -> { + true + } + else -> false } ) - val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) {} drawerLayoutManager = LinearLayoutManager(this) @@ -146,7 +154,10 @@ class DiscoveryActivity : AppCompatActivity() { .subscribe { consentManagementDialogFragment = ConsentManagementDialogFragment() consentManagementDialogFragment.isCancelable = false - consentManagementDialogFragment.show(supportFragmentManager, "consentManagementDialogFragment") + consentManagementDialogFragment.show( + supportFragmentManager, + "consentManagementDialogFragment" + ) } .addToDisposable(disposables) diff --git a/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt index e0c8eafe28..d39b051b3c 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/EditProfileActivity.kt @@ -14,6 +14,7 @@ import com.kickstarter.models.User import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.EditProfileViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -32,7 +33,10 @@ class EditProfileActivity : ComponentActivity() { } binding = ActivityEditProfileBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) @@ -76,6 +80,9 @@ class EditProfileActivity : ComponentActivity() { } private fun displayPreferences(user: User) { - SwitchCompatUtils.setCheckedWithoutAnimation(binding.privateProfileSwitch, user.showPublicProfile().isFalse()) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.privateProfileSwitch, + user.showPublicProfile().isFalse() + ) } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/EditorialActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/EditorialActivity.kt index ac82b1e627..71208f1f7f 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/EditorialActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/EditorialActivity.kt @@ -13,6 +13,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.fragments.DiscoveryFragment +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.EditorialViewModel import io.reactivex.disposables.CompositeDisposable @@ -27,7 +28,10 @@ class EditorialActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityEditorialBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) getEnvironment()?.let { env -> intent?.let { factory = EditorialViewModel.Factory(env, it) diff --git a/app/src/main/java/com/kickstarter/ui/activities/FacebookConfirmationActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/FacebookConfirmationActivity.kt index 84584073e5..543ba5d3d8 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/FacebookConfirmationActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/FacebookConfirmationActivity.kt @@ -11,6 +11,7 @@ import com.kickstarter.libs.utils.SwitchCompatUtils import com.kickstarter.libs.utils.TransitionUtils import com.kickstarter.libs.utils.ViewUtils import com.kickstarter.libs.utils.extensions.addToDisposable +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.FacebookConfirmationViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -26,10 +27,14 @@ class FacebookConfirmationActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = FacebookConfirmationLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) - binding.signUpWithFacebookToolbar.loginToolbar.title = getString(R.string.facebook_confirmation_navbar_title) + binding.signUpWithFacebookToolbar.loginToolbar.title = + getString(R.string.facebook_confirmation_navbar_title) viewModel.outputs.prefillEmail() .observeOn(AndroidSchedulers.mainThread()) @@ -43,7 +48,12 @@ class FacebookConfirmationActivity : ComponentActivity() { viewModel.outputs.sendNewslettersIsChecked() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { SwitchCompatUtils.setCheckedWithoutAnimation(binding.newsletterSwitch, it) } + .subscribe { + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.newsletterSwitch, + it + ) + } .addToDisposable(disposables) viewModel.outputs.signupError() diff --git a/app/src/main/java/com/kickstarter/ui/activities/HelpActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/HelpActivity.kt index 88726a5c40..800abc6927 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/HelpActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/HelpActivity.kt @@ -8,11 +8,18 @@ import com.kickstarter.databinding.HelpLayoutBinding import com.kickstarter.libs.Environment import com.kickstarter.libs.qualifiers.WebEndpoint import com.kickstarter.libs.utils.extensions.getEnvironment +import com.kickstarter.utils.WindowInsetsUtil import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy open class HelpActivity : ComponentActivity() { - @IntDef(HELP_TYPE_TERMS, HELP_TYPE_PRIVACY, HELP_TYPE_HOW_IT_WORKS, HELP_TYPE_COOKIE_POLICY, HELP_TYPE_ACCESSIBILITY) + @IntDef( + HELP_TYPE_TERMS, + HELP_TYPE_PRIVACY, + HELP_TYPE_HOW_IT_WORKS, + HELP_TYPE_COOKIE_POLICY, + HELP_TYPE_ACCESSIBILITY + ) @Retention(RetentionPolicy.SOURCE) annotation class HelpType @@ -58,7 +65,10 @@ open class HelpActivity : ComponentActivity() { environment = this.getEnvironment() webEndpoint = environment?.webEndpoint() binding = HelpLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) val url = getUrlForHelpType(helpType) diff --git a/app/src/main/java/com/kickstarter/ui/activities/HelpSettingsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/HelpSettingsActivity.kt index 7338b8b509..44a4d35f77 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/HelpSettingsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/HelpSettingsActivity.kt @@ -18,6 +18,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.models.User import com.kickstarter.models.chrome.ChromeTabsHelperActivity import com.kickstarter.ui.extensions.startDisclaimerChromeTab +import com.kickstarter.utils.WindowInsetsUtil import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -38,6 +39,10 @@ class HelpSettingsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHelpSettingsBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) val view = binding.root setContentView(view) @@ -120,6 +125,7 @@ class HelpSettingsActivity : AppCompatActivity() { activity.startActivity(helpActivityIntent) } } + else -> null } ChromeTabsHelperActivity.openCustomTab(this, baseCustomTabsIntent(this), uri, fallback) diff --git a/app/src/main/java/com/kickstarter/ui/activities/MessageCreatorActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/MessageCreatorActivity.kt index d249609710..c83bafd650 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/MessageCreatorActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/MessageCreatorActivity.kt @@ -19,6 +19,7 @@ import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.onChange import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.MessageCreatorViewModel.Factory import com.kickstarter.viewmodels.MessageCreatorViewModel.MessageCreatorViewModel import io.reactivex.android.schedulers.AndroidSchedulers @@ -35,7 +36,10 @@ class MessageCreatorActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMessageCreatorBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/MessageThreadsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/MessageThreadsActivity.kt index 7fee5d6201..189678f1e4 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/MessageThreadsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/MessageThreadsActivity.kt @@ -23,6 +23,7 @@ import com.kickstarter.models.MessageThread import com.kickstarter.ui.adapters.MessageThreadsAdapter import com.kickstarter.ui.data.Mailbox import com.kickstarter.ui.extensions.finishWithAnimation +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.MessageThreadsViewModel.Factory import com.kickstarter.viewmodels.MessageThreadsViewModel.MessageThreadsViewModel import io.reactivex.android.schedulers.AndroidSchedulers @@ -44,7 +45,10 @@ class MessageThreadsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MessageThreadsLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpAdapter() diff --git a/app/src/main/java/com/kickstarter/ui/activities/MessagesActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/MessagesActivity.kt index 6649efcb4a..1a9c10e182 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/MessagesActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/MessagesActivity.kt @@ -30,6 +30,7 @@ import com.kickstarter.ui.adapters.MessagesAdapter import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.startActivityWithTransition +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.MessagesViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -52,6 +53,10 @@ class MessagesActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MessagesLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/NewsletterActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/NewsletterActivity.kt index 42aa23b293..1f6a7ec8ea 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/NewsletterActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/NewsletterActivity.kt @@ -13,6 +13,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.isTrue import com.kickstarter.models.User import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.NewsletterViewModel.Factory import com.kickstarter.viewmodels.NewsletterViewModel.NewsletterViewModel import io.reactivex.android.schedulers.AndroidSchedulers @@ -21,6 +22,7 @@ import io.reactivex.disposables.CompositeDisposable enum class Newsletter { ALL, ALUMNI, ARTS, FILMS, GAMES, HAPPENING, INVENT, MUSIC, PROMO, READS, WEEKLY } + class NewsletterActivity : AppCompatActivity() { private lateinit var ksString: KSString @@ -36,7 +38,10 @@ class NewsletterActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityNewsletterBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) @@ -65,33 +70,76 @@ class NewsletterActivity : AppCompatActivity() { this.viewModel.outputs.subscribeAll() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { SwitchCompatUtils.setCheckedWithoutAnimation(binding.subscribeAllSwitch, it) } + .subscribe { + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.subscribeAllSwitch, + it + ) + } .addToDisposable(disposables) binding.alumniSwitch.setOnClickListener { viewModel.inputs.sendAlumniNewsletter(binding.alumniSwitch.isChecked) } binding.artsNewsSwitch.setOnClickListener { viewModel.inputs.sendArtsNewsNewsletter(binding.artsNewsSwitch.isChecked) } binding.filmsSwitch.setOnClickListener { viewModel.inputs.sendFilmsNewsletter(binding.filmsSwitch.isChecked) } binding.gamesWeLoveSwitch.setOnClickListener { viewModel.inputs.sendGamesNewsletter(binding.gamesWeLoveSwitch.isChecked) } - binding.happeningSwitch.setOnClickListener { viewModel.inputs.sendHappeningNewsletter(binding.happeningSwitch.isChecked) } + binding.happeningSwitch.setOnClickListener { + viewModel.inputs.sendHappeningNewsletter( + binding.happeningSwitch.isChecked + ) + } binding.inventSwitch.setOnClickListener { viewModel.inputs.sendInventNewsletter(binding.inventSwitch.isChecked) } binding.musicSwitch.setOnClickListener { viewModel.inputs.sendMusicNewsletter(binding.musicSwitch.isChecked) } binding.newsEventsSwitch.setOnClickListener { viewModel.inputs.sendPromoNewsletter(binding.newsEventsSwitch.isChecked) } - binding.projectsWeLoveSwitch.setOnClickListener { viewModel.inputs.sendWeeklyNewsletter(binding.projectsWeLoveSwitch.isChecked) } + binding.projectsWeLoveSwitch.setOnClickListener { + viewModel.inputs.sendWeeklyNewsletter( + binding.projectsWeLoveSwitch.isChecked + ) + } binding.readsSwitch.setOnClickListener { viewModel.inputs.sendReadsNewsletter(binding.readsSwitch.isChecked) } binding.subscribeAllSwitch.setOnClickListener { viewModel.inputs.sendAllNewsletter(binding.subscribeAllSwitch.isChecked) } } private fun displayPreferences(user: User) { - SwitchCompatUtils.setCheckedWithoutAnimation(binding.alumniSwitch, user.alumniNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.artsNewsSwitch, user.artsCultureNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.filmsSwitch, user.filmNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.gamesWeLoveSwitch, user.gamesNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.happeningSwitch, user.happeningNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.inventSwitch, user.inventNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.musicSwitch, user.musicNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.newsEventsSwitch, user.promoNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.projectsWeLoveSwitch, user.weeklyNewsletter().isTrue()) - SwitchCompatUtils.setCheckedWithoutAnimation(binding.readsSwitch, user.publishingNewsletter().isTrue()) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.alumniSwitch, + user.alumniNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.artsNewsSwitch, + user.artsCultureNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.filmsSwitch, + user.filmNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.gamesWeLoveSwitch, + user.gamesNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.happeningSwitch, + user.happeningNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.inventSwitch, + user.inventNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.musicSwitch, + user.musicNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.newsEventsSwitch, + user.promoNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.projectsWeLoveSwitch, + user.weeklyNewsletter().isTrue() + ) + SwitchCompatUtils.setCheckedWithoutAnimation( + binding.readsSwitch, + user.publishingNewsletter().isTrue() + ) } private fun newsletterString(newsletter: Newsletter): String? { @@ -113,7 +161,15 @@ class NewsletterActivity : AppCompatActivity() { private fun showOptInPrompt(newsletter: Newsletter) { val string = newsletterString(newsletter) - val optInDialogMessageString = this.ksString.format(getString(R.string.profile_settings_newsletter_opt_in_message), "newsletter", string) - ViewUtils.showDialog(this, getString(R.string.profile_settings_newsletter_opt_in_title), optInDialogMessageString) + val optInDialogMessageString = this.ksString.format( + getString(R.string.profile_settings_newsletter_opt_in_message), + "newsletter", + string + ) + ViewUtils.showDialog( + this, + getString(R.string.profile_settings_newsletter_opt_in_title), + optInDialogMessageString + ) } } diff --git a/app/src/main/java/com/kickstarter/ui/activities/NotificationsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/NotificationsActivity.kt index 1b18218621..c8e267e3e8 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/NotificationsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/NotificationsActivity.kt @@ -19,6 +19,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.intValueOrZero import com.kickstarter.libs.utils.extensions.isTrue import com.kickstarter.models.User +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.NotificationsViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -32,10 +33,13 @@ class NotificationsActivity : ComponentActivity() { private val circleFilled = R.drawable.circle_gray_filled private val subscribeString = R.string.profile_settings_accessibility_subscribe_notifications - private val subscribeMobileString = R.string.profile_settings_accessibility_subscribe_mobile_notifications + private val subscribeMobileString = + R.string.profile_settings_accessibility_subscribe_mobile_notifications private val unableToSaveString = R.string.profile_settings_error - private val unsubscribeMobileString = R.string.profile_settings_accessibility_unsubscribe_mobile_notifications - private val unsubscribeString = R.string.profile_settings_accessibility_unsubscribe_notifications + private val unsubscribeMobileString = + R.string.profile_settings_accessibility_unsubscribe_mobile_notifications + private val unsubscribeString = + R.string.profile_settings_accessibility_unsubscribe_notifications private var notifyMobileOfBackings: Boolean = false private var notifyMobileOfComments: Boolean = false @@ -66,7 +70,10 @@ class NotificationsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityNotificationsBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) this.getEnvironment()?.let { env -> viewModelFactory = NotificationsViewModel.Factory(env) env @@ -105,7 +112,8 @@ class NotificationsActivity : ComponentActivity() { } private fun displayPreferences(user: User) { - binding.projectNotificationsCount.text = user.backedProjectsCount().intValueOrZero().toString() + binding.projectNotificationsCount.text = + user.backedProjectsCount().intValueOrZero().toString() displayMarketingUpdates(user) displayBackingsNotificationSettings(user) @@ -121,7 +129,11 @@ class NotificationsActivity : ComponentActivity() { private fun displayMarketingUpdates(user: User) { this.notifyMobileOfMarketingUpdates = user.notifyMobileOfMarketingUpdate().isTrue() - toggleImageButtonIconColor(binding.marketingUpdatesPhoneIcon, this.notifyMobileOfMarketingUpdates, true) + toggleImageButtonIconColor( + binding.marketingUpdatesPhoneIcon, + this.notifyMobileOfMarketingUpdates, + true + ) } private fun displayBackingsNotificationSettings(user: User) { @@ -141,16 +153,22 @@ class NotificationsActivity : ComponentActivity() { binding.emailFrequencySpinner.setSelection(frequencyIndex, false) } - binding.emailFrequencySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onNothingSelected(parent: AdapterView<*>?) { - } + binding.emailFrequencySpinner.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + } - override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - if (frequencyIndex != position) { - viewModel.inputs.notifyOfCreatorDigest(position == User.EmailFrequency.DAILY_SUMMARY.ordinal) + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long + ) { + if (frequencyIndex != position) { + viewModel.inputs.notifyOfCreatorDigest(position == User.EmailFrequency.DAILY_SUMMARY.ordinal) + } } } - } } private fun displayCommentsNotificationSettings(user: User) { @@ -163,7 +181,10 @@ class NotificationsActivity : ComponentActivity() { private fun displayCommentRepliesNotificationSettings(user: User) { this.notifyMobileOfCommentReplies = user.notifyOfCommentReplies().isTrue() - toggleImageButtonIconColor(binding.commentRepliesMailIcon, this.notifyMobileOfCommentReplies) + toggleImageButtonIconColor( + binding.commentRepliesMailIcon, + this.notifyMobileOfCommentReplies + ) } private fun displayCreatorTipsNotificationSettings(user: User) { @@ -186,7 +207,11 @@ class NotificationsActivity : ComponentActivity() { this.notifyMobileOfFriendActivity = user.notifyMobileOfFriendActivity().isTrue() this.notifyOfFriendActivity = user.notifyOfFriendActivity().isTrue() - toggleImageButtonIconColor(binding.friendActivityPhoneIcon, this.notifyMobileOfFriendActivity, true) + toggleImageButtonIconColor( + binding.friendActivityPhoneIcon, + this.notifyMobileOfFriendActivity, + true + ) toggleImageButtonIconColor(binding.friendActivityMailIcon, this.notifyOfFriendActivity) } @@ -208,7 +233,11 @@ class NotificationsActivity : ComponentActivity() { this.notifyMobileOfUpdates = user.notifyMobileOfUpdates().isTrue() this.notifyOfUpdates = user.notifyOfUpdates().isTrue() - toggleImageButtonIconColor(binding.projectUpdatesPhoneIcon, this.notifyMobileOfUpdates, true) + toggleImageButtonIconColor( + binding.projectUpdatesPhoneIcon, + this.notifyMobileOfUpdates, + true + ) toggleImageButtonIconColor(binding.projectUpdatesMailIcon, this.notifyOfUpdates) } @@ -251,7 +280,10 @@ class NotificationsActivity : ComponentActivity() { } binding.backingsRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.backingsPhoneIcon, binding.backingsMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.backingsPhoneIcon, + binding.backingsMailIcon + ) } binding.commentsMailIcon.setOnClickListener { @@ -271,7 +303,10 @@ class NotificationsActivity : ComponentActivity() { } binding.commentsRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.commentsPhoneIcon, binding.commentsMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.commentsPhoneIcon, + binding.commentsMailIcon + ) } binding.creatorEduMailIcon.setOnClickListener { @@ -283,7 +318,10 @@ class NotificationsActivity : ComponentActivity() { } binding.creatorEduRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.creatorEduPhoneIcon, binding.creatorEduMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.creatorEduPhoneIcon, + binding.creatorEduMailIcon + ) } binding.friendActivityMailIcon.setOnClickListener { @@ -295,7 +333,10 @@ class NotificationsActivity : ComponentActivity() { } binding.friendsBackProjectRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.friendActivityPhoneIcon, binding.friendActivityMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.friendActivityPhoneIcon, + binding.friendActivityMailIcon + ) } binding.messagesMailIcon.setOnClickListener { @@ -307,7 +348,10 @@ class NotificationsActivity : ComponentActivity() { } binding.messagesNotificationRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.messagesPhoneIcon, binding.messagesMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.messagesPhoneIcon, + binding.messagesMailIcon + ) } binding.newFollowersMailIcon.setOnClickListener { @@ -319,7 +363,10 @@ class NotificationsActivity : ComponentActivity() { } binding.newFollowersRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.newFollowersPhoneIcon, binding.newFollowersMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.newFollowersPhoneIcon, + binding.newFollowersMailIcon + ) } binding.postLikesPhoneIcon.setOnClickListener { @@ -339,7 +386,10 @@ class NotificationsActivity : ComponentActivity() { } binding.projectUpdatesRow.setOnClickListener { - AnimationUtils.notificationBounceAnimation(binding.projectUpdatesPhoneIcon, binding.projectUpdatesMailIcon) + AnimationUtils.notificationBounceAnimation( + binding.projectUpdatesPhoneIcon, + binding.projectUpdatesMailIcon + ) } } @@ -347,7 +397,11 @@ class NotificationsActivity : ComponentActivity() { startActivity(Intent(this, ProjectNotificationSettingsActivity::class.java)) } - private fun toggleImageButtonIconColor(imageButton: ImageButton, enabled: Boolean, typeMobile: Boolean = false) { + private fun toggleImageButtonIconColor( + imageButton: ImageButton, + enabled: Boolean, + typeMobile: Boolean = false + ) { val color = getEnabledColorResId(enabled) imageButton.setColorFilter(ContextCompat.getColor(this, color)) diff --git a/app/src/main/java/com/kickstarter/ui/activities/PaymentMethodsSettingsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/PaymentMethodsSettingsActivity.kt index 75f3688d0b..332da92a1a 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/PaymentMethodsSettingsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/PaymentMethodsSettingsActivity.kt @@ -17,6 +17,7 @@ import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showErrorSnackBar import com.kickstarter.ui.extensions.showErrorToast import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.PaymentMethodsViewModel import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetResult @@ -48,6 +49,10 @@ class PaymentMethodsSettingsActivity : AppCompatActivity() { } binding = ActivitySettingsPaymentMethodsBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/PrivacyActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/PrivacyActivity.kt index 792b998145..85bff3c731 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/PrivacyActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/PrivacyActivity.kt @@ -17,6 +17,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.isFalse import com.kickstarter.libs.utils.extensions.isTrue import com.kickstarter.models.User +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.PrivacyViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -41,6 +42,10 @@ class PrivacyActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityPrivacyBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) getEnvironment()?.let { env -> viewModelFactory = PrivacyViewModel.Factory(env) diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt index 542e33874c..4dde384a10 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProfileActivity.kt @@ -21,6 +21,7 @@ import com.kickstarter.ui.IntentKey import com.kickstarter.ui.adapters.ProfileAdapter import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.startActivityWithTransition +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ProfileViewModel import io.reactivex.disposables.CompositeDisposable @@ -37,7 +38,10 @@ class ProfileActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ProfileLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) getEnvironment()?.let { env -> @@ -151,7 +155,10 @@ class ProfileActivity : ComponentActivity() { if (projects.isEmpty()) { binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.setPadding( - 0, binding.recyclerView.paddingTop, binding.recyclerView.paddingRight, binding.recyclerView.paddingBottom + 0, + binding.recyclerView.paddingTop, + binding.recyclerView.paddingRight, + binding.recyclerView.paddingBottom ) if (ViewUtils.isPortrait(this)) { diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectNotificationSettingsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectNotificationSettingsActivity.kt index 3552ed0c51..98350168b3 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectNotificationSettingsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectNotificationSettingsActivity.kt @@ -10,6 +10,7 @@ import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.adapters.ProjectNotificationSettingsAdapter import com.kickstarter.ui.extensions.showSnackbar +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ProjectNotificationSettingsViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -29,6 +30,11 @@ class ProjectNotificationSettingsActivity : ComponentActivity() { viewModelFactory = ProjectNotificationSettingsViewModel.Factory(env) } binding = ProjectNotificationSettingsLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + + ) setContentView(binding.root) val adapter = ProjectNotificationSettingsAdapter() diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt index ec08674d7a..1c3c4fd937 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt @@ -34,6 +34,8 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.core.view.isGone import androidx.fragment.app.FragmentManager import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -87,6 +89,7 @@ import com.kickstarter.ui.fragments.BackingFragment import com.kickstarter.ui.fragments.CancelPledgeFragment import com.kickstarter.ui.fragments.PledgeFragment import com.kickstarter.ui.fragments.RewardsFragment +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.projectpage.AddOnsViewModel import com.kickstarter.viewmodels.projectpage.CheckoutFlowViewModel import com.kickstarter.viewmodels.projectpage.LatePledgeCheckoutViewModel @@ -149,19 +152,24 @@ class ProjectPageActivity : ProjectPagerTabs.RISKS, ) - var startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { - // There are no request codes - val data = result.data?.getLongExtra(IntentKey.VIDEO_SEEK_POSITION, 0) - data?.let { - viewModel.inputs.closeFullScreenVideo(it) + var startForResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + // There are no request codes + val data = result.data?.getLongExtra(IntentKey.VIDEO_SEEK_POSITION, 0) + data?.let { + viewModel.inputs.closeFullScreenVideo(it) + } } } - } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityProjectPageBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) @@ -196,12 +204,15 @@ class ProjectPageActivity : val viewTreeObserver = binding.pledgeContainerLayout.pledgeContainerRoot.viewTreeObserver if (viewTreeObserver.isAlive) { - viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - this@ProjectPageActivity.viewModel.inputs.onGlobalLayout() - binding.pledgeContainerLayout.pledgeContainerRoot.viewTreeObserver.removeOnGlobalLayoutListener(this) - } - }) + viewTreeObserver.addOnGlobalLayoutListener(object : + ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + this@ProjectPageActivity.viewModel.inputs.onGlobalLayout() + binding.pledgeContainerLayout.pledgeContainerRoot.viewTreeObserver.removeOnGlobalLayoutListener( + this + ) + } + }) } this.supportFragmentManager.addOnBackStackChangedListener { @@ -212,7 +223,8 @@ class ProjectPageActivity : if (fragment == lastFragmentWithView) { fragment.view?.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES } else { - fragment.view?.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + fragment.view?.importantForAccessibility = + View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS } } } @@ -235,7 +247,8 @@ class ProjectPageActivity : // - Every time the ProjectData gets updated // - the fragments on the viewPager are updated as well (binding.projectPager.adapter as? ProjectPagerAdapter)?.updatedWithProjectData(it) - val fFLatePledge = environment?.featureFlagClient()?.getBoolean(FlagKey.ANDROID_POST_CAMPAIGN_PLEDGES) ?: false + val fFLatePledge = environment?.featureFlagClient() + ?.getBoolean(FlagKey.ANDROID_POST_CAMPAIGN_PLEDGES) ?: false if (fFLatePledge && it.project().showLatePledgeFlow()) { rewardsSelectionViewModel.provideProjectData(it) @@ -287,12 +300,18 @@ class ProjectPageActivity : this.viewModel.outputs.pledgeActionButtonColor() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.pledgeContainerLayout.pledgeActionButton.backgroundTintList = ContextCompat.getColorStateList(this, it) } + .subscribe { + binding.pledgeContainerLayout.pledgeActionButton.backgroundTintList = + ContextCompat.getColorStateList(this, it) + } .addToDisposable(disposables) this.viewModel.outputs.pledgeActionButtonContainerIsGone() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = (!it).toVisibility() } + .subscribe { + binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = + (!it).toVisibility() + } .addToDisposable(disposables) this.viewModel.outputs.pledgeActionButtonText() @@ -302,7 +321,10 @@ class ProjectPageActivity : this.viewModel.outputs.pledgeToolbarNavigationIcon() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.pledgeContainerLayout.pledgeToolbar.navigationIcon = ContextCompat.getDrawable(this, it) } + .subscribe { + binding.pledgeContainerLayout.pledgeToolbar.navigationIcon = + ContextCompat.getDrawable(this, it) + } .addToDisposable(disposables) this.viewModel.outputs.pledgeToolbarTitle() @@ -317,12 +339,18 @@ class ProjectPageActivity : this.viewModel.outputs.reloadProjectContainerIsGone() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.pledgeContainerLayout.projectRetryLayout.pledgeSheetRetryContainer.visibility = (!it).toVisibility() } + .subscribe { + binding.pledgeContainerLayout.projectRetryLayout.pledgeSheetRetryContainer.visibility = + (!it).toVisibility() + } .addToDisposable(disposables) this.viewModel.outputs.reloadProgressBarIsGone() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { binding.pledgeContainerLayout.projectRetryLayout.pledgeSheetProgressBar.visibility = (!it).toVisibility() } + .subscribe { + binding.pledgeContainerLayout.projectRetryLayout.pledgeSheetProgressBar.visibility = + (!it).toVisibility() + } .addToDisposable(disposables) this.viewModel.outputs.scrimIsVisible() @@ -550,7 +578,10 @@ class ProjectPageActivity : LaunchedEffect(checkoutPayment.id) { checkoutPayment.backing?.let { - latePledgeCheckoutViewModel.provideCheckoutIdAndBacking(checkoutPayment.id, it) + latePledgeCheckoutViewModel.provideCheckoutIdAndBacking( + checkoutPayment.id, + it + ) } } @@ -568,7 +599,10 @@ class ProjectPageActivity : LaunchedEffect(Unit) { latePledgeCheckoutViewModel.clientSecretForNewPaymentMethod.collect { - flowControllerPresentPaymentOption(it, latePledgeCheckoutUIState.userEmail) + flowControllerPresentPaymentOption( + it, + latePledgeCheckoutUIState.userEmail + ) } } @@ -685,7 +719,10 @@ class ProjectPageActivity : } ) - val successfulPledge = latePledgeCheckoutViewModel.onPledgeSuccess.collectAsStateWithLifecycle(initialValue = false).value + val successfulPledge = + latePledgeCheckoutViewModel.onPledgeSuccess.collectAsStateWithLifecycle( + initialValue = false + ).value LaunchedEffect(successfulPledge) { if (successfulPledge) { @@ -717,7 +754,12 @@ class ProjectPageActivity : private fun showAccountabilityPage() { getEnvironment()?.webEndpoint()?.let { endpoint -> val trustUrl = UrlUtils.appendPath(endpoint, "trust") - ChromeTabsHelperActivity.openCustomTab(this, UrlUtils.baseCustomTabsIntent(this), Uri.parse(trustUrl), null) + ChromeTabsHelperActivity.openCustomTab( + this, + UrlUtils.baseCustomTabsIntent(this), + Uri.parse(trustUrl), + null + ) } ?: run { showToastError() } @@ -826,14 +868,15 @@ class ProjectPageActivity : return Pair.create(R.anim.fade_in_slide_in_left, R.anim.slide_out_right) } - private fun getTabTitle(position: Int, pagerList: List) = when (pagerList[position]) { - ProjectPagerTabs.OVERVIEW -> getString(R.string.Overview) - ProjectPagerTabs.CAMPAIGN -> getString(R.string.Campaign) - ProjectPagerTabs.FAQS -> getString(R.string.Faq) - ProjectPagerTabs.RISKS -> getString(R.string.Risks) - ProjectPagerTabs.USE_OF_AI -> getString(R.string.Use_of_ai) - ProjectPagerTabs.ENVIRONMENTAL_COMMITMENT -> getString(R.string.Environmental_commitments) - } + private fun getTabTitle(position: Int, pagerList: List) = + when (pagerList[position]) { + ProjectPagerTabs.OVERVIEW -> getString(R.string.Overview) + ProjectPagerTabs.CAMPAIGN -> getString(R.string.Campaign) + ProjectPagerTabs.FAQS -> getString(R.string.Faq) + ProjectPagerTabs.RISKS -> getString(R.string.Risks) + ProjectPagerTabs.USE_OF_AI -> getString(R.string.Use_of_ai) + ProjectPagerTabs.ENVIRONMENTAL_COMMITMENT -> getString(R.string.Environmental_commitments) + } private fun animateScrimVisibility(show: Boolean) { val shouldAnimateIn = show && binding.pledgeContainerLayout.scrim.alpha <= 1f @@ -844,7 +887,6 @@ class ProjectPageActivity : .alpha(finalAlpha) .setDuration(200L) .setListener(object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator) { if (!show) { binding.pledgeContainerLayout.scrim.visibility = View.GONE @@ -860,43 +902,61 @@ class ProjectPageActivity : } } - private fun backingFragment() = supportFragmentManager.findFragmentById(R.id.fragment_backing) as BackingFragment? + private fun backingFragment() = + supportFragmentManager.findFragmentById(R.id.fragment_backing) as BackingFragment? private fun clearFragmentBackStack(): Boolean { - return supportFragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) + return supportFragmentManager.popBackStackImmediate( + null, + FragmentManager.POP_BACK_STACK_INCLUSIVE + ) } @SuppressLint("DiscouragedApi", "InternalInsetResource") private fun expandPledgeSheet(expandAndAnimate: Pair) { var statusBarHeight = 0 - // TODO: Replace with window insets compat - val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android") - if (resourceId > 0) { - statusBarHeight = resources.getDimensionPixelSize(resourceId) + + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets -> + statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top + insets } val expand = expandAndAnimate.first val animate = expandAndAnimate.second - val targetToShow = if (!expand) binding.pledgeContainerLayout.pledgeActionButtonsLayout else binding.pledgeContainerLayout.pledgeContainer + val targetToShow = + if (!expand) binding.pledgeContainerLayout.pledgeActionButtonsLayout else binding.pledgeContainerLayout.pledgeContainer val showRewardsFragmentAnimator = ObjectAnimator.ofFloat(targetToShow, View.ALPHA, 0f, 1f) - val targetToHide = if (!expand) binding.pledgeContainerLayout.pledgeContainer else binding.pledgeContainerLayout.pledgeActionButtonsLayout + val targetToHide = + if (!expand) binding.pledgeContainerLayout.pledgeContainer else binding.pledgeContainerLayout.pledgeActionButtonsLayout val hideRewardsFragmentAnimator = ObjectAnimator.ofFloat(targetToHide, View.ALPHA, 1f, 0f) val guideline = rewardsSheetGuideline() - val initialValue = (if (expand) binding.pledgeContainerLayout.pledgeContainerRoot.height - guideline else 0).toFloat() - val finalValue = ((if (expand) 0 else binding.pledgeContainerLayout.pledgeContainerRoot.height - guideline) + statusBarHeight).toFloat() + val initialValue = + (if (expand) binding.pledgeContainerLayout.pledgeContainerRoot.height - guideline else 0).toFloat() + val finalValue = + ((if (expand) 0 else binding.pledgeContainerLayout.pledgeContainerRoot.height - guideline) + statusBarHeight).toFloat() val initialRadius = resources.getDimensionPixelSize(R.dimen.fab_radius).toFloat() - val pledgeContainerYAnimator = ObjectAnimator.ofFloat(binding.pledgeContainerLayout.pledgeContainerRoot, View.Y, initialValue, finalValue).apply { + val pledgeContainerYAnimator = ObjectAnimator.ofFloat( + binding.pledgeContainerLayout.pledgeContainerRoot, + View.Y, + initialValue, + finalValue + ).apply { addUpdateListener { valueAnim -> - val radius = initialRadius * if (expand) 1 - valueAnim.animatedFraction else valueAnim.animatedFraction + val radius = + initialRadius * if (expand) 1 - valueAnim.animatedFraction else valueAnim.animatedFraction binding.pledgeContainerLayout.pledgeContainerRoot.radius = radius } } AnimatorSet().apply { - playTogether(showRewardsFragmentAnimator, hideRewardsFragmentAnimator, pledgeContainerYAnimator) + playTogether( + showRewardsFragmentAnimator, + hideRewardsFragmentAnimator, + pledgeContainerYAnimator + ) duration = animDuration addListener(object : Animator.AnimatorListener { @@ -906,12 +966,15 @@ class ProjectPageActivity : override fun onAnimationEnd(animation: Animator) { setFragmentsState(expand) if (expand) { - binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = View.GONE - binding.projectActivityToolbar.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = + View.GONE + binding.projectActivityToolbar.importantForAccessibility = + View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS binding.pledgeContainerLayout.pledgeToolbar.requestFocus() } else { binding.pledgeContainerLayout.pledgeContainer.visibility = View.GONE - binding.projectActivityToolbar.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES + binding.projectActivityToolbar.importantForAccessibility = + View.IMPORTANT_FOR_ACCESSIBILITY_YES if (animate) { binding.projectActivityToolbar.requestFocus() } @@ -922,7 +985,8 @@ class ProjectPageActivity : if (expand) { binding.pledgeContainerLayout.pledgeContainer.visibility = View.VISIBLE } else if (animate) { - binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = View.VISIBLE + binding.pledgeContainerLayout.pledgeActionButtonsLayout.visibility = + View.VISIBLE } } }) @@ -937,6 +1001,7 @@ class ProjectPageActivity : is RewardsFragment -> { fragment.setState(expand && fragment.isVisible) } + is BackingFragment -> { fragment.setState(expand && fragment.isVisible) } @@ -945,8 +1010,10 @@ class ProjectPageActivity : } private fun handleNativeCheckoutBackPress() { - val retryPadding = resources.getDimensionPixelSize(R.dimen.grid_4) // pledge_sheet_retry_container padding - val pledgeSheetIsExpanded = binding.pledgeContainerLayout.pledgeContainerRoot.y <= retryPadding + val retryPadding = + resources.getDimensionPixelSize(R.dimen.grid_4) // pledge_sheet_retry_container padding + val pledgeSheetIsExpanded = + binding.pledgeContainerLayout.pledgeContainerRoot.y <= retryPadding when { supportFragmentManager.backStackEntryCount > 0 -> supportFragmentManager.popBackStack() @@ -960,7 +1027,11 @@ class ProjectPageActivity : finish() } - private fun renderProject(backingFragment: BackingFragment, rewardsFragment: RewardsFragment, projectData: ProjectData) { + private fun renderProject( + backingFragment: BackingFragment, + rewardsFragment: RewardsFragment, + projectData: ProjectData + ) { rewardsFragment.configureWith(projectData) backingFragment.configureWith(projectData) } @@ -976,15 +1047,18 @@ class ProjectPageActivity : } } - private fun rewardsFragment() = supportFragmentManager.findFragmentById(R.id.fragment_rewards) as RewardsFragment? + private fun rewardsFragment() = + supportFragmentManager.findFragmentById(R.id.fragment_rewards) as RewardsFragment? - private fun rewardsSheetGuideline(): Int = resources.getDimensionPixelSize(R.dimen.reward_fragment_guideline_constraint_end) + private fun rewardsSheetGuideline(): Int = + resources.getDimensionPixelSize(R.dimen.reward_fragment_guideline_constraint_end) private fun setBackingDetailsSubtitle(stringResOrTitle: Either?) { stringResOrTitle?.let { either -> @StringRes val stringRes = either.right() val title = either.left() - binding.pledgeContainerLayout.backingDetailsSubtitle.text = stringRes?.let { getString(it) } ?: title + binding.pledgeContainerLayout.backingDetailsSubtitle.text = + stringRes?.let { getString(it) } ?: title } } @@ -1003,18 +1077,22 @@ class ProjectPageActivity : this.viewModel.inputs.viewRewardsClicked() true } + R.id.update_payment -> { this.viewModel.inputs.updatePaymentClicked() true } + R.id.cancel_pledge -> { this.viewModel.inputs.cancelPledgeClicked() true } + R.id.contact_creator -> { this.viewModel.inputs.contactCreatorClicked() true } + else -> false } } @@ -1034,7 +1112,8 @@ class ProjectPageActivity : private fun setInitialRewardsContainerY() { val guideline = rewardsSheetGuideline() - binding.pledgeContainerLayout.pledgeContainerRoot.y = (binding.root.height - guideline).toFloat() + binding.pledgeContainerLayout.pledgeContainerRoot.y = + (binding.root.height - guideline).toFloat() } private fun showCancelPledgeFragment(project: Project) { @@ -1058,9 +1137,15 @@ class ProjectPageActivity : val pledgeData = checkoutDataAndProjectData.second val projectData = pledgeData.projectData() - val fFLatePledge = getEnvironment()?.featureFlagClient()?.getBoolean(FlagKey.ANDROID_POST_CAMPAIGN_PLEDGES) ?: false + val fFLatePledge = + getEnvironment()?.featureFlagClient()?.getBoolean(FlagKey.ANDROID_POST_CAMPAIGN_PLEDGES) + ?: false - if (clearFragmentBackStack() || (projectData.project().showLatePledgeFlow() && fFLatePledge)) { + if (clearFragmentBackStack() || ( + projectData.project() + .showLatePledgeFlow() && fFLatePledge + ) + ) { startActivity( Intent(this, ThanksActivity::class.java) .putExtra(IntentKey.PROJECT, projectData.project().reduceProjectPayload()) @@ -1076,7 +1161,6 @@ class ProjectPageActivity : .setPositiveButton(getString(R.string.general_alert_buttons_ok)) { dialog, _ -> dialog.dismiss() } .show() } - private fun showPledgeFragment( pledgeDataAndPledgeReason: Pair, ffClient: FeatureFlagClientType @@ -1101,7 +1185,12 @@ class ProjectPageActivity : } private fun showStarToast() { - ViewUtils.showToastFromTop(this, getString(this.projectStarConfirmationString), 0, resources.getDimensionPixelSize(R.dimen.grid_8)) + ViewUtils.showToastFromTop( + this, + getString(this.projectStarConfirmationString), + 0, + resources.getDimensionPixelSize(R.dimen.grid_8) + ) } private fun showUpdatePledgeSuccess() { @@ -1114,7 +1203,8 @@ class ProjectPageActivity : private fun startShareIntent(projectNameAndShareUrl: Pair) { val name = projectNameAndShareUrl.first - val shareMessage = this.ksString.format(getString(this.projectShareCopyString), "project_title", name) + val shareMessage = + this.ksString.format(getString(this.projectShareCopyString), "project_title", name) val url = projectNameAndShareUrl.second val intent = Intent(Intent.ACTION_SEND) @@ -1139,17 +1229,21 @@ class ProjectPageActivity : } private fun styleProjectActionButton(detailsAreVisible: Boolean) { - val buttonParams = binding.pledgeContainerLayout.pledgeActionButton.layoutParams as LinearLayout.LayoutParams + val buttonParams = + binding.pledgeContainerLayout.pledgeActionButton.layoutParams as LinearLayout.LayoutParams when { detailsAreVisible -> { binding.pledgeContainerLayout.backingDetails.visibility = View.VISIBLE buttonParams.width = LinearLayout.LayoutParams.WRAP_CONTENT - binding.pledgeContainerLayout.pledgeActionButton.cornerRadius = resources.getDimensionPixelSize(R.dimen.grid_2) + binding.pledgeContainerLayout.pledgeActionButton.cornerRadius = + resources.getDimensionPixelSize(R.dimen.grid_2) } + else -> { binding.pledgeContainerLayout.backingDetails.visibility = View.GONE buttonParams.width = LinearLayout.LayoutParams.MATCH_PARENT - binding.pledgeContainerLayout.pledgeActionButton.cornerRadius = resources.getDimensionPixelSize(R.dimen.fab_radius) + binding.pledgeContainerLayout.pledgeActionButton.cornerRadius = + resources.getDimensionPixelSize(R.dimen.fab_radius) } } binding.pledgeContainerLayout.pledgeActionButton.layoutParams = buttonParams @@ -1159,7 +1253,9 @@ class ProjectPageActivity : try { // - Every time the ProjectData gets updated // - the fragments on the viewPager are updated as well - (binding.projectPager.adapter as? ProjectPagerAdapter)?.updatedWithProjectData(projectData) + (binding.projectPager.adapter as? ProjectPagerAdapter)?.updatedWithProjectData( + projectData + ) val rewardsFragment = rewardsFragment() val backingFragment = backingFragment() @@ -1172,6 +1268,7 @@ class ProjectPageActivity : .hide(rewardsFragment) .commitNow() } + else -> if (!backingFragment.isHidden) { supportFragmentManager.beginTransaction() .show(rewardsFragment) @@ -1207,7 +1304,8 @@ class ProjectPageActivity : } is PaymentSheetResult.Failed -> { - val errorMessage = paymentSheetResult.error.localizedMessage ?: getString(R.string.general_error_something_wrong) + val errorMessage = paymentSheetResult.error.localizedMessage + ?: getString(R.string.general_error_something_wrong) showErrorToast( applicationContext, binding.pledgeContainerCompose, @@ -1254,7 +1352,11 @@ class ProjectPageActivity : } private fun showToastError(message: String? = null) { - showErrorToast(applicationContext, binding.pledgeContainerCompose, message ?: getString(R.string.general_error_something_wrong)) + showErrorToast( + applicationContext, + binding.pledgeContainerCompose, + message ?: getString(R.string.general_error_something_wrong) + ) } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectSocialActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectSocialActivity.kt index 0e2e85d87f..883a2568c6 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectSocialActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectSocialActivity.kt @@ -10,6 +10,7 @@ import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.adapters.ProjectSocialAdapter import com.kickstarter.ui.extensions.finishWithAnimation +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ProjectSocialViewModel.Factory import com.kickstarter.viewmodels.ProjectSocialViewModel.ProjectSocialViewModel import io.reactivex.android.schedulers.AndroidSchedulers @@ -32,6 +33,10 @@ class ProjectSocialActivity : AppCompatActivity() { } binding = ProjectSocialLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) val adapter = ProjectSocialAdapter() diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectUpdatesActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectUpdatesActivity.kt index 5250c6ad81..3162ddbcf5 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectUpdatesActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectUpdatesActivity.kt @@ -20,6 +20,7 @@ import com.kickstarter.ui.adapters.UpdatesAdapter import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.startActivityWithTransition +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ProjectUpdatesViewModel.Factory import com.kickstarter.viewmodels.ProjectUpdatesViewModel.ProjectUpdatesViewModel import io.reactivex.disposables.CompositeDisposable @@ -40,6 +41,10 @@ class ProjectUpdatesActivity : AppCompatActivity(), UpdatesAdapter.Delegate { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityUpdatesBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/ReportProjectActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ReportProjectActivity.kt index 3395785ca3..a64bce45d5 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ReportProjectActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ReportProjectActivity.kt @@ -7,6 +7,7 @@ import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -14,6 +15,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rxjava2.subscribeAsState import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.kickstarter.R import com.kickstarter.libs.featureflag.FlagKey @@ -76,6 +78,7 @@ class ReportProjectActivity : ComponentActivity() { } Scaffold( + modifier = Modifier.systemBarsPadding(), topBar = { TopToolBar( title = stringResource(id = R.string.Report_this_project), diff --git a/app/src/main/java/com/kickstarter/ui/activities/SetPasswordActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/SetPasswordActivity.kt index e2c11d6fd0..06889dedc8 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/SetPasswordActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/SetPasswordActivity.kt @@ -85,6 +85,7 @@ class SetPasswordActivity : AppCompatActivity() { } else false ) { SetPasswordScreen( + onSaveButtonClicked = { newPassword -> viewModel.inputs.newPassword(newPassword) viewModel.inputs.confirmPassword(newPassword) diff --git a/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt index 4972b68302..c25bfcdbd9 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/SettingsActivity.kt @@ -25,6 +25,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.SharedPreferenceKey import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.SettingsViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -55,6 +56,10 @@ class SettingsActivity : AppCompatActivity() { getString(R.string.dark) ) binding = SettingsLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root, + ) this.getEnvironment()?.let { env -> viewModelFactory = SettingsViewModel.Factory(env) sharedPrefs = env.sharedPreferences() diff --git a/app/src/main/java/com/kickstarter/ui/activities/SurveyResponseActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/SurveyResponseActivity.kt index c27b574d00..cac5d70fca 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/SurveyResponseActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/SurveyResponseActivity.kt @@ -15,6 +15,7 @@ import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.libs.utils.extensions.isProjectSurveyUri import com.kickstarter.libs.utils.extensions.isProjectUri import com.kickstarter.services.RequestHandler +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.SurveyResponseViewModel import io.reactivex.disposables.CompositeDisposable import okhttp3.Request @@ -42,6 +43,10 @@ class SurveyResponseActivity : ComponentActivity() { factory = SurveyResponseViewModel.Factory(environment = env, intent = intent) } binding = SurveyResponseLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) binding.surveyResponseWebView.registerRequestHandlers( diff --git a/app/src/main/java/com/kickstarter/ui/activities/ThanksActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ThanksActivity.kt index 17281ea9f7..bc685ab069 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ThanksActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ThanksActivity.kt @@ -25,6 +25,7 @@ import com.kickstarter.ui.adapters.ThanksAdapter import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck import com.kickstarter.ui.extensions.showRatingDialogWidget import com.kickstarter.ui.extensions.startActivityWithTransition +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ThanksViewModel import com.kickstarter.viewmodels.ThanksViewModel.Factory import io.reactivex.android.schedulers.AndroidSchedulers @@ -42,6 +43,10 @@ class ThanksActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ThanksLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) getEnvironment()?.let { env -> diff --git a/app/src/main/java/com/kickstarter/ui/activities/ThreadActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ThreadActivity.kt index 29de03ada6..dd11e35242 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ThreadActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ThreadActivity.kt @@ -22,6 +22,7 @@ import com.kickstarter.ui.adapters.RepliesStatusAdapter import com.kickstarter.ui.adapters.RootCommentAdapter import com.kickstarter.ui.extensions.hideKeyboard import com.kickstarter.ui.views.OnCommentComposerViewClickedListener +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.ThreadViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -59,6 +60,10 @@ class ThreadActivity : super.onCreate(savedInstanceState) binding = ActivityThreadLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) val environment = this.getEnvironment()?.let { env -> viewModelFactory = ThreadViewModel.Factory(env) diff --git a/app/src/main/java/com/kickstarter/ui/activities/UpdateActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/UpdateActivity.kt index 948703548e..b99a836297 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/UpdateActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/UpdateActivity.kt @@ -24,6 +24,7 @@ import com.kickstarter.models.Update import com.kickstarter.services.RequestHandler import com.kickstarter.ui.IntentKey import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.UpdateViewModel import io.reactivex.disposables.CompositeDisposable import okhttp3.Request @@ -47,7 +48,10 @@ class UpdateActivity : AppCompatActivity() { disposables = CompositeDisposable() binding = UpdateLayoutBinding.inflate(layoutInflater) - + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) setUpConnectivityStatusCheck(lifecycle) diff --git a/app/src/main/java/com/kickstarter/ui/activities/VideoActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/VideoActivity.kt index a4c243fccb..e13bae5614 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/VideoActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/VideoActivity.kt @@ -30,6 +30,7 @@ import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.getEnvironment import com.kickstarter.ui.IntentKey import com.kickstarter.ui.extensions.setUpConnectivityStatusCheck +import com.kickstarter.utils.WindowInsetsUtil import com.kickstarter.viewmodels.VideoViewModel.Factory import com.kickstarter.viewmodels.VideoViewModel.VideoViewModel import io.reactivex.android.schedulers.AndroidSchedulers @@ -55,6 +56,10 @@ class VideoActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = VideoPlayerLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) val environment = this.getEnvironment()?.let { env -> diff --git a/app/src/main/java/com/kickstarter/ui/activities/WebViewActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/WebViewActivity.kt index 6f72667a69..8b18716c06 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/WebViewActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/WebViewActivity.kt @@ -7,6 +7,7 @@ import com.kickstarter.databinding.WebViewLayoutBinding import com.kickstarter.ui.IntentKey import com.kickstarter.ui.extensions.finishWithAnimation import com.kickstarter.ui.views.KSWebView +import com.kickstarter.utils.WindowInsetsUtil class WebViewActivity : ComponentActivity() { private lateinit var binding: WebViewLayoutBinding @@ -14,6 +15,10 @@ class WebViewActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = WebViewLayoutBinding.inflate(layoutInflater) + WindowInsetsUtil.manageEdgeToEdge( + window, + binding.root + ) setContentView(binding.root) val toolbarTitle = intent.getStringExtra(IntentKey.TOOLBAR_TITLE) diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/ChangePasswordScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/ChangePasswordScreen.kt index bc07b460d8..c9e40ed594 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/ChangePasswordScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/ChangePasswordScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -109,6 +110,7 @@ fun ChangePasswordScreen( val focusManager = LocalFocusManager.current Scaffold( + modifier = Modifier.systemBarsPadding(), scaffoldState = scaffoldState, topBar = { TopToolBar( diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/FormularyScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/FormularyScreen.kt index 027e3d4ab6..1dba0cd93d 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/FormularyScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/FormularyScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.Button @@ -80,6 +81,7 @@ fun FormularyScreen( Column( modifier = Modifier + .systemBarsPadding() .animateContentSize() .fillMaxSize() .verticalScroll(rememberScrollState()) diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/PreLaunchProjectPageScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/PreLaunchProjectPageScreen.kt index f1d6f53765..16e7ffd0b6 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/PreLaunchProjectPageScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/PreLaunchProjectPageScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Card import androidx.compose.material.Scaffold @@ -91,6 +92,7 @@ fun PreLaunchProjectPageScreen( ) { val project = projectState.value Scaffold( + modifier = Modifier.systemBarsPadding(), topBar = { TopToolBar( right = { diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/ReportProjectScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/ReportProjectScreen.kt index 755c8ae126..fedb533e47 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/ReportProjectScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/ReportProjectScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.text.ClickableText @@ -44,8 +45,18 @@ import com.kickstarter.viewmodels.ReportProjectViewModel import type.FlaggingKind @Composable -@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2, name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) -@Preview(showBackground = true, backgroundColor = 0X00000000, name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview( + showBackground = true, + backgroundColor = 0xFFF0EAE2, + name = "Light", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + showBackground = true, + backgroundColor = 0X00000000, + name = "Dark", + uiMode = Configuration.UI_MODE_NIGHT_YES +) fun PreviewTextLinks() { KSTheme { TextWithClickableLink(html = stringResource(id = R.string.Projects_may_not_offer)) @@ -53,8 +64,18 @@ fun PreviewTextLinks() { } @Composable -@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2, name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) -@Preview(showBackground = true, backgroundColor = 0X00000000, name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview( + showBackground = true, + backgroundColor = 0xFFF0EAE2, + name = "Light", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + showBackground = true, + backgroundColor = 0X00000000, + name = "Dark", + uiMode = Configuration.UI_MODE_NIGHT_YES +) fun ReportProjectScreenPreview() { KSTheme { ReportProjectCategoryScreen(PaddingValues()) @@ -62,8 +83,18 @@ fun ReportProjectScreenPreview() { } @Composable -@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2, name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) -@Preview(showBackground = true, backgroundColor = 0X00000000, name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview( + showBackground = true, + backgroundColor = 0xFFF0EAE2, + name = "Light", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + showBackground = true, + backgroundColor = 0X00000000, + name = "Dark", + uiMode = Configuration.UI_MODE_NIGHT_YES +) fun CategoryRowPreview() { KSTheme { val list = rulesMap().values.first() @@ -73,8 +104,18 @@ fun CategoryRowPreview() { } @Composable -@Preview(showBackground = true, backgroundColor = 0xFFF0EAE2, name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) -@Preview(showBackground = true, backgroundColor = 0X00000000, name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview( + showBackground = true, + backgroundColor = 0xFFF0EAE2, + name = "Light", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + showBackground = true, + backgroundColor = 0X00000000, + name = "Dark", + uiMode = Configuration.UI_MODE_NIGHT_YES +) fun RulesListPreview() { KSTheme { val list = rulesMap().values.first() @@ -91,11 +132,31 @@ fun rulesMap(): Map, List, List, List AddOnsScreen( - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .systemBarsPadding(), environment = Environment.Builder().build(), lazyColumnListState = rememberLazyListState(), selectedReward = RewardFactory.reward().toBuilder().minimum(5.0).build(), diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/AiDisclosureScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/AiDisclosureScreen.kt index 15a26bd88b..8503cfdb2d 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/AiDisclosureScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/AiDisclosureScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -87,6 +88,7 @@ fun AiDisclosureScreen( Column( modifier = Modifier .fillMaxWidth() + .systemBarsPadding() .background(colors.kds_white) .padding( PaddingValues( diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt index f1c3ddd4ad..999fff37cd 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/CheckoutScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.selection.selectable @@ -360,6 +361,7 @@ fun CheckoutScreen( } Column( modifier = Modifier + .systemBarsPadding() .verticalScroll(rememberScrollState()) .padding(padding) ) { diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt index ba006a537c..286cb0d88d 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/ProjectPledgeButtonAndFragmentContainer.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState @@ -149,7 +150,7 @@ fun ProjectPledgeButtonAndFragmentContainer( onDisclaimerItemClicked: (disclaimerItem: DisclaimerItems) -> Unit, onAccountabilityLinkClicked: () -> Unit ) { - Column { + Column(modifier = Modifier.systemBarsPadding()) { Surface( modifier = Modifier .fillMaxWidth(), @@ -182,7 +183,7 @@ fun ProjectPledgeButtonAndFragmentContainer( Box( modifier = Modifier .fillMaxWidth() - .padding(dimensions.paddingMediumLarge) + .padding(dimensions.paddingXLarge) ) { KSPrimaryGreenButton( onClickAction = onContinueClicked, diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt index b42dd70a6a..39690bc6f7 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items @@ -59,7 +60,9 @@ fun RewardCarouselScreenPreview() { backgroundColor = KSTheme.colors.backgroundAccentGraySubtle ) { padding -> RewardCarouselScreen( - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .systemBarsPadding(), lazyRowState = rememberLazyListState(), environment = Environment.Builder().build(), rewards = (0..10).map { diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/search/SearchScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/search/SearchScreen.kt index 429ac00eac..73c255bf70 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/search/SearchScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/search/SearchScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.itemsIndexed @@ -122,6 +123,7 @@ fun SearchScreen( var currentSearchTerm by rememberSaveable { mutableStateOf("") } Scaffold( + modifier = Modifier.systemBarsPadding(), scaffoldState = scaffoldState, topBar = { Surface(elevation = 3.dp) { diff --git a/app/src/main/java/com/kickstarter/ui/toolbars/compose/ToolBar.kt b/app/src/main/java/com/kickstarter/ui/toolbars/compose/ToolBar.kt index aa406d7b34..cb2728735a 100644 --- a/app/src/main/java/com/kickstarter/ui/toolbars/compose/ToolBar.kt +++ b/app/src/main/java/com/kickstarter/ui/toolbars/compose/ToolBar.kt @@ -162,6 +162,7 @@ fun TopToolBarBetaIcon( right() }, backgroundColor = backgroundColor ?: colors.kds_white + ) } diff --git a/app/src/main/java/com/kickstarter/utils/WindowInsetsUtil.kt b/app/src/main/java/com/kickstarter/utils/WindowInsetsUtil.kt new file mode 100644 index 0000000000..17840b4892 --- /dev/null +++ b/app/src/main/java/com/kickstarter/utils/WindowInsetsUtil.kt @@ -0,0 +1,54 @@ +package com.kickstarter.utils + +import android.view.View +import android.view.ViewGroup +import android.view.Window +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updateLayoutParams + +object WindowInsetsUtil { + + /** + * Configures the window for edge-to-edge content display and applies system bar insets + * (status bar and navigation bar) as padding or margins to avoid content overlap. + * + * This method makes the content extend to the edges of the screen and adjusts the view's + * layout parameters to ensure it doesn't overlap with system UI elements such as + * the status bar or navigation bar. + * + * @param window The window of the current activity or fragment. + * @param rootView The root view where the system bar insets will be applied. + */ + fun manageEdgeToEdge( + window: Window, + rootView: View + ) { + // Set the window to allow drawing under the system bars (status, nav bars), + // making them transparent, and enabling edge-to-edge display. + WindowCompat.setDecorFitsSystemWindows(window, false) + + // Listen for window insets (which represent system UI like status and navigation bars) + // and apply those insets to the view's layout parameters. + ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, windowInsets -> + // Extract the insets that represent the system bars (status and navigation bars) + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + + // Update the view's layout margins with the insets so the content avoids overlapping + // with system bars. You can choose to apply top, left, bottom, and right insets as needed. + v.updateLayoutParams { + // Apply the left, right, top, and bottom margins based on the insets + leftMargin = insets.left + bottomMargin = insets.bottom + rightMargin = insets.right + topMargin = insets.top + } + + // Return CONSUMED to indicate that the window insets have been handled and + // should not be passed down to child views. If you want child views to handle insets, + // you can return the windowInsets instead. + WindowInsetsCompat.CONSUMED + } + } +} diff --git a/app/src/main/java/com/kickstarter/viewmodels/ThreadViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/ThreadViewModel.kt index a252ee4280..13dd221860 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/ThreadViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/ThreadViewModel.kt @@ -407,7 +407,7 @@ interface ThreadViewModel { /** reversed replies **/ apolloPaginate .paginatedData() - ?.map { it.reversed() } + ?.map { it.asReversed() } ?.compose(Transformers.combineLatestPair(this.hasPreviousElements)) ?.distinctUntilChanged() ?.share() diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml index 182dbefcd9..1a6972b33f 100644 --- a/app/src/main/res/layout/activity_account.xml +++ b/app/src/main/res/layout/activity_account.xml @@ -11,7 +11,10 @@ + android:layout_height="wrap_content" + android:id="@+id/account_appbar_layout" + android:background="@color/kds_white"> + diff --git a/app/src/main/res/layout/activity_edit_profile.xml b/app/src/main/res/layout/activity_edit_profile.xml index dc49aaba6f..941935dce2 100644 --- a/app/src/main/res/layout/activity_edit_profile.xml +++ b/app/src/main/res/layout/activity_edit_profile.xml @@ -1,234 +1,235 @@ - - - + android:layout_height="match_parent" + android:background="@color/kds_support_100" + android:orientation="vertical"> - + - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="match_parent"> - - - - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/grid_3" + android:focusable="true" + android:focusableInTouchMode="true" + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + diff --git a/app/src/main/res/layout/activity_feed_layout.xml b/app/src/main/res/layout/activity_feed_layout.xml index 522da12591..283446dff0 100644 --- a/app/src/main/res/layout/activity_feed_layout.xml +++ b/app/src/main/res/layout/activity_feed_layout.xml @@ -1,25 +1,27 @@ - + - - + + + - + - + diff --git a/app/src/main/res/layout/activity_feed_toolbar.xml b/app/src/main/res/layout/activity_feed_toolbar.xml index 71c465384d..8c98f5db0b 100644 --- a/app/src/main/res/layout/activity_feed_toolbar.xml +++ b/app/src/main/res/layout/activity_feed_toolbar.xml @@ -1,27 +1,26 @@ - + + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:orientation="horizontal"> - + android:id="@+id/back_button" + style="@style/ToolbarIconBackButton" /> + + style="@style/ToolbarTitle" + android:text="@string/activity_creator_navigation_header_activity" /> diff --git a/app/src/main/res/layout/activity_help_settings.xml b/app/src/main/res/layout/activity_help_settings.xml index b4c3ce8062..e0c0b8ff10 100644 --- a/app/src/main/res/layout/activity_help_settings.xml +++ b/app/src/main/res/layout/activity_help_settings.xml @@ -7,8 +7,10 @@ android:orientation="vertical"> + android:id="@+id/toolbar_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/kds_white"> diff --git a/app/src/main/res/layout/activity_newsletter.xml b/app/src/main/res/layout/activity_newsletter.xml index fd1731b7dc..0c14da19b9 100644 --- a/app/src/main/res/layout/activity_newsletter.xml +++ b/app/src/main/res/layout/activity_newsletter.xml @@ -1,301 +1,294 @@ - - - + android:layout_height="match_parent" + android:background="@color/kds_support_100" + android:orientation="vertical"> - + - - - - + - + - + + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> - + - + - - + - + - + - + + - + - - + - - + - + - + + - + - - + - + - + - + - + + - + - - + - + - + - + - + + - + - - + - + - + - + - + + - + - - + - + - + - + - + + - + - - + - + + - + - + + - + - - - + - + - + - + - + + - + - - + - + - + - + - + + - + - - + - + - + - + - + + - + - - + + + - + - + + + + + + + + - + diff --git a/app/src/main/res/layout/activity_notifications.xml b/app/src/main/res/layout/activity_notifications.xml index f16f41e895..a8738272fa 100644 --- a/app/src/main/res/layout/activity_notifications.xml +++ b/app/src/main/res/layout/activity_notifications.xml @@ -1,374 +1,377 @@ - - - + android:layout_height="match_parent"> - - - - - + android:layout_height="wrap_content"> - - + - - + - - - - - - - + - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="match_parent" + android:background="@color/kds_support_100" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + tools:context="com.kickstarter.ui.activities.NotificationsActivity"> - - - - - - - - - - - - - - - - - + android:divider="@drawable/divider_grey_500_horizontal" + android:orientation="vertical" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + android:showDividers="middle|end"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/app/src/main/res/layout/activity_project_page.xml b/app/src/main/res/layout/activity_project_page.xml index 159eb4e0c6..448ac111f2 100644 --- a/app/src/main/res/layout/activity_project_page.xml +++ b/app/src/main/res/layout/activity_project_page.xml @@ -1,16 +1,16 @@ + android:fitsSystemWindows="false"> + android:fitsSystemWindows="false"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/discovery_layout.xml b/app/src/main/res/layout/discovery_layout.xml index e49e16aba8..5cb7cf2618 100644 --- a/app/src/main/res/layout/discovery_layout.xml +++ b/app/src/main/res/layout/discovery_layout.xml @@ -9,9 +9,10 @@ tools:context=".ui.activities.DiscoveryActivity"> + android:fitsSystemWindows="false"> - + - + - + diff --git a/app/src/main/res/layout/pledge_container.xml b/app/src/main/res/layout/pledge_container.xml index 1f15f2db9e..4a2396f4bb 100644 --- a/app/src/main/res/layout/pledge_container.xml +++ b/app/src/main/res/layout/pledge_container.xml @@ -10,7 +10,7 @@ app:cardCornerRadius="@dimen/card_container_radius" app:cardElevation="@dimen/grid_2" tools:layout_marginTop="620dp" - tools:showIn="@layout/activity_project"> + tools:showIn="@layout/activity_project_page"> - - - + android:layout_height="match_parent"> - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="wrap_content"> - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/project_notification_settings_layout.xml b/app/src/main/res/layout/project_notification_settings_layout.xml index 6f215cc8e4..40b1ffa63d 100644 --- a/app/src/main/res/layout/project_notification_settings_layout.xml +++ b/app/src/main/res/layout/project_notification_settings_layout.xml @@ -1,23 +1,23 @@ - - - + android:layout_height="match_parent" + android:orientation="vertical"> - + - + - + + + diff --git a/app/src/main/res/layout/settings_layout.xml b/app/src/main/res/layout/settings_layout.xml index 179adce8c2..3fd668cc31 100644 --- a/app/src/main/res/layout/settings_layout.xml +++ b/app/src/main/res/layout/settings_layout.xml @@ -10,8 +10,10 @@ android:orientation="vertical"> + android:id="@+id/tool_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/kds_white"> diff --git a/app/src/test/java/com/kickstarter/viewmodels/ThreadViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/ThreadViewModelTest.kt index 670fb6f0ea..448aea54de 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/ThreadViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/ThreadViewModelTest.kt @@ -146,10 +146,10 @@ class ThreadViewModelTest : KSRobolectricTestCase() { .addToDisposable(disposables) vm.outputs.showReplyComposer().subscribe { showReplyComposer.onNext(it) } .addToDisposable(disposables) - // Start the view model with a backed project and comment. val project = ProjectFactory.backedProject().reduceProjectPayload() vm.intent( + Intent().putExtra( IntentKey.COMMENT_CARD_DATA, CommentCardDataFactory.commentCardData().toBuilder().project(project).build() @@ -170,7 +170,6 @@ class ThreadViewModelTest : KSRobolectricTestCase() { .addToDisposable(disposables) vm.outputs.showReplyComposer().subscribe { showReplyComposer.onNext(it) } .addToDisposable(disposables) - // Start the view model with a project and comment. val project = ProjectFactory.project().reduceProjectPayload() vm.intent( @@ -198,6 +197,7 @@ class ThreadViewModelTest : KSRobolectricTestCase() { .addToDisposable(disposables) // Start the view model with a backed project and comment. + val project = ProjectFactory.backedProject().reduceProjectPayload() vm.intent( Intent().putExtra( @@ -283,6 +283,7 @@ class ThreadViewModelTest : KSRobolectricTestCase() { setUpEnvironment(env) // Start the view model with a backed project and comment. + val project = ProjectFactory.project().reduceProjectPayload() vm.intent( Intent().putExtra( @@ -342,7 +343,6 @@ class ThreadViewModelTest : KSRobolectricTestCase() { @Test fun testThreadsViewModel_openCommentGuidelinesLink() { setUpEnvironment() - val project = ProjectFactory.project().reduceProjectPayload() vm.intent( Intent().putExtra( @@ -407,7 +407,6 @@ class ThreadViewModelTest : KSRobolectricTestCase() { val onReplies = BehaviorSubject.create, Boolean>>() val vm = ThreadViewModel.ThreadViewModel(env) - val project = ProjectFactory.project().reduceProjectPayload() vm.intent( Intent().putExtra( @@ -495,7 +494,6 @@ class ThreadViewModelTest : KSRobolectricTestCase() { val vm = ThreadViewModel.ThreadViewModel(env) // Start the view model with a backed project and comment. - val project = ProjectFactory.project().reduceProjectPayload() vm.intent( Intent().putExtra( diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4352ff2f88..9e773f392c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jan 26 16:41:20 PST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME