diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 19d268d08..afa349d56 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -399,7 +399,7 @@
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/Badges.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/Badges.kt
index 922302879..0a6535ab9 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/badges/Badges.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/badges/Badges.kt
@@ -7,6 +7,7 @@ import com.google.android.flexbox.AlignItems
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
+import org.signal.core.util.DimensionUnit
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.badges.models.Badge
@@ -36,8 +37,15 @@ object Badges {
}
.forEach { customPref(it) }
- val perRow = context.resources.getInteger(R.integer.badge_columns)
- val empties = (perRow - (badges.size % perRow)) % perRow
+ val gutter = context.resources.getDimensionPixelSize(R.dimen.dsl_settings_gutter)
+ val buffer = DimensionUnit.DP.toPixels(12f)
+ val gutterExtra = gutter - buffer
+ val badgeSize = DimensionUnit.DP.toPixels(88f)
+ val windowWidth = context.resources.displayMetrics.widthPixels
+ val availableWidth = windowWidth - gutterExtra
+ val perRow = (availableWidth / badgeSize).toInt()
+
+ val empties = ((perRow - (badges.size % perRow)) % perRow)
repeat(empties) {
customPref(Badge.EmptyModel())
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt
index fae8eda99..aa243e778 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsActivity.kt
@@ -3,49 +3,33 @@ package org.thoughtcrime.securesms.components.settings.app
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import androidx.activity.viewModels
import androidx.navigation.NavDirections
+import io.reactivex.rxjava3.subjects.PublishSubject
+import io.reactivex.rxjava3.subjects.Subject
import org.thoughtcrime.securesms.MainActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.DSLSettingsActivity
+import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository
-import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository
-import org.thoughtcrime.securesms.components.settings.app.subscription.boost.BoostRepository
-import org.thoughtcrime.securesms.components.settings.app.subscription.boost.BoostViewModel
-import org.thoughtcrime.securesms.components.settings.app.subscription.subscribe.SubscribeViewModel
-import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.help.HelpFragment
import org.thoughtcrime.securesms.keyvalue.SettingsValues
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.util.CachedInflater
import org.thoughtcrime.securesms.util.DynamicTheme
-import org.thoughtcrime.securesms.util.FeatureFlags
private const val START_LOCATION = "app.settings.start.location"
private const val NOTIFICATION_CATEGORY = "android.intent.category.NOTIFICATION_PREFERENCES"
private const val STATE_WAS_CONFIGURATION_UPDATED = "app.settings.state.configuration.updated"
-class AppSettingsActivity : DSLSettingsActivity() {
+class AppSettingsActivity : DSLSettingsActivity(), DonationPaymentComponent {
private var wasConfigurationUpdated = false
- private val donationRepository: DonationPaymentRepository by lazy { DonationPaymentRepository(this) }
- private val subscribeViewModel: SubscribeViewModel by viewModels(
- factoryProducer = {
- SubscribeViewModel.Factory(SubscriptionsRepository(ApplicationDependencies.getDonationsService()), donationRepository, FETCH_SUBSCRIPTION_TOKEN_REQUEST_CODE)
- }
- )
-
- private val boostViewModel: BoostViewModel by viewModels(
- factoryProducer = {
- BoostViewModel.Factory(BoostRepository(ApplicationDependencies.getDonationsService()), donationRepository, FETCH_BOOST_TOKEN_REQUEST_CODE)
- }
- )
+ override val donationPaymentRepository: DonationPaymentRepository by lazy { DonationPaymentRepository(this) }
+ override val googlePayResultPublisher: Subject = PublishSubject.create()
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
- warmDonationViewModels()
-
if (intent?.hasExtra(ARG_NAV_GRAPH) != true) {
intent?.putExtra(ARG_NAV_GRAPH, R.navigation.app_settings)
}
@@ -106,15 +90,10 @@ class AppSettingsActivity : DSLSettingsActivity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
- subscribeViewModel.onActivityResult(requestCode, resultCode, data)
- boostViewModel.onActivityResult(requestCode, resultCode, data)
+ googlePayResultPublisher.onNext(DonationPaymentComponent.GooglePayResult(requestCode, resultCode, data))
}
companion object {
-
- private const val FETCH_SUBSCRIPTION_TOKEN_REQUEST_CODE = 1000
- private const val FETCH_BOOST_TOKEN_REQUEST_CODE = 2000
-
@JvmStatic
fun home(context: Context): Intent = getIntentForStartLocation(context, StartLocation.HOME)
@@ -149,13 +128,6 @@ class AppSettingsActivity : DSLSettingsActivity() {
}
}
- private fun warmDonationViewModels() {
- if (FeatureFlags.donorBadges()) {
- subscribeViewModel
- boostViewModel
- }
- }
-
private enum class StartLocation(val code: Int) {
HOME(0),
BACKUPS(1),
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentComponent.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentComponent.kt
new file mode 100644
index 000000000..0ba7c540d
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentComponent.kt
@@ -0,0 +1,11 @@
+package org.thoughtcrime.securesms.components.settings.app.subscription
+
+import android.content.Intent
+import io.reactivex.rxjava3.subjects.Subject
+
+interface DonationPaymentComponent {
+ val donationPaymentRepository: DonationPaymentRepository
+ val googlePayResultPublisher: Subject
+
+ class GooglePayResult(val requestCode: Int, val resultCode: Int, val data: Intent?)
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt
index 531744c00..8876ce8b3 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationPaymentRepository.kt
@@ -1,9 +1,14 @@
package org.thoughtcrime.securesms.components.settings.app.subscription
import android.app.Activity
+import android.content.BroadcastReceiver
+import android.content.Context
import android.content.Intent
+import android.content.IntentFilter
+import android.net.ConnectivityManager
import com.google.android.gms.wallet.PaymentData
import io.reactivex.rxjava3.core.Completable
+import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.logging.Log
@@ -13,6 +18,7 @@ import org.signal.donations.GooglePayPaymentSource
import org.signal.donations.StripeApi
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobmanager.JobTracker
+import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
import org.thoughtcrime.securesms.keyvalue.SignalStore
@@ -48,11 +54,25 @@ import java.util.concurrent.TimeUnit
*/
class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFetcher, StripeApi.SetupIntentHelper {
+ private val application = activity.application
private val googlePayApi = GooglePayApi(activity, StripeApi.Gateway(Environment.Donations.STRIPE_CONFIGURATION), Environment.Donations.GOOGLE_PAY_CONFIGURATION)
private val stripeApi = StripeApi(Environment.Donations.STRIPE_CONFIGURATION, this, this, ApplicationDependencies.getOkHttpClient())
fun isGooglePayAvailable(): Completable = googlePayApi.queryIsReadyToPay()
+ fun internetConnectionObserver(): Observable = Observable.create {
+ val observer = object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ if (!it.isDisposed) {
+ it.onNext(NetworkConstraint.isMet(application))
+ }
+ }
+ }
+
+ it.setCancellable { application.unregisterReceiver(observer) }
+ application.registerReceiver(observer, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
+ }
+
fun requestTokenFromGooglePay(price: FiatMoney, label: String, requestCode: Int) {
googlePayApi.requestPayment(price, label, requestCode)
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt
index 9896a7d91..9e3c6d00d 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostFragment.kt
@@ -24,11 +24,14 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationEvent
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationExceptions
+import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
import org.thoughtcrime.securesms.components.settings.app.subscription.models.CurrencySelection
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.components.settings.models.Progress
+import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.help.HelpFragment
+import org.thoughtcrime.securesms.keyboard.findListener
import org.thoughtcrime.securesms.util.BottomSheetUtil.requireCoordinatorLayout
import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.LifecycleDisposable
@@ -42,7 +45,12 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
layoutId = R.layout.boost_bottom_sheet
) {
- private val viewModel: BoostViewModel by viewModels(ownerProducer = { requireActivity() })
+ private val viewModel: BoostViewModel by viewModels(
+ factoryProducer = {
+ BoostViewModel.Factory(BoostRepository(ApplicationDependencies.getDonationsService()), donationPaymentComponent.donationPaymentRepository, FETCH_BOOST_TOKEN_REQUEST_CODE)
+ }
+ )
+
private val lifecycleDisposable = LifecycleDisposable()
private lateinit var boost1AnimationView: LottieAnimationView
@@ -53,6 +61,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
private lateinit var boost6AnimationView: LottieAnimationView
private lateinit var processingDonationPaymentDialog: AlertDialog
+ private lateinit var donationPaymentComponent: DonationPaymentComponent
private val sayThanks: CharSequence by lazy {
SpannableStringBuilder(requireContext().getString(R.string.BoostFragment__say_thanks_and_earn, 30))
@@ -65,6 +74,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
}
override fun bindAdapter(adapter: DSLSettingsAdapter) {
+ donationPaymentComponent = findListener()!!
viewModel.refresh()
CurrencySelection.register(adapter)
@@ -277,5 +287,6 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
companion object {
private val TAG = Log.tag(BoostFragment::class.java)
+ private const val FETCH_BOOST_TOKEN_REQUEST_CODE = 2000
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostViewModel.kt
index fe11847fe..76167b99a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostViewModel.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/BoostViewModel.kt
@@ -8,6 +8,7 @@ import com.google.android.gms.wallet.PaymentData
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.subjects.PublishSubject
@@ -32,14 +33,28 @@ class BoostViewModel(
private val store = Store(BoostState(currencySelection = SignalStore.donationsValues().getBoostCurrency()))
private val eventPublisher: PublishSubject = PublishSubject.create()
private val disposables = CompositeDisposable()
+ private val networkDisposable: Disposable
val state: LiveData = store.stateLiveData
val events: Observable = eventPublisher.observeOn(AndroidSchedulers.mainThread())
private var boostToPurchase: Boost? = null
+ init {
+ networkDisposable = donationPaymentRepository
+ .internetConnectionObserver()
+ .distinctUntilChanged()
+ .subscribe { isConnected ->
+ if (!disposables.isDisposed && isConnected && store.state.stage == BoostState.Stage.FAILURE) {
+ store.update { it.copy(stage = BoostState.Stage.INIT) }
+ refresh()
+ }
+ }
+ }
+
override fun onCleared() {
- disposables.clear()
+ networkDisposable.dispose()
+ disposables.dispose()
}
fun getSupportedCurrencyCodes(): List {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ActiveSubscriptionPreference.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ActiveSubscriptionPreference.kt
index 34a555d49..bc57223fb 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ActiveSubscriptionPreference.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/manage/ActiveSubscriptionPreference.kt
@@ -59,7 +59,7 @@ object ActiveSubscriptionPreference {
expiry.text = context.getString(
R.string.MySupportPreference__renews_s,
- DateUtils.formatDate(
+ DateUtils.formatDateWithYear(
Locale.getDefault(),
model.renewalTimestamp
)
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt
index cec6f25d7..c9aa695dc 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeFragment.kt
@@ -21,11 +21,15 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationEvent
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationExceptions
+import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
+import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository
import org.thoughtcrime.securesms.components.settings.app.subscription.models.CurrencySelection
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.components.settings.models.Progress
+import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.help.HelpFragment
+import org.thoughtcrime.securesms.keyboard.findListener
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
import org.thoughtcrime.securesms.subscription.Subscription
import org.thoughtcrime.securesms.util.CommunicationActions
@@ -41,8 +45,6 @@ class SubscribeFragment : DSLSettingsFragment(
layoutId = R.layout.subscribe_fragment
) {
- private val viewModel: SubscribeViewModel by viewModels(ownerProducer = { requireActivity() })
-
private val lifecycleDisposable = LifecycleDisposable()
private val supportTechSummary: CharSequence by lazy {
@@ -56,6 +58,13 @@ class SubscribeFragment : DSLSettingsFragment(
}
private lateinit var processingDonationPaymentDialog: AlertDialog
+ private lateinit var donationPaymentComponent: DonationPaymentComponent
+
+ private val viewModel: SubscribeViewModel by viewModels(
+ factoryProducer = {
+ SubscribeViewModel.Factory(SubscriptionsRepository(ApplicationDependencies.getDonationsService()), donationPaymentComponent.donationPaymentRepository, FETCH_SUBSCRIPTION_TOKEN_REQUEST_CODE)
+ }
+ )
override fun onResume() {
super.onResume()
@@ -63,6 +72,7 @@ class SubscribeFragment : DSLSettingsFragment(
}
override fun bindAdapter(adapter: DSLSettingsAdapter) {
+ donationPaymentComponent = findListener()!!
viewModel.refresh()
BadgePreview.register(adapter)
@@ -92,6 +102,9 @@ class SubscribeFragment : DSLSettingsFragment(
is DonationEvent.SubscriptionCancellationFailed -> onSubscriptionFailedToCancel(it.throwable)
}
}
+ lifecycleDisposable += donationPaymentComponent.googlePayResultPublisher.subscribe {
+ viewModel.onActivityResult(it.requestCode, it.resultCode, it.data)
+ }
}
private fun getConfiguration(state: SubscribeState): DSLConfiguration {
@@ -302,5 +315,6 @@ class SubscribeFragment : DSLSettingsFragment(
companion object {
private val TAG = Log.tag(SubscribeFragment::class.java)
+ private const val FETCH_SUBSCRIPTION_TOKEN_REQUEST_CODE = 1000
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeViewModel.kt
index b6c54b12c..dfedf6c42 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeViewModel.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/subscribe/SubscribeViewModel.kt
@@ -9,6 +9,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.subjects.PublishSubject
@@ -38,6 +39,7 @@ class SubscribeViewModel(
private val store = Store(SubscribeState(currencySelection = SignalStore.donationsValues().getSubscriptionCurrency()))
private val eventPublisher: PublishSubject = PublishSubject.create()
private val disposables = CompositeDisposable()
+ private val networkDisposable: Disposable
val state: LiveData = store.stateLiveData
val events: Observable = eventPublisher.observeOn(AndroidSchedulers.mainThread())
@@ -45,8 +47,21 @@ class SubscribeViewModel(
private var subscriptionToPurchase: Subscription? = null
private val activeSubscriptionSubject = PublishSubject.create()
+ init {
+ networkDisposable = donationPaymentRepository
+ .internetConnectionObserver()
+ .distinctUntilChanged()
+ .subscribe { isConnected ->
+ if (!disposables.isDisposed && isConnected && store.state.stage == SubscribeState.Stage.FAILURE) {
+ store.update { it.copy(stage = SubscribeState.Stage.INIT) }
+ refresh()
+ }
+ }
+ }
+
override fun onCleared() {
- disposables.clear()
+ networkDisposable.dispose()
+ disposables.dispose()
}
fun getPriceOfSelectedSubscription(): FiatMoney? {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java
index 19681b701..0e85ef5e8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java
@@ -83,6 +83,7 @@ import org.thoughtcrime.securesms.MainNavigator;
import org.thoughtcrime.securesms.MuteDialog;
import org.thoughtcrime.securesms.NewConversationActivity;
import org.thoughtcrime.securesms.R;
+import org.thoughtcrime.securesms.badges.BadgeImageView;
import org.thoughtcrime.securesms.badges.models.Badge;
import org.thoughtcrime.securesms.badges.self.expired.ExpiredBadgeBottomSheetDialogFragment;
import org.thoughtcrime.securesms.components.RatingManager;
@@ -519,6 +520,9 @@ public class ConversationListFragment extends MainFragment implements ActionMode
private void initializeProfileIcon(@NonNull Recipient recipient) {
ImageView icon = requireView().findViewById(R.id.toolbar_icon);
+ BadgeImageView imageView = requireView().findViewById(R.id.toolbar_badge);
+ imageView.setBadgeFromRecipient(recipient);
+
AvatarUtil.loadIconIntoImageView(recipient, icon, getResources().getDimensionPixelSize(R.dimen.toolbar_avatar_size));
icon.setOnClickListener(v -> getNavigator().goToAppSettings());
}
diff --git a/app/src/main/res/layout/conversation_list_fragment.xml b/app/src/main/res/layout/conversation_list_fragment.xml
index b5f9b0420..a52222f51 100644
--- a/app/src/main/res/layout/conversation_list_fragment.xml
+++ b/app/src/main/res/layout/conversation_list_fragment.xml
@@ -1,7 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/banner_barrier">
-
+
-
+
-
+
-
+
-
+
-
+
+
+
diff --git a/app/src/main/res/values-sw360dp/dimens.xml b/app/src/main/res/values-sw360dp/dimens.xml
index 016e4c879..7efc0f0b1 100644
--- a/app/src/main/res/values-sw360dp/dimens.xml
+++ b/app/src/main/res/values-sw360dp/dimens.xml
@@ -32,6 +32,4 @@
34dp
32dp
-
- 4
\ No newline at end of file
diff --git a/app/src/main/res/values-sw480dp/dimens.xml b/app/src/main/res/values-sw480dp/dimens.xml
index 5882581c1..80c9e9b46 100644
--- a/app/src/main/res/values-sw480dp/dimens.xml
+++ b/app/src/main/res/values-sw480dp/dimens.xml
@@ -2,6 +2,4 @@
350dp
300dp
-
- 5
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 91c3de8fe..dbd5ed969 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -210,7 +210,5 @@
16dp
- 3
-
18dp