Skip to content

ALTAPPS-468: Android edge to edge support #1092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8c96344
Enable edge-to-edge format
XanderZhu Jun 4, 2024
20d1396
Merge branch 'develop' into feature/ALTAPPS-468/Android-edge-to-edge-…
XanderZhu Jun 20, 2024
f019169
Merge branch 'develop' into feature/ALTAPPS-468/Android-edge-to-edge-…
XanderZhu Jun 21, 2024
f78c852
Apply edge-to-edge for auth & onboarding
XanderZhu Jun 21, 2024
51acf35
Apply insets to GamificationToolbar
XanderZhu Jun 24, 2024
33d0ca1
Apply insets to Profile
XanderZhu Jun 24, 2024
b8089ee
Apply insets to TopicSearch screen
XanderZhu Jun 24, 2024
e2f2333
Rewrite ScreenDataLoadingError to compose from views
XanderZhu Jun 24, 2024
89030c6
Use insetter inside doOnApplyWindowInsets
XanderZhu Jun 24, 2024
112368e
Apply insets to Paywall
XanderZhu Jun 24, 2024
8337d60
Apply insets to ManageSubscription
XanderZhu Jun 24, 2024
4a09a26
Fix insets applying on ManageSubscription & PaywallScreens
XanderZhu Jun 24, 2024
e72a692
Apply insets to Progress screen
XanderZhu Jun 24, 2024
209a128
Apply insets to Project list & details screens
XanderZhu Jun 24, 2024
98d9354
Apply insets to TopicsRepetition screens
XanderZhu Jun 25, 2024
889307a
Apply insets to Track selection screens
XanderZhu Jun 25, 2024
9ac39a6
Apply insets to StepPracticeFragment
XanderZhu Jun 25, 2024
c664b87
Apply insets to Step screen
XanderZhu Jun 25, 2024
cce68cb
Apply insets to the full screen code editor
XanderZhu Jun 27, 2024
8e7c03b
Apply insets to TopicCompleted screen
XanderZhu Jun 27, 2024
6c71023
Merge branch 'develop' into feature/ALTAPPS-468/Android-edge-to-edge-…
XanderZhu Jun 27, 2024
c948817
Apply insets to the StageImplementationFragment
XanderZhu Jun 27, 2024
b9010b8
Apply insets to the ProfileSettingsDialogFragment
XanderZhu Jun 27, 2024
5f663e3
Clean up
XanderZhu Jun 27, 2024
fde849a
fix ktlint & detekt
XanderZhu Jun 27, 2024
f434be0
Clear binding after onDestroy view
XanderZhu Jun 27, 2024
27d7920
Clean up
XanderZhu Jun 27, 2024
295b7ce
Merge branch 'develop' into feature/ALTAPPS-468/Android-edge-to-edge-…
ivan-magda Jun 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions androidHyperskillApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
implementation(libs.android.ui.constraintlayout)
implementation(libs.android.ui.swiperefreshlayout)
implementation(libs.android.ui.core.ktx)
implementation(libs.android.ui.activity.ktx)
implementation(libs.android.ui.fragment)
implementation(libs.android.ui.fragment.ktx)
implementation(libs.android.lifecycle.runtime)
Expand Down Expand Up @@ -71,6 +72,7 @@ dependencies {
implementation(libs.android.splashscreen)
implementation(libs.android.timepicker)
implementation(libs.android.lottie)
implementation(libs.android.ui.insetter)

implementation(platform(libs.compose.bom))
implementation(libs.compose.ui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import by.kirich1409.viewbindingdelegate.viewBinding
import co.touchlab.kermit.Logger
import dev.chrisbanes.insetter.applyInsetter
import org.hyperskill.app.android.HyperskillApp
import org.hyperskill.app.android.R
import org.hyperskill.app.android.auth.view.ui.navigation.AuthFlow
Expand Down Expand Up @@ -59,6 +60,7 @@ class AuthCredentialsFragment :

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
applyWindowInsets()
initViewStateDelegate()
viewBinding.emailEditText.inputType =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
Expand Down Expand Up @@ -113,6 +115,14 @@ class AuthCredentialsFragment :
authCredentialsViewModel.onNewMessage(AuthCredentialsFeature.Message.ViewedEventMessage)
}

private fun applyWindowInsets() {
viewBinding.authEmailFragment.applyInsetter {
type(statusBars = true, navigationBars = true) {
padding()
}
}
}

private fun injectComponent() {
val authCredentialsComponent = HyperskillApp.graph().buildAuthCredentialsComponent()
val platformAuthComponent =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.google.android.gms.auth.api.signin.GoogleSignInStatusCodes
import com.google.android.gms.common.Scopes
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.Scope
import dev.chrisbanes.insetter.applyInsetter
import org.hyperskill.app.android.BuildConfig
import org.hyperskill.app.android.HyperskillApp
import org.hyperskill.app.android.R
Expand Down Expand Up @@ -132,6 +133,8 @@ class AuthSocialFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

applyWindowInsets()

with(viewBinding.signInWithEmailMaterialButton) {
isVisible = !isInSignUpMode
setOnClickListener {
Expand Down Expand Up @@ -164,6 +167,14 @@ class AuthSocialFragment :
authSocialViewModel.onNewMessage(AuthSocialFeature.Message.ViewedEventMessage)
}

private fun applyWindowInsets() {
viewBinding.authSocialContentContainer.applyInsetter {
type(statusBars = true, navigationBars = true) {
padding()
}
}
}

override fun onAction(action: AuthSocialFeature.Action.ViewAction) {
when (action) {
is AuthSocialFeature.Action.ViewAction.CompleteAuthFlow ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.webkit.WebView
import androidx.core.view.WindowCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import dev.chrisbanes.insetter.applyInsetter
import org.hyperskill.app.android.HyperskillApp
import org.hyperskill.app.android.R
import org.hyperskill.app.android.auth.view.ui.widget.AuthSocialWebViewClient
Expand Down Expand Up @@ -71,6 +72,17 @@ class AuthSocialWebViewFragment :
injectComponent()
}

override fun onStart() {
super.onStart()
dialog?.window?.let { window ->
window.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
WindowCompat.setDecorFitsSystemWindows(window, false)
}
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding = DialogInAppWebViewBinding.inflate(inflater, container, false)
if (webView == null) {
Expand Down Expand Up @@ -100,6 +112,7 @@ class AuthSocialWebViewFragment :
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
applyWindowInsets()
initViewStateDelegate()
viewBinding.centeredAppbar.centeredToolbar.centeredToolbar.apply {
setNavigationOnClickListener {
Expand All @@ -114,14 +127,20 @@ class AuthSocialWebViewFragment :
)
}

override fun onStart() {
super.onStart()
dialog
?.window
?.let { window ->
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
private fun applyWindowInsets() {
viewBinding.centeredAppbar.centeredToolbar.root.applyInsetter {
type(statusBars = true) {
padding()
}
}
webView?.applyInsetter {
type(navigationBars = true) {
margin()
}
type(ime = true) {
margin()
}
}
}

override fun onDestroyView() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ package org.hyperskill.app.android.code.util

import android.content.Context
import android.view.View
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isInvisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dev.chrisbanes.insetter.Insetter
import org.hyperskill.app.android.R
import org.hyperskill.app.android.code.view.adapter.CodeToolbarAdapter
import org.hyperskill.app.android.code.view.widget.CodeEditorLayout
import org.hyperskill.app.android.view.base.ui.extension.setOnKeyboardOpenListener
import org.hyperskill.app.android.core.extensions.doOnApplyWindowInsets

object CodeEditorKeyboardExtensionUtil {

fun interface CodeEditorKeyboardListener {
fun onCodeEditorKeyboardStateChanged(
isKeyboardShown: Boolean,
insets: WindowInsetsCompat,
toolbarHeight: Int
)
}
Expand All @@ -24,8 +27,8 @@ object CodeEditorKeyboardExtensionUtil {
}

fun setupKeyboardExtension(
context: Context,
rootView: View,
context: Context,
recyclerView: RecyclerView,
codeLayout: CodeEditorLayout,
codeToolbarAdapter: CodeToolbarAdapter,
Expand All @@ -46,38 +49,28 @@ object CodeEditorKeyboardExtensionUtil {

setupRecycler(context, recyclerView, codeToolbarAdapter)

// Flag is necessary,
// because keyboard listener is constantly invoked
// (probably global layout listener reacts to view changes)
var keyboardShown = false

setOnKeyboardOpenListener(
rootView,
onKeyboardHidden = {
if (keyboardShown) {
recyclerView.isInvisible = true
codeLayout.isNestedScrollingEnabled = true
codeEditorKeyboardListener?.onCodeEditorKeyboardStateChanged(
isKeyboardShown = false,
toolbarHeight = 0
)
keyboardShown = false
}
},
onKeyboardShown = {
if (!keyboardShown) {
if (isToolbarEnabled()) {
recyclerView.isInvisible = false
}
codeLayout.isNestedScrollingEnabled = false
codeEditorKeyboardListener?.onCodeEditorKeyboardStateChanged(
isKeyboardShown = true,
toolbarHeight = recyclerView.height
)
keyboardShown = true
rootView.doOnApplyWindowInsets(Insetter.CONSUME_NONE) { _, insets, _ ->
val imeInsetsType = WindowInsetsCompat.Type.ime()
if (insets.isVisible(imeInsetsType)) {
if (isToolbarEnabled()) {
recyclerView.isInvisible = false
}
codeLayout.isNestedScrollingEnabled = false
codeEditorKeyboardListener?.onCodeEditorKeyboardStateChanged(
isKeyboardShown = true,
insets = insets,
toolbarHeight = recyclerView.height
)
} else {
recyclerView.isInvisible = true
codeLayout.isNestedScrollingEnabled = true
codeEditorKeyboardListener?.onCodeEditorKeyboardStateChanged(
isKeyboardShown = false,
insets = insets,
toolbarHeight = 0
)
}
)
}
}

private fun setupRecycler(context: Context, recyclerView: RecyclerView, codeToolbarAdapter: CodeToolbarAdapter) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.hyperskill.app.android.core.extensions

import android.view.View
import dev.chrisbanes.insetter.Insetter
import dev.chrisbanes.insetter.OnApplyInsetsListener

fun View.doOnApplyWindowInsets(
@Insetter.ConsumeOptions consume: Int = Insetter.CONSUME_AUTO,
onApplyInsetsListener: OnApplyInsetsListener
) {
Insetter
.builder()
.setOnApplyInsetsListener(onApplyInsetsListener)
.consume(consume)
.applyToView(this)
}
Loading
Loading