Remove FloatingActionButton library and replace Contacts menu with
native Floating Action Buttons
This commit is contained in:
parent
19031ab346
commit
fd5d2260a2
|
@ -50,6 +50,4 @@ dependencies {
|
|||
// jCard functionality not needed
|
||||
exclude group: 'com.fasterxml.jackson.core'
|
||||
}
|
||||
|
||||
implementation 'com.github.clans:fab:1.6.4'
|
||||
}
|
||||
|
|
|
@ -24,14 +24,12 @@ import android.view.ActionMode
|
|||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.ImageView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
|
@ -51,11 +49,9 @@ import ch.protonmail.android.databinding.ActivityContactsBinding
|
|||
import ch.protonmail.android.permissions.PermissionHelper
|
||||
import ch.protonmail.android.utils.AppUtil
|
||||
import ch.protonmail.android.utils.extensions.showToast
|
||||
import com.github.clans.fab.FloatingActionButton
|
||||
import com.github.clans.fab.FloatingActionMenu
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
// region constants
|
||||
|
@ -74,8 +70,11 @@ class ContactsActivity :
|
|||
|
||||
private lateinit var progressLayoutView: View
|
||||
private lateinit var viewPager: ViewPager
|
||||
private lateinit var addFab: FloatingActionMenu
|
||||
private lateinit var fabContactsAddMenu: FloatingActionButton
|
||||
private lateinit var fabContactsAddContact: FloatingActionButton
|
||||
private lateinit var fabContactsAddContactGroup: FloatingActionButton
|
||||
private lateinit var tabLayoutContacts: TabLayout
|
||||
private var isFabOpen: Boolean = false
|
||||
|
||||
private val contactsViewModel: ContactsViewModel by viewModels()
|
||||
|
||||
|
@ -117,16 +116,26 @@ class ContactsActivity :
|
|||
}
|
||||
binding.tablayoutContacts.setupWithViewPager(viewPager)
|
||||
|
||||
addFab = binding.fabContactsAddMenu
|
||||
binding.fabContactsAddContact.setOnClickListener {
|
||||
fabContactsAddMenu = binding.fabContactsAddMenu
|
||||
fabContactsAddContact = binding.fabContactsAddContact
|
||||
fabContactsAddContactGroup = binding.fabContactsAddContactGroup
|
||||
|
||||
fabContactsAddMenu.setOnClickListener {
|
||||
if (!isFabOpen) {
|
||||
showFabMenu()
|
||||
} else {
|
||||
closeFabMenu()
|
||||
}
|
||||
}
|
||||
|
||||
fabContactsAddContact.setOnClickListener {
|
||||
startActivityForResult(
|
||||
EditContactDetailsActivity.startNewContactActivity(this),
|
||||
REQUEST_CODE_NEW_CONTACT
|
||||
)
|
||||
binding.fabContactsAddMenu.close(false)
|
||||
}
|
||||
|
||||
binding.fabContactsAddContactGroup.setOnClickListener {
|
||||
fabContactsAddContactGroup.setOnClickListener {
|
||||
if (!contactsViewModel.isPaidUser()) {
|
||||
showToast(R.string.paid_plan_needed)
|
||||
return@setOnClickListener
|
||||
|
@ -134,26 +143,22 @@ class ContactsActivity :
|
|||
val intent =
|
||||
AppUtil.decorInAppIntent(Intent(this, ContactGroupEditCreateActivity::class.java))
|
||||
startActivity(intent)
|
||||
binding.fabContactsAddMenu.close(false)
|
||||
}
|
||||
contactsViewModel.fetchContactsResult.observe(
|
||||
this,
|
||||
::onContactsFetchedEvent
|
||||
)
|
||||
|
||||
contactsViewModel.hasConnectivity.observe(
|
||||
this,
|
||||
{ onConnectivityEvent(it) }
|
||||
)
|
||||
contactsViewModel.hasConnectivity.observe(this) { onConnectivityEvent(it) }
|
||||
|
||||
progressLayoutView = binding.layoutProgressContacts
|
||||
tabLayoutContacts = binding.tablayoutContacts
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.contacts_menu, menu)
|
||||
val searchItem = menu?.findItem(R.id.action_search)
|
||||
searchItem?.configureSearch()
|
||||
val searchItem = menu.findItem(R.id.action_search)
|
||||
searchItem.configureSearch()
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
|
@ -250,23 +255,20 @@ class ContactsActivity :
|
|||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (addFab.isOpened) {
|
||||
addFab.close(true)
|
||||
if (isFabOpen) {
|
||||
closeFabMenu()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onPageSelected(position: Int) {
|
||||
addFab.visibility = ViewGroup.VISIBLE
|
||||
val recyclerViewBottomPadding = {
|
||||
val mainFab = addFab.children.first { it is FloatingActionButton }
|
||||
mainFab.height + (window.decorView.height - addFab.bottom) * 2
|
||||
}
|
||||
val recyclerViewBottomPadding =
|
||||
fabContactsAddMenu.height * 2
|
||||
when (position) {
|
||||
0 -> {
|
||||
window.decorView.doOnPreDraw {
|
||||
contactsListFragment.updateRecyclerViewBottomPadding(recyclerViewBottomPadding())
|
||||
contactsListFragment.updateRecyclerViewBottomPadding(recyclerViewBottomPadding)
|
||||
}
|
||||
contactGroupsFragment.apply {
|
||||
if (isAdded && actionMode != null)
|
||||
|
@ -275,7 +277,7 @@ class ContactsActivity :
|
|||
}
|
||||
1 -> {
|
||||
window.decorView.doOnPreDraw {
|
||||
contactGroupsFragment.updateRecyclerViewBottomPadding(recyclerViewBottomPadding())
|
||||
contactGroupsFragment.updateRecyclerViewBottomPadding(recyclerViewBottomPadding)
|
||||
}
|
||||
contactsListFragment.apply {
|
||||
if (isAdded && actionMode != null)
|
||||
|
@ -314,6 +316,22 @@ class ContactsActivity :
|
|||
|
||||
override fun onHasPermission(type: Constants.PermissionType) = onPermissionConfirmed(type)
|
||||
}
|
||||
|
||||
private fun showFabMenu() {
|
||||
isFabOpen = true
|
||||
val rotationLeft = -45f
|
||||
fabContactsAddMenu.animate().rotation(rotationLeft)
|
||||
fabContactsAddContact.animate().translationY(-resources.getDimension(R.dimen.animation_translation_55))
|
||||
fabContactsAddContactGroup.animate().translationY(-resources.getDimension(R.dimen.animation_translation_105))
|
||||
}
|
||||
|
||||
private fun closeFabMenu() {
|
||||
isFabOpen = false
|
||||
val rotationRight = 45f
|
||||
fabContactsAddMenu.animate().rotation(rotationRight)
|
||||
fabContactsAddContact.animate().translationY(0f)
|
||||
fabContactsAddContactGroup.animate().translationY(0f)
|
||||
}
|
||||
}
|
||||
|
||||
class ViewPagerOnPageSelected(private val pageSelected: (Int) -> Unit = {}) : ViewPager.OnPageChangeListener {
|
||||
|
|
|
@ -390,6 +390,10 @@ class ContactsListFragment : BaseFragment(), IContactsFragment {
|
|||
adapter = contactsAdapter
|
||||
addItemDecoration(itemDecoration)
|
||||
}
|
||||
|
||||
contactsRecyclerView.setOnScrollChangeListener { _, _, _, _, _ ->
|
||||
listener.selectPage(0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateRecyclerViewBottomPadding(@Px size: Int) {
|
||||
|
|
|
@ -1,268 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Proton AG
|
||||
*
|
||||
* This file is part of Proton Mail.
|
||||
*
|
||||
* Proton Mail is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Proton Mail is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
package ch.protonmail.android.views.contactDetails;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import ch.protonmail.android.R;
|
||||
|
||||
|
||||
public class SquareFloatingButtonView extends androidx.appcompat.widget.AppCompatTextView {
|
||||
|
||||
public static final int FAB_TYPE_SQUARE = 1;
|
||||
public static final int FAB_TYPE_ROUNDED_SQUARE = 2;
|
||||
|
||||
public static final int FAB_SIZE_NORMAL = 10;
|
||||
public static final int FAB_SIZE_MINI = 11;
|
||||
|
||||
|
||||
private int fabType;
|
||||
private int fabSize;
|
||||
private float fabElevation;
|
||||
private int fabColor;
|
||||
private Drawable fabIcon;
|
||||
private int fabIconColor;
|
||||
|
||||
private boolean isCreated;
|
||||
|
||||
public SquareFloatingButtonView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public SquareFloatingButtonView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareFloatingButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
initTypedArray(attrs);
|
||||
}
|
||||
|
||||
|
||||
public void hide() {
|
||||
this.setVisibility(GONE);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
this.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
private void initTypedArray(AttributeSet attrs) {
|
||||
TypedArray ta = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.SquareFloatingButtonView, 0, 0);
|
||||
|
||||
fabType = ta.getInt(R.styleable.SquareFloatingButtonView_fabType, FAB_TYPE_SQUARE);
|
||||
fabSize = ta.getInt(R.styleable.SquareFloatingButtonView_fabSizes, FAB_SIZE_NORMAL);
|
||||
fabElevation = ta.getDimension(R.styleable.SquareFloatingButtonView_fabElevation, getResources().getDimension(R.dimen.fab_default_elevation));
|
||||
fabColor = ta.getColor(R.styleable.SquareFloatingButtonView_fabColor, ContextCompat.getColor(getContext(), R.color.new_purple));
|
||||
fabIcon = ta.getDrawable(R.styleable.SquareFloatingButtonView_fabIcon);
|
||||
fabIconColor = ta.getColor(R.styleable.SquareFloatingButtonView_fabIconColor, -1);
|
||||
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
private void buildView() {
|
||||
isCreated = true;
|
||||
setGravity(Gravity.CENTER);
|
||||
initFabBackground();
|
||||
|
||||
|
||||
initFabIconColor();
|
||||
initFabShadow();
|
||||
createSize();
|
||||
initFabPadding();
|
||||
}
|
||||
|
||||
private void initFabBackground() {
|
||||
Drawable backgroundDrawable;
|
||||
switch (fabType) {
|
||||
case FAB_TYPE_ROUNDED_SQUARE:
|
||||
backgroundDrawable = ContextCompat.getDrawable(getContext(), R.drawable.fab_rounded_square_bg);
|
||||
break;
|
||||
default:
|
||||
backgroundDrawable = ContextCompat.getDrawable(getContext(), R.drawable.fab_square_bg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (backgroundDrawable != null)
|
||||
backgroundDrawable.mutate().setColorFilter(fabColor, PorterDuff.Mode.SRC_IN);
|
||||
|
||||
Drawable selectableDrawable;
|
||||
selectableDrawable = new RippleDrawable(ColorStateList.valueOf(Color.argb(150, 255, 255, 255)),
|
||||
null, backgroundDrawable);
|
||||
|
||||
LayerDrawable backgroundLayers = new LayerDrawable(new Drawable[]{
|
||||
backgroundDrawable,
|
||||
selectableDrawable});
|
||||
|
||||
setBackground(backgroundLayers);
|
||||
}
|
||||
|
||||
private void initFabIconColor() {
|
||||
if (fabIcon != null && fabIconColor != -1) {
|
||||
fabIcon.mutate().setColorFilter(fabIconColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
|
||||
private void initFabPadding() {
|
||||
|
||||
|
||||
int h = fabIcon.getIntrinsicHeight();
|
||||
int w = fabIcon.getIntrinsicWidth();
|
||||
fabIcon.setBounds(0, 0, w, h);
|
||||
setCompoundDrawablePadding(getResources().getDimensionPixelSize(R.dimen.fab_text_horizontal_margin_mini));
|
||||
setCompoundDrawables(fabIcon, null, null, null);
|
||||
|
||||
|
||||
int iconWidth = fabIcon != null ? fabIcon.getIntrinsicWidth() : 0;
|
||||
int iconHeight = fabIcon != null ? fabIcon.getIntrinsicHeight() : 0;
|
||||
|
||||
int paddingSize = fabSize == FAB_SIZE_MINI
|
||||
? getResources().getDimensionPixelSize(R.dimen.fab_text_horizontal_margin_mini)
|
||||
: getResources().getDimensionPixelSize(R.dimen.fab_text_horizontal_margin_normal);
|
||||
|
||||
int normalSize = getResources().getDimensionPixelSize(R.dimen.fab_size_normal);
|
||||
int miniSize = getResources().getDimensionPixelSize(R.dimen.fab_size_mini);
|
||||
|
||||
int horizontalPadding = iconWidth == 0 ? paddingSize
|
||||
: (fabSize == FAB_SIZE_MINI ? (miniSize - iconWidth) / 2 : (normalSize - iconWidth) / 2);
|
||||
int verticalPadding = iconHeight == 0 ? paddingSize
|
||||
: (fabSize == FAB_SIZE_MINI ? (miniSize - iconHeight) / 2 : (normalSize - iconHeight) / 2);
|
||||
|
||||
|
||||
setPaddingRelative(horizontalPadding, verticalPadding, horizontalPadding * 2, verticalPadding);
|
||||
}
|
||||
|
||||
private void initFabShadow() {
|
||||
ViewCompat.setElevation(this, fabElevation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
createSize();
|
||||
}
|
||||
|
||||
private void createSize() {
|
||||
ViewGroup.LayoutParams thisParams = getLayoutParams();
|
||||
|
||||
if (fabSize == FAB_SIZE_MINI) {
|
||||
setMinHeight(getResources().getDimensionPixelSize(R.dimen.fab_size_mini));
|
||||
setMinWidth(getResources().getDimensionPixelSize(R.dimen.fab_size_mini));
|
||||
|
||||
thisParams.width = getResources().getDimensionPixelSize(R.dimen.fab_size_mini);
|
||||
thisParams.height = getResources().getDimensionPixelSize(R.dimen.fab_size_mini);
|
||||
} else {
|
||||
setMinHeight(getResources().getDimensionPixelSize(R.dimen.fab_size_normal));
|
||||
setMinWidth(getResources().getDimensionPixelSize(R.dimen.fab_size_normal));
|
||||
|
||||
thisParams.width = getResources().getDimensionPixelSize(R.dimen.fab_size_normal);
|
||||
thisParams.height = getResources().getDimensionPixelSize(R.dimen.fab_size_normal);
|
||||
|
||||
}
|
||||
|
||||
this.setLayoutParams(thisParams);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (!isCreated) {
|
||||
buildView();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (!isCreated) {
|
||||
buildView();
|
||||
}
|
||||
}
|
||||
|
||||
public int getFabType() {
|
||||
return fabType;
|
||||
}
|
||||
|
||||
public void setFabType(int fabType) {
|
||||
this.fabType = fabType;
|
||||
buildView();
|
||||
}
|
||||
|
||||
public int getFabSize() {
|
||||
return fabSize;
|
||||
}
|
||||
|
||||
public void setFabSize(int fabSize) {
|
||||
this.fabSize = fabSize;
|
||||
buildView();
|
||||
}
|
||||
|
||||
public float getFabElevation() {
|
||||
return fabElevation;
|
||||
}
|
||||
|
||||
public void setFabElevation(float fabElevation) {
|
||||
this.fabElevation = fabElevation;
|
||||
buildView();
|
||||
}
|
||||
|
||||
public int getFabColor() {
|
||||
return fabColor;
|
||||
}
|
||||
|
||||
public void setFabColor(int fabColor) {
|
||||
this.fabColor = fabColor;
|
||||
buildView();
|
||||
}
|
||||
|
||||
public Drawable getFabIcon() {
|
||||
return fabIcon;
|
||||
}
|
||||
|
||||
public void setFabIcon(Drawable fabIcon) {
|
||||
this.fabIcon = fabIcon;
|
||||
buildView();
|
||||
}
|
||||
|
||||
public int getFabIconColor() {
|
||||
return fabIconColor;
|
||||
}
|
||||
|
||||
public void setFabIconColor(int fabIconColor) {
|
||||
this.fabIconColor = fabIconColor;
|
||||
buildView();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<!--
|
||||
~ Copyright (c) 2022 Proton AG
|
||||
~
|
||||
~ This file is part of Proton Mail.
|
||||
~
|
||||
~ Proton Mail is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ Proton Mail is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M10.5,5.6C10.5,7.533 8.933,9.1 7,9.1C6.0717,9.1 5.1815,8.7312 4.5251,8.0749C3.8688,7.4185 3.5,6.5282 3.5,5.6C3.5,3.667 5.067,2.1 7,2.1C8.933,2.1 10.5,3.667 10.5,5.6ZM9.5,5.6C9.5,4.2193 8.3807,3.1 7,3.1C5.6193,3.1 4.5,4.2193 4.5,5.6C4.5,6.9807 5.6193,8.1 7,8.1C8.3807,8.1 9.5,6.9807 9.5,5.6Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M2,12.71L3.71,11H10V10H3.29L1,12.29V15H10V14H2V12.71Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M12,9H13V12H16V13H13V16H12V13H9V12H12V9Z" />
|
||||
</vector>
|
|
@ -1,41 +0,0 @@
|
|||
<!--
|
||||
~ Copyright (c) 2022 Proton AG
|
||||
~
|
||||
~ This file is part of Proton Mail.
|
||||
~
|
||||
~ Proton Mail is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ Proton Mail is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M6.59,1.54C5.5853,1.4852 4.6673,2.1072 4.3457,3.0605C4.024,4.014 4.3775,5.0649 5.21,5.63L4.65,6.46C3.4407,5.6437 2.9262,4.1198 3.3932,2.7376C3.8602,1.3553 5.1934,0.4557 6.65,0.54C7.2519,0.579 7.8322,0.7794 8.33,1.12L7.75,1.94C7.4093,1.6989 7.0069,1.5601 6.59,1.54Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M6.2401,5.7666C6.2437,7.5534 7.6932,9 9.48,9C10.3428,9 11.1699,8.6559 11.7781,8.044C12.3863,7.432 12.7253,6.6028 12.72,5.74C12.709,3.9532 11.2535,2.5127 9.4668,2.52C7.68,2.5274 6.2364,3.9798 6.2401,5.7666ZM7.4087,4.9075C7.7542,4.068 8.5722,3.52 9.48,3.52V3.5C10.7171,3.5 11.72,4.5029 11.72,5.74C11.7281,6.6478 11.1875,7.4707 10.3512,7.8237C9.5148,8.1767 8.5481,7.99 7.9033,7.351C7.2585,6.712 7.0632,5.747 7.4087,4.9075Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M9,13V12H12V9H13V12H16V13H13V16H12V13H9Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M10,11V10H7.35L4,12.23V15H10V14H5V12.77L7.65,11H10Z" />
|
||||
<path
|
||||
android:fillColor="@color/icon_inverted"
|
||||
android:pathData="M6,8H4.35L1,10.23V13H3V12H2V10.77L4.65,9H6V8Z" />
|
||||
</vector>
|
|
@ -17,7 +17,7 @@
|
|||
~ along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
||||
-->
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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/layout_contacts_main_content"
|
||||
|
@ -26,39 +26,54 @@
|
|||
android:fitsSystemWindows="true"
|
||||
tools:context=".contacts.ContactsActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar_contacts"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/coordinatorLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_norm"
|
||||
android:translationZ="@dimen/elevation_m">
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar_contacts"
|
||||
layout="@layout/toolbar" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tablayout_contacts"
|
||||
style="@style/CustomTabLayout"
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar_contacts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:tabGravity="fill"
|
||||
app:tabIndicatorColor="@color/interaction_strong"
|
||||
app:tabMode="fixed" />
|
||||
android:background="@color/background_norm"
|
||||
android:translationZ="@dimen/elevation_m"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<include
|
||||
android:id="@+id/toolbar_contacts"
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tablayout_contacts"
|
||||
style="@style/CustomTabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:tabGravity="fill"
|
||||
app:tabIndicatorColor="@color/interaction_strong"
|
||||
app:tabMode="fixed" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/viewpager_contacts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
android:layout_height="0dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/coordinatorLayout" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_no_connectivity_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/coordinatorLayout" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/layout_progress_contacts"
|
||||
|
@ -66,6 +81,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/background_norm"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ProgressBar
|
||||
|
@ -89,53 +105,50 @@
|
|||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- TODO: library development has discontinued in 2016 -->
|
||||
<com.github.clans.fab.FloatingActionMenu
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_contacts_add_contact"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_m"
|
||||
android:src="@drawable/ic_proton_user_plus"
|
||||
app:backgroundTint="@color/interaction_strong"
|
||||
app:fabSize="mini"
|
||||
app:layout_constraintBottom_toBottomOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintEnd_toEndOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintStart_toStartOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintTop_toTopOf="@id/fab_contacts_add_menu"
|
||||
app:rippleColor="?attr/brand_norm"
|
||||
app:tint="@color/icon_inverted"
|
||||
tools:ignore="VectorDrawableCompat" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_contacts_add_contact_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/margin_m"
|
||||
android:src="@drawable/ic_proton_users_plus"
|
||||
app:backgroundTint="@color/interaction_strong"
|
||||
app:fabSize="mini"
|
||||
app:layout_constraintBottom_toBottomOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintEnd_toEndOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintStart_toStartOf="@id/fab_contacts_add_menu"
|
||||
app:layout_constraintTop_toTopOf="@id/fab_contacts_add_menu"
|
||||
app:rippleColor="?attr/brand_norm"
|
||||
app:tint="@color/icon_inverted"
|
||||
tools:ignore="VectorDrawableCompat" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_contacts_add_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:src="@drawable/ic_proton_plus"
|
||||
app:backgroundTint="@color/interaction_strong"
|
||||
app:fabSize="normal"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:menu_colorNormal="@color/interaction_strong"
|
||||
app:menu_colorPressed="@color/dark_purple_statusbar"
|
||||
app:menu_colorRipple="@color/dark_purple_statusbar"
|
||||
app:menu_icon="@drawable/ic_add_inverted"
|
||||
app:menu_labels_colorNormal="@color/white"
|
||||
app:menu_labels_hideAnimation="@anim/fab_slide_out_to_right"
|
||||
app:menu_labels_position="@integer/fab_label_start"
|
||||
app:menu_labels_showAnimation="@anim/fab_slide_in_from_right"
|
||||
app:menu_labels_showShadow="true"
|
||||
app:menu_labels_singleLine="true"
|
||||
app:menu_labels_textColor="@color/dark_purple"
|
||||
app:menu_labels_textSize="14sp"
|
||||
app:menu_openDirection="up"
|
||||
app:menu_showShadow="true">
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:rippleColor="?attr/brand_norm"
|
||||
app:tint="@color/icon_inverted" />
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/fab_contacts_add_contact"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_contact_add"
|
||||
app:fab_colorNormal="@color/interaction_strong"
|
||||
app:fab_colorPressed="@color/dark_purple_statusbar"
|
||||
app:fab_label="@string/fab_add_contact"
|
||||
app:fab_size="mini"
|
||||
app:menu_colorRipple="@color/dark_purple_statusbar"
|
||||
tools:ignore="VectorDrawableCompat" />
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/fab_contacts_add_contact_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_contacts_group_add"
|
||||
app:fab_colorNormal="@color/interaction_strong"
|
||||
app:fab_colorPressed="@color/dark_purple_statusbar"
|
||||
app:fab_label="@string/fab_add_contact_group"
|
||||
app:fab_size="mini"
|
||||
app:menu_colorRipple="@color/dark_purple_statusbar"
|
||||
tools:ignore="VectorDrawableCompat" />
|
||||
|
||||
</com.github.clans.fab.FloatingActionMenu>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -218,4 +218,7 @@
|
|||
|
||||
<!-- endregion -->
|
||||
|
||||
<dimen name="animation_translation_55">55dp</dimen>
|
||||
<dimen name="animation_translation_105">105dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -29,7 +29,7 @@ import ch.protonmail.android.uitests.robots.contacts.ContactsMatchers.withContac
|
|||
import ch.protonmail.android.uitests.robots.contacts.ContactsMatchers.withContactNameAndEmail
|
||||
import ch.protonmail.android.uitests.robots.mailbox.composer.ComposerRobot
|
||||
import ch.protonmail.android.uitests.robots.mailbox.inbox.InboxRobot
|
||||
import com.github.clans.fab.FloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import me.proton.core.test.android.instrumented.Robot
|
||||
import me.proton.core.test.android.instrumented.utils.StringUtils.stringFromResource
|
||||
import org.hamcrest.CoreMatchers.containsString
|
||||
|
|
Loading…
Reference in New Issue