Commit 91a43428 authored by Antonia Wüst's avatar Antonia Wüst

Merge branch 'dev' of https://gitlab.akamu.de/akamu/game-client-android into dev

parents c4f16f68 be60e2f5
......@@ -40,7 +40,11 @@ public class App extends Application implements SettingsDataSource.FetchSettings
public void onCreate() {
super.onCreate();
SharedPreferences prefs = android.preference.PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String defaultLanguage = prefs.getString(Constants.USER_LANG, getApplicationContext().getResources().getString(R.string.pref_language_eng_value));
String deviceLang = Locale.getDefault().getDisplayLanguage();
String langEN = getApplicationContext().getResources().getString(R.string.pref_language_eng_value);
String langDE = getApplicationContext().getResources().getString(R.string.pref_language_ger_value);
String defaultLang = deviceLang.equals(langEN) || deviceLang.equals(langDE) ? deviceLang : langDE;
String defaultLanguage = prefs.getString(Constants.USER_LANG, defaultLang);
Lingver.init(this, Objects.requireNonNull(defaultLanguage));
boolean isNightMode = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(Constants.IS_NIGHT_MODE, false);
if (isNightMode) {
......@@ -65,6 +69,6 @@ public class App extends Application implements SettingsDataSource.FetchSettings
@Override
public void onFetchSettingsFailed(@NotNull String reason) {
System.out.println("Fetching settings failed.");
System.out.println("Fetching settings failed: " + reason);
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ interface FriendsDataSource {
fun onChallengeRequestSuccess(friendName: String)
fun onChallengeRequestFailed(reason : String)
fun onChallengeRequestFailedNoPoolsSelected()
fun onChallengeRequestFailedNoPoolsInCommon()
}
interface GetAllUsersCallback {
......
......@@ -3,6 +3,7 @@ package de.akamu.tudarmstadt.data.friends
import android.os.AsyncTask
import de.akamu.tudarmstadt.api.V2APIDuel
import de.akamu.tudarmstadt.api.V2APIFriend
import de.akamu.tudarmstadt.api.V2APIPool
import de.akamu.tudarmstadt.api.V2APIUser
import de.akamu.tudarmstadt.exceptions.AkamuAPIException
import de.akamu.tudarmstadt.model.User
......@@ -51,16 +52,24 @@ class FriendsDataSourceImpl : FriendsDataSource {
var errorMessage : String = "Oops! Something went wrong..."
private var noPoolsSelected: Boolean = false
private var noPoolsInCommon: Boolean = false
override fun doInBackground(vararg params: Void?): Boolean {
return try {
V2APIDuel.startDuel(friend.id.toInt())
true
val playablePools = V2APIPool.getPlayablePools()
val myPools = playablePools.filter { pool -> pool.isSelected }
if (myPools.isEmpty()) {
noPoolsSelected = true
false
} else {
V2APIDuel.startDuel(friend.id.toInt())
true
}
} catch (ae : AkamuAPIException) {
ae.printStackTrace()
errorMessage = ae.message!!
if (ae.code == 409) {
noPoolsSelected = true
noPoolsInCommon = true
}
false
} catch (e : Exception) {
......@@ -76,6 +85,8 @@ class FriendsDataSourceImpl : FriendsDataSource {
} else {
if (noPoolsSelected) {
callback.onChallengeRequestFailedNoPoolsSelected()
} else if (noPoolsInCommon) {
callback.onChallengeRequestFailedNoPoolsInCommon()
} else {
callback.onChallengeRequestFailed(errorMessage)
}
......
......@@ -205,6 +205,33 @@ class FriendsListFragment : Fragment(),
infoDialog.show()
}
override fun showSendChallengeRequestFailedNoPoolsInCommon() {
lateinit var infoDialog: AlertDialog
val builder = AlertDialog.Builder(context, R.style.DialogStyle)
builder.setTitle(getString(R.string.no_common_questionpools))
val infoTextView = TextView(requireActivity())
infoTextView.text = getString(R.string.no_common_questionpool_info)
infoTextView.setTextColor(ContextCompat.getColor(requireActivity(), R.color.textLight))
val container = FrameLayout(requireActivity())
val params = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
params.leftMargin = resources.getDimensionPixelSize(R.dimen.dialog_margin)
params.rightMargin = resources.getDimensionPixelSize(R.dimen.dialog_margin)
infoTextView.layoutParams = params
container.addView(infoTextView)
builder.setView(container)
builder.setPositiveButton(getString(R.string.select_your_questionpools)) { _: DialogInterface, _: Int ->
(requireActivity() as MainActivity).navigateToChangeQuestionPools()
}
builder.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.cancel()
}
infoDialog = builder.create()
infoDialog.show()
}
override fun showSendChallengeRequestSuccess(friendName: String) {
Toast.makeText(requireActivity(), friendName + " " + getString(R.string.prompt_challenged_successful), Toast.LENGTH_SHORT).show()
}
......
......@@ -27,6 +27,7 @@ import de.akamu.tudarmstadt.model.User
import de.akamu.tudarmstadt.util.AkamuResource
import de.akamu.tudarmstadt.util.AppUserUtil
import de.akamu.tudarmstadt.util.Constants
import de.akamu.tudarmstadt.util.Extensions.Companion.toast
import kotlinx.android.synthetic.main.activity_main.*
import tyrantgit.explosionfield.ExplosionField
......@@ -88,8 +89,7 @@ class MainActivity : BaseActivity(), DashboardContract.View, NextLevelEventHandl
fillProfile()
setupBottomNavigation()
val pageQuantifier = intent.getIntExtra(Constants.KEY_MAINACTIVITY_PAGE, 0)
when(pageQuantifier) {
when(intent.getIntExtra(Constants.KEY_MAINACTIVITY_PAGE, 0)) {
Constants.DUEL_LIST_FRAGMENT -> navigateToDuelList()
Constants.CHALLENGE_FRAGMENT -> navigateToChallenge()
else -> navigateToDuelList()
......@@ -217,7 +217,7 @@ class MainActivity : BaseActivity(), DashboardContract.View, NextLevelEventHandl
}
override fun onLoadUserFail(reason: String) {
Toast.makeText(this, reason, Toast.LENGTH_SHORT).show()
toast(getString(R.string.load_user_failed, reason))
}
override fun onNextLevelReached() {
......
......@@ -8,6 +8,7 @@ import android.widget.ImageButton
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import de.akamu.tudarmstadt.R
import de.akamu.tudarmstadt.model.Duel
......@@ -137,7 +138,7 @@ class FriendsListAdapter(
sendChallengeButton.visibility = View.VISIBLE
sendChallengeButton.isEnabled = false
sendChallengeButton.animate()?.rotation(360F)?.start()
sendChallengeButton.background = context.getDrawable(R.drawable.md_transparent)
sendChallengeButton.background = ContextCompat.getDrawable(context, R.drawable.md_transparent)
sendChallengeButton.setImageResource(R.drawable.ic_checked_akamu_blue)
}
......
......@@ -18,6 +18,8 @@ interface FriendsListContract {
fun showSendChallengeRequestFailed(reason: String)
/** Let the user know that sending a challenge request has failed because no pool has been selected **/
fun showSendChallengeRequestFailedNoPoolsSelected()
/** Let the user know that sending a challenge request has failed because both players have no common pools **/
fun showSendChallengeRequestFailedNoPoolsInCommon()
/** Let the user know that sending a challenge request was successful **/
fun showSendChallengeRequestSuccess(friendName: String)
/** Bind the SearchListAdapter to the recycler view by passing a list of users **/
......
......@@ -33,6 +33,10 @@ class FriendsListInteractor(private val dataSource: FriendsDataSourceImpl) : Fri
callback.onChallengeRequestFailedNoPoolsSelected()
}
override fun onChallengeRequestFailedNoPoolsInCommon() {
callback.onChallengeRequestFailedNoPoolsInCommon()
}
})
}
......
......@@ -76,6 +76,11 @@ class FriendsListPresenter(
callback.indicateChallengeSentFailed()
}
override fun onChallengeRequestFailedNoPoolsInCommon() {
view?.showSendChallengeRequestFailedNoPoolsInCommon()
callback.indicateChallengeSentFailed()
}
})
}
......
......@@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.preference.PreferenceManager
import de.akamu.tudarmstadt.BaseActivity
import de.akamu.tudarmstadt.R
import de.akamu.tudarmstadt.data.login.LoginDataSourceImpl
......@@ -22,13 +23,6 @@ class LoginActivity : BaseActivity(), LoginContract.View {
override lateinit var presenter: LoginContract.Presenter
override fun onStart() {
super.onStart()
if (!presenter.unauthorized) {
presenter.autoLogin()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(R.style.OffWhiteTheme)
......@@ -39,7 +33,8 @@ class LoginActivity : BaseActivity(), LoginContract.View {
this
)
presenter.unauthorized = intent.getBooleanExtra(Constants.KEY_UNAUTHORIZED, false)
val isUnauthorized = intent.getBooleanExtra(Constants.KEY_UNAUTHORIZED, false)
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(Constants.PREF_UNAUTHORIZED, isUnauthorized).apply()
logo_login.start()
......@@ -69,6 +64,13 @@ class LoginActivity : BaseActivity(), LoginContract.View {
}
}
override fun onStart() {
super.onStart()
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.PREF_UNAUTHORIZED, true)) {
presenter.autoLogin()
}
}
override fun showLoginFailed() {
toast(getString(R.string.invalid_username_or_password))
}
......@@ -89,6 +91,7 @@ class LoginActivity : BaseActivity(), LoginContract.View {
override fun isLoggedIn(loggedIn: Boolean, appUser: User) {
if (loggedIn) {
AppUserUtil.updateLocalAppUser(appUser, this)
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(Constants.PREF_UNAUTHORIZED, false).apply()
startActivity(Intent(this, MainActivity::class.java))
finish()
}
......
......@@ -41,8 +41,6 @@ interface LoginContract {
interface Presenter : BasePresenter {
var unauthorized : Boolean
/** Checks if the user is already logged in and if so, navigates to MainActivity */
fun autoLogin()
......
package de.akamu.tudarmstadt.features.login
import androidx.preference.PreferenceManager
import de.akamu.tudarmstadt.api.AkamuFirebase
import de.akamu.tudarmstadt.api.V2API
import de.akamu.tudarmstadt.data.login.LoginDataSource
import de.akamu.tudarmstadt.model.User
import de.akamu.tudarmstadt.util.Constants
class LoginPresenter(private val interactor: LoginInteractor, var view: LoginContract.View?) : LoginContract.Presenter {
override var unauthorized: Boolean = false
init {
view?.presenter = this
}
......
......@@ -15,6 +15,7 @@ import com.stepstone.stepper.VerificationError
import de.akamu.tudarmstadt.R
import de.akamu.tudarmstadt.features.signup.SignupActivity
import de.akamu.tudarmstadt.features.signup.SignupContract
import de.akamu.tudarmstadt.util.Constants
import de.akamu.tudarmstadt.util.Extensions.Companion.toast
import kotlinx.android.synthetic.main.fragment_password.*
......@@ -25,8 +26,8 @@ class PasswordFragment : Fragment(), PasswordContract.View, Step {
private var errorStringNotEqual: String = "error"
private var errorStringNotUpperLower: String = "error"
var ve1 : VerificationError? = null
var ve2 : VerificationError? = null
var ve1: VerificationError? = null
var ve2: VerificationError? = null
override lateinit var presenter: PasswordContract.Presenter
override var signupPresenter: SignupContract.Presenter? = null
......@@ -50,10 +51,21 @@ class PasswordFragment : Fragment(), PasswordContract.View, Step {
super.onActivityCreated(savedInstanceState)
signupPresenter = (activity as SignupActivity).presenter
textView_password_info.text = getString(
R.string.password_rules,
Constants.MIN_PASSWORD_LENGTH,
Constants.MAX_PASSWORD_LENGTH
)
val signUpFirstPasswordOnEditorActionListener = SignUpFirstPasswordOnEditorActionListener()
val signUpSecondPasswordOnEditorActionListener = SignUpSecondPasswordOnEditorActionListener()
textinputedittext_signup_password1.setOnEditorActionListener(signUpFirstPasswordOnEditorActionListener)
textinputedittext_signup_password2.setOnEditorActionListener(signUpSecondPasswordOnEditorActionListener)
val signUpSecondPasswordOnEditorActionListener =
SignUpSecondPasswordOnEditorActionListener()
textinputedittext_signup_password1.setOnEditorActionListener(
signUpFirstPasswordOnEditorActionListener
)
textinputedittext_signup_password2.setOnEditorActionListener(
signUpSecondPasswordOnEditorActionListener
)
}
override fun showFirstPasswordValid() {
......@@ -128,12 +140,14 @@ class PasswordFragment : Fragment(), PasswordContract.View, Step {
// activity?.toast(error.errorMessage)
}
private inner class SignUpFirstPasswordOnEditorActionListener : TextView.OnEditorActionListener {
private inner class SignUpFirstPasswordOnEditorActionListener :
TextView.OnEditorActionListener {
override fun onEditorAction(textView: TextView, id: Int, keyEvent: KeyEvent?): Boolean {
if (id == EditorInfo.IME_ACTION_NEXT || id == EditorInfo.IME_NULL) {
presenter.checkFirstPassword(textinputedittext_signup_password1.text.toString())
if(ve1 == null){
val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
if (ve1 == null) {
val imm =
activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
imm!!.hideSoftInputFromWindow(
textinputlayout_signup_password1.windowToken,
InputMethodManager.RESULT_UNCHANGED_SHOWN
......@@ -145,15 +159,17 @@ class PasswordFragment : Fragment(), PasswordContract.View, Step {
}
}
private inner class SignUpSecondPasswordOnEditorActionListener : TextView.OnEditorActionListener {
private inner class SignUpSecondPasswordOnEditorActionListener :
TextView.OnEditorActionListener {
override fun onEditorAction(textView: TextView, id: Int, keyEvent: KeyEvent?): Boolean {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
presenter.checkSecondPassword(
textinputedittext_signup_password1.text.toString(),
textinputedittext_signup_password2.text.toString()
)
if(ve2 == null){
val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
if (ve2 == null) {
val imm =
activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
imm!!.hideSoftInputFromWindow(
textinputlayout_signup_password2.windowToken,
InputMethodManager.RESULT_UNCHANGED_SHOWN
......
......@@ -62,7 +62,7 @@ class PasswordPresenter(var view: PasswordContract.View?)
checkSecondPassword(password1, password2)
}
fun containsUpperAndLowerChar(password: String) : Boolean {
private fun containsUpperAndLowerChar(password: String) : Boolean {
return password != password.toLowerCase(Locale.ROOT)
&& password != password.toUpperCase(Locale.ROOT)
}
......
......@@ -54,5 +54,6 @@ class Constants {
const val BUG_REPORTS_ENABLED_KEY = "BUG_REPORTS_ENABLED_KEY"
const val IS_NIGHT_MODE = "IS_NIGHT_MODE"
const val USER_LANG = "USER_LANG"
const val PREF_UNAUTHORIZED = "PREF_UNAUTHORIZED"
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/Coordinator_profileScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true"
tools:context=".features.profile.ProfileActivity">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/Coordinator_profileScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true"
android:background="@color/white"
tools:context=".features.profile.ProfileActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolBar_profile"
......@@ -16,12 +17,12 @@
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<include
layout="@layout/content_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?android:actionBarSize"/>
android:layout_marginTop="?android:actionBarSize" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".features.profile.ProfileActivity"
tools:showIn="@layout/activity_profile">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".features.profile.ProfileActivity"
tools:showIn="@layout/activity_profile">
<LinearLayout
android:id="@+id/linearLayout2"
......@@ -38,7 +39,7 @@
android:layout_height="match_parent"
android:alpha="1.0"
android:contentDescription="@string/user_avatar"
android:src="@drawable/oval_yellow"/>
android:src="@drawable/oval_yellow" />
</FrameLayout>
......@@ -54,7 +55,7 @@
android:elevation="4dp"
app:layout_constraintBottom_toBottomOf="@+id/framelayout_profile_avatar"
app:layout_constraintEnd_toEndOf="@+id/framelayout_profile_avatar"
app:srcCompat="@drawable/ic_edit_light"/>
app:srcCompat="@drawable/ic_edit_light" />
<TextView
android:id="@+id/username_profile"
......@@ -73,7 +74,7 @@
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/framelayout_profile_avatar"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"/>
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textView_level_profile"
......@@ -84,13 +85,13 @@
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Level"
android:textSize="18sp"
android:textColor="@color/textLight"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/framelayout_profile_avatar"
app:layout_constraintTop_toBottomOf="@+id/username_profile"
tools:ignore="HardcodedText"/>
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/score_profile"
......@@ -107,21 +108,21 @@
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/framelayout_profile_avatar"
app:layout_constraintTop_toBottomOf="@id/textView_level_profile"
tools:ignore="HardcodedText"/>
tools:ignore="HardcodedText" />
<ProgressBar
android:id="@+id/progressbar_score_profile"
android:layout_width="0dp"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/progressbar_rounded"
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="8dp"
android:progressDrawable="@drawable/progressbar_rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/framelayout_profile_avatar"
app:layout_constraintTop_toBottomOf="@+id/score_profile"/>
app:layout_constraintTop_toBottomOf="@+id/score_profile" />
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -134,19 +135,16 @@
android:layout_marginBottom="@dimen/profile_section_title"
android:text="@string/title"
android:textColor="@color/textLight"
android:textStyle="bold"/>
android:textStyle="bold" />
<View
android:id="@+id/sep1"
style="@style/Divider"/>
style="@style/Divider" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/title_profile_edit"
style="@style/TextButtonRipple"
......@@ -162,7 +160,7 @@
android:textSize="18sp"
android:textStyle="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/change_title_edit"
......@@ -178,13 +176,13 @@
app:layout_constraintHorizontal_bias="0.976"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"/>
app:layout_constraintVertical_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/sep2"
style="@style/Divider"/>
style="@style/Divider" />
<TextView
android:id="@+id/title_subjects_profile"
......@@ -195,11 +193,11 @@
android:layout_marginBottom="@dimen/profile_section_title"
android:text="@string/subjects"
android:textColor="@color/textLight"
android:textStyle="bold"/>
android:textStyle="bold" />
<View
android:id="@+id/sep3"
style="@style/Divider"/>
style="@style/Divider" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
......@@ -222,7 +220,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/select_subjects_edit"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"/>
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/select_subjects_edit"
......@@ -238,13 +236,13 @@
app:layout_constraintHorizontal_bias="0.976"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"/>
app:layout_constraintVertical_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/sep4"
style="@style/Divider"/>
style="@style/Divider" />
<TextView
android:id="@+id/title_change_password"
......@@ -255,11 +253,11 @@
android:layout_marginBottom="@dimen/profile_section_title"
android:text="@string/change_your_password"
android:textColor="@color/textLight"
android:textStyle="bold"/>
android:textStyle="bold" />
<View
android:id="@+id/sep5"
style="@style/Divider"/>
style="@style/Divider" />
<androidx.constraintlayout.widget.