Remove v4 flavor and move mailbox view v4 UI to main

We will not use the v4 flavor and instead we will work on v4 on a separate branch.

MAILAND-1495

#comment Affected: Mailbox view UI
This commit is contained in:
stefanija 2021-03-17 15:36:07 +01:00
parent b07b7e5552
commit 331e16c3da
57 changed files with 712 additions and 2116 deletions

View File

@ -138,7 +138,6 @@ android(appIdSuffix = "android") {
register("beta") {
applicationId = "ch.protonmail.android.beta"
}
register("v4")
}
buildTypes {

View File

@ -72,7 +72,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme"
android:theme="@style/ProtonTheme.Mail"
tools:replace="android:theme">
<!-- Disable default WorkManagerInitializer for use Hilt injection -->

View File

@ -18,7 +18,6 @@
*/
package ch.protonmail.android.activities;
import static ch.protonmail.android.core.Constants.FLAVOR_V4;
import static ch.protonmail.android.settings.pin.ValidatePinActivityKt.EXTRA_FRAGMENT_TITLE;
import static ch.protonmail.android.settings.pin.ValidatePinActivityKt.EXTRA_LOGOUT;
import static ch.protonmail.android.settings.pin.ValidatePinActivityKt.EXTRA_PIN_VALID;
@ -54,7 +53,6 @@ import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import ch.protonmail.android.BuildConfig;
import ch.protonmail.android.R;
import ch.protonmail.android.activities.messageDetails.MessageDetailsActivity;
import ch.protonmail.android.adapters.swipe.SwipeProcessor;
@ -79,7 +77,6 @@ import ch.protonmail.android.settings.pin.ValidatePinActivity;
import ch.protonmail.android.utils.AppUtil;
import ch.protonmail.android.utils.CustomLocale;
import ch.protonmail.android.utils.INetworkConfiguratorCallback;
import ch.protonmail.android.utils.UiUtil;
import ch.protonmail.android.worker.FetchMailSettingsWorker;
import ch.protonmail.android.worker.FetchUserInfoWorker;
import dagger.hilt.android.AndroidEntryPoint;
@ -179,10 +176,6 @@ public abstract class BaseActivity extends AppCompatActivity implements INetwork
setSupportActionBar(mToolbar);
}
if (!BuildConfig.FLAVOR.equals(FLAVOR_V4)) {
UiUtil.setStatusBarColor(this, ContextCompat.getColor(this, R.color.dark_purple_statusbar));
}
ForceSwitchedAccountNotifier.notifier.observe(this, event -> {
if (event != null) {
AppUtil.postEventOnUi(event);

View File

@ -51,7 +51,6 @@ import ch.protonmail.android.api.segments.event.AlarmReceiver
import ch.protonmail.android.api.segments.event.FetchUpdatesJob
import ch.protonmail.android.contacts.ContactsActivity
import ch.protonmail.android.core.Constants
import ch.protonmail.android.core.Constants.FLAVOR_V4
import ch.protonmail.android.core.UserManager
import ch.protonmail.android.data.local.MessageDatabase
import ch.protonmail.android.domain.entity.Id
@ -322,9 +321,6 @@ abstract class NavigationActivity :
onUserClicked(false)
drawerHeaderView.switchState()
}
if (BuildConfig.FLAVOR != FLAVOR_V4) {
drawerToggle.syncState()
}
navigationDrawerRecyclerView!!.smoothScrollToPosition(0)
onDrawerClose()
onDrawerClose = {}
@ -494,10 +490,6 @@ abstract class NavigationActivity :
fun onSignOutSelected() {
fun onLogoutConfirmed(currentUserId: Id, hasNextLoggedInUser: Boolean) {
if (BuildConfig.FLAVOR != FLAVOR_V4) {
findViewById<View>(R.id.spinner_layout)?.visibility = View.VISIBLE
}
lifecycleScope.launch {
if (hasNextLoggedInUser) {
overlayDialog =

View File

@ -26,7 +26,6 @@ import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.res.Configuration
import android.graphics.Canvas
import android.graphics.Color
import android.net.Uri
@ -61,7 +60,6 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import androidx.work.WorkInfo
import ch.protonmail.android.BuildConfig
import ch.protonmail.android.R
import ch.protonmail.android.activities.EXTRA_FIRST_LOGIN
import ch.protonmail.android.activities.EXTRA_HAS_SWITCHED_USER
@ -114,7 +112,6 @@ import ch.protonmail.android.api.services.MessagesService.Companion.startFetchMe
import ch.protonmail.android.api.services.MessagesService.Companion.startFetchMessagesByLabel
import ch.protonmail.android.core.Constants
import ch.protonmail.android.core.Constants.DrawerOptionType
import ch.protonmail.android.core.Constants.FLAVOR_V4
import ch.protonmail.android.core.Constants.MessageLocationType
import ch.protonmail.android.core.Constants.MessageLocationType.Companion.fromInt
import ch.protonmail.android.core.Constants.Prefs.PREF_DONT_SHOW_PLAY_SERVICES
@ -186,9 +183,7 @@ import kotlinx.android.synthetic.main.activity_mailbox.*
import kotlinx.android.synthetic.main.activity_mailbox.mailboxRecyclerView
import kotlinx.android.synthetic.main.activity_mailbox.screenShotPreventerView
import kotlinx.android.synthetic.main.activity_mailbox.storageLimitAlert
import kotlinx.android.synthetic.v4.activity_mailbox.*
import kotlinx.android.synthetic.main.fragment_billing.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import me.proton.core.util.android.sharedpreferences.get
@ -201,11 +196,9 @@ import java.lang.ref.WeakReference
import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlin.time.milliseconds
import kotlin.time.seconds
private const val TAG_MAILBOX_ACTIVITY = "MailboxActivity"
private const val ACTION_MESSAGE_DRAFTED = "ch.protonmail.MESSAGE_DRAFTED"
private const val PLAY_SERVICES_RESOLUTION_REQUEST = 9000
private const val STATE_MAILBOX_LOCATION = "mailbox_location"
private const val STATE_MAILBOX_LABEL_LOCATION = "mailbox_label_location"
@ -363,19 +356,14 @@ class MailboxActivity :
mailboxRecyclerView.adapter = messagesAdapter
mailboxRecyclerView.layoutManager = LinearLayoutManager(this)
if (BuildConfig.FLAVOR == FLAVOR_V4) {
val itemDecoration = DividerItemDecoration(mailboxRecyclerView.context, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(getDrawable(R.drawable.list_divider)!!)
mailboxRecyclerView.addItemDecoration(itemDecoration)
}
// Set the list divider
val itemDecoration = DividerItemDecoration(mailboxRecyclerView.context, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(getDrawable(R.drawable.list_divider)!!)
mailboxRecyclerView.addItemDecoration(itemDecoration)
buildSwipeProcessor()
if (BuildConfig.FLAVOR == FLAVOR_V4) {
initializeSwipeRefreshLayout(mailboxSwipeRefreshLayout)
} else {
initializeSwipeRefreshLayout(swipe_refresh_layout)
initializeSwipeRefreshLayout(spinner_layout)
initializeSwipeRefreshLayout(no_messages_layout)
}
initializeSwipeRefreshLayout(mailboxSwipeRefreshLayout)
initializeSwipeRefreshLayout(noMessagesSwipeRefreshLayout)
if (userManager.isFirstMailboxLoad) {
swipeCustomizeSnack = Snackbar.make(
@ -427,6 +415,7 @@ class MailboxActivity :
mailboxLocationMain.observe(this, messagesAdapter::setNewLocation)
messagesLiveData.observe(this, MessagesListObserver(messagesAdapter))
ItemTouchHelper(SwipeController()).attachToRecyclerView(mailboxRecyclerView)
if (extras != null && extras.getBoolean(EXTRA_HAS_SWITCHED_USER, false)) {
@ -644,9 +633,8 @@ class MailboxActivity :
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
if (BuildConfig.FLAVOR == FLAVOR_V4) {
setElevationOnToolbarAndStatusView(false)
}
// Set the elevation to 0 since after account switch the list is scrolled to the top
setElevationOnToolbarAndStatusView(false)
}
private inner class MessagesListObserver(
@ -658,16 +646,6 @@ class MailboxActivity :
}
}
private fun setElevationOnToolbarAndStatusView(shouldIncreaseElevation: Boolean) {
if (shouldIncreaseElevation) {
supportActionBar?.elevation = 32F
mailboxStatusLayout.elevation = 32F
} else {
supportActionBar?.elevation = 0F
mailboxStatusLayout.elevation = 0F
}
}
private val listScrollListener: RecyclerView.OnScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(view: RecyclerView, scrollState: Int) {
scrollStateChanged =
@ -686,13 +664,12 @@ class MailboxActivity :
loadMoreMessages()
}
if (BuildConfig.FLAVOR == FLAVOR_V4) {
val firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()
if (firstVisibleItem == 0) {
setElevationOnToolbarAndStatusView(false)
} else {
setElevationOnToolbarAndStatusView(true)
}
// Increase the elevation if the list is scrolled down and decrease if it is scrolled to the top
val firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()
if (firstVisibleItem == 0) {
setElevationOnToolbarAndStatusView(false)
} else {
setElevationOnToolbarAndStatusView(true)
}
}
@ -718,6 +695,16 @@ class MailboxActivity :
}
}
private fun setElevationOnToolbarAndStatusView(shouldIncreaseElevation: Boolean) {
val elevation = if (shouldIncreaseElevation) {
resources.getDimensionPixelSize(R.dimen.action_bar_elevation)
} else {
resources.getDimensionPixelSize(R.dimen.action_bar_no_elevation)
}.toFloat()
supportActionBar?.elevation = elevation
mailboxStatusLayout.elevation = elevation
}
private fun registerFcmReceiver() {
val filter = IntentFilter(getString(R.string.action_notification))
filter.priority = 2
@ -763,9 +750,6 @@ class MailboxActivity :
syncUUID = UUID.randomUUID().toString()
if (userManager.isBackgroundSyncEnabled) {
setRefreshing(true)
if (BuildConfig.FLAVOR != FLAVOR_V4) {
layout_sync.visibility = View.VISIBLE
}
}
if (firstLogin == null) {
firstLogin = intent.getBooleanExtra(EXTRA_FIRST_LOGIN, false)
@ -861,9 +845,7 @@ class MailboxActivity :
reloadMessageCounts()
registerFcmReceiver()
checkDelinquency()
if (BuildConfig.FLAVOR != FLAVOR_V4) {
no_messages_layout.visibility = View.GONE
}
noMessagesSwipeRefreshLayout.visibility = View.GONE
mailboxViewModel.checkConnectivity()
val mailboxLocation = mailboxLocationMain.value
if (mailboxLocation == MessageLocationType.INBOX) {
@ -903,11 +885,11 @@ class MailboxActivity :
}
private fun setUpMenuItems(composeMenuItem: MenuItem, searchMenuItem: MenuItem) {
composeMenuItem.actionView.findViewById<ImageView>(R.id.composeImageView)
composeMenuItem.actionView.findViewById<ImageView>(R.id.composeImageButton)
.setOnClickListener {
mailboxViewModel.usedSpaceActionEvent(FLOW_TRY_COMPOSE)
}
searchMenuItem.actionView.findViewById<ImageView>(R.id.searchImageView)
searchMenuItem.actionView.findViewById<ImageView>(R.id.searchImageButton)
.setOnClickListener {
val intent = AppUtil.decorInAppIntent(
Intent(
@ -921,55 +903,31 @@ class MailboxActivity :
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.mailbox_options_menu, menu)
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
val mailboxLocation = mailboxLocationMain.value
if (BuildConfig.FLAVOR == FLAVOR_V4) {
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
} else {
menu.findItem(R.id.empty).isVisible =
mailboxLocation in listOf(
MessageLocationType.DRAFT,
MessageLocationType.SPAM,
MessageLocationType.TRASH
)
}
menu.findItem(R.id.empty).isVisible =
mailboxLocation in listOf(MessageLocationType.DRAFT, MessageLocationType.SPAM, MessageLocationType.TRASH)
return true
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.clear()
menuInflater.inflate(R.menu.mailbox_options_menu, menu)
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
val mailboxLocation = mailboxLocationMain.value
if (BuildConfig.FLAVOR == FLAVOR_V4) {
setUpMenuItems(menu.findItem(R.id.compose), menu.findItem(R.id.search))
} else {
menu.findItem(R.id.empty).isVisible =
mailboxLocation in listOf(
MessageLocationType.DRAFT,
MessageLocationType.SPAM,
MessageLocationType.TRASH,
MessageLocationType.LABEL,
MessageLocationType.LABEL_FOLDER
)
}
menu.findItem(R.id.empty).isVisible =
mailboxLocation in listOf(
MessageLocationType.DRAFT,
MessageLocationType.SPAM,
MessageLocationType.TRASH,
MessageLocationType.LABEL,
MessageLocationType.LABEL_FOLDER
)
return super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.search -> {
val intent = AppUtil.decorInAppIntent(
Intent(
this@MailboxActivity,
SearchActivity::class.java
)
)
startActivity(intent)
true
}
R.id.compose -> {
mailboxViewModel.usedSpaceActionEvent(FLOW_TRY_COMPOSE)
true
}
R.id.empty -> {
if (!isFinishing) {
showTwoButtonInfoDialog(
@ -988,20 +946,6 @@ class MailboxActivity :
}
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
if (BuildConfig.FLAVOR != FLAVOR_V4) {
drawerToggle.syncState()
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (BuildConfig.FLAVOR != FLAVOR_V4) {
drawerToggle.syncState()
}
}
override fun onBackPressed() {
saveLastInteraction()
val drawerClosed = closeDrawer()
@ -1013,24 +957,14 @@ class MailboxActivity :
}
private fun initializeSwipeRefreshLayout(swipeRefreshLayoutAux: SwipeRefreshLayout) {
if (BuildConfig.FLAVOR == FLAVOR_V4) {
swipeRefreshLayoutAux.setColorSchemeResources(R.color.cornflower_blue)
} else {
swipeRefreshLayoutAux.setColorSchemeResources(R.color.ultramarine_blue, R.color.lake_blue)
}
swipeRefreshLayoutAux.setColorSchemeResources(R.color.cornflower_blue)
swipeRefreshLayoutAux.setOnRefreshListener(this)
}
fun setRefreshing(shouldRefresh: Boolean) {
Timber.v("setRefreshing shouldRefresh:$shouldRefresh")
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.isRefreshing = shouldRefresh
} else {
swipe_refresh_layout.isRefreshing = shouldRefresh
spinner_layout.isRefreshing = shouldRefresh
no_messages_layout.isRefreshing = shouldRefresh
spinner_layout.visibility = if (shouldRefresh) View.VISIBLE else View.GONE
}
mailboxSwipeRefreshLayout.isRefreshing = shouldRefresh
noMessagesSwipeRefreshLayout.isRefreshing = shouldRefresh
}
private fun setLoadingMore(loadingMore: Boolean): Boolean {
@ -1185,10 +1119,6 @@ class MailboxActivity :
return
}
refreshMailboxJobRunning = false
lifecycleScope.launchWhenCreated {
delay(1.seconds)
SyncDoneRunnable(this@MailboxActivity).run()
}
setLoadingMore(false)
if (!isDohOngoing) {
showToast(event.status)
@ -1225,10 +1155,6 @@ class MailboxActivity :
@Subscribe
fun onMailboxNoMessages(event: MailboxNoMessagesEvent?) {
// show toast only if user initiated load more
lifecycleScope.launchWhenCreated {
delay(300.milliseconds)
SyncDoneRunnable(this@MailboxActivity).run()
}
if (isLoadingMore.get()) {
showToast(R.string.no_more_messages, Toast.LENGTH_SHORT)
messagesAdapter.notifyDataSetChanged()
@ -1238,11 +1164,8 @@ class MailboxActivity :
@Subscribe
fun onUpdatesLoaded(event: FetchUpdatesEvent?) {
syncingDone()
lifecycleScope.launchWhenCreated {
refreshDrawerHeader(userManager.requireCurrentUser())
delay(1.seconds)
SyncDoneRunnable(this@MailboxActivity).run()
}
}
@ -1288,23 +1211,11 @@ class MailboxActivity :
fun refreshEmptyView(count: Int) {
if (count == 0) {
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.visibility = View.GONE
} else {
spinner_layout.visibility = View.GONE
no_messages_layout.visibility = View.VISIBLE
swipe_refresh_layout.visibility = View.GONE
swipe_refresh_wrapper.visibility = View.GONE
}
mailboxSwipeRefreshLayout.visibility = View.GONE
noMessagesSwipeRefreshLayout.visibility = View.VISIBLE
} else {
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.visibility = View.VISIBLE
} else {
spinner_layout.visibility = View.VISIBLE
no_messages_layout.visibility = View.GONE
swipe_refresh_layout.visibility = View.VISIBLE
swipe_refresh_wrapper.visibility = View.VISIBLE
}
mailboxSwipeRefreshLayout.visibility = View.VISIBLE
noMessagesSwipeRefreshLayout.visibility = View.GONE
}
}
@ -1350,11 +1261,7 @@ class MailboxActivity :
menu.removeItem(moveToInbox.itemId)
}
menu.findItem(R.id.move_to_spam).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.isEnabled = false
} else {
swipe_refresh_layout.isEnabled = false
}
mailboxSwipeRefreshLayout.isEnabled = false
return true
}
@ -1521,11 +1428,7 @@ class MailboxActivity :
override fun onDestroyActionMode(mode: ActionMode) {
actionMode = null
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.isEnabled = true
} else {
swipe_refresh_layout.isEnabled = true
}
mailboxSwipeRefreshLayout.isEnabled = true
messagesAdapter.endSelectionMode()
UiUtil.setStatusBarColor(this, ContextCompat.getColor(this, R.color.dark_purple_statusbar))
}
@ -1598,13 +1501,7 @@ class MailboxActivity :
/* SwipeRefreshLayout.OnRefreshListener */
override fun onRefresh() {
if (BuildConfig.FLAVOR != FLAVOR_V4) {
if (!spinner_layout.isRefreshing) {
fetchUpdates(true)
}
} else {
fetchUpdates(true)
}
fetchUpdates(true)
}
/**
@ -1627,34 +1524,12 @@ class MailboxActivity :
)
}
private fun syncingDone() {
if (BuildConfig.FLAVOR != FLAVOR_V4) {
layout_sync.visibility = View.GONE
}
}
private class SyncDoneRunnable internal constructor(activity: MailboxActivity) : Runnable {
private val mailboxActivityWeakReference = WeakReference(activity)
override fun run() {
val mailboxActivity = mailboxActivityWeakReference.get()
mailboxActivity?.syncingDone()
}
}
private fun setupNewMessageLocation(newLocation: Int) {
val newMessageLocationType = fromInt(newLocation)
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxSwipeRefreshLayout.visibility = View.VISIBLE
mailboxSwipeRefreshLayout.isRefreshing = true
setElevationOnToolbarAndStatusView(false)
} else {
swipe_refresh_layout.visibility = View.VISIBLE
swipe_refresh_layout.isRefreshing = true
swipe_refresh_wrapper.visibility = View.VISIBLE
no_messages_layout.visibility = View.GONE
spinner_layout.visibility = View.VISIBLE
}
mailboxSwipeRefreshLayout.visibility = View.VISIBLE
mailboxSwipeRefreshLayout.isRefreshing = true
noMessagesSwipeRefreshLayout.visibility = View.GONE
setElevationOnToolbarAndStatusView(false)
LoaderManager.getInstance(this).destroyLoader(LOADER_ID_LABELS_OFFLINE)
if (actionMode != null) {
actionMode!!.finish()
@ -1728,10 +1603,8 @@ class MailboxActivity :
when (requestCode) {
REQUEST_CODE_TRASH_MESSAGE_DETAILS -> {
if (BuildConfig.FLAVOR != FLAVOR_V4) {
move_to_trash.visibility = View.VISIBLE
handler.postDelayed({ move_to_trash.visibility = View.GONE }, 1000)
}
// move_to_trash.visibility = View.VISIBLE
// handler.postDelayed({ move_to_trash.visibility = View.GONE }, 1000)
}
REQUEST_CODE_VALIDATE_PIN -> {
requireNotNull(data) { "No data for request $requestCode" }
@ -1904,18 +1777,10 @@ class MailboxActivity :
override fun onPostExecute(label: Label?) {
val mailboxActivity = mailboxActivity.get() ?: return
if (BuildConfig.FLAVOR == FLAVOR_V4) {
mailboxActivity.mailboxSwipeRefreshLayout.visibility = View.VISIBLE
mailboxActivity.mailboxSwipeRefreshLayout.isRefreshing = true
mailboxActivity.setElevationOnToolbarAndStatusView(false)
} else {
mailboxActivity.swipe_refresh_layout.visibility = View.VISIBLE
mailboxActivity.swipe_refresh_wrapper.visibility = View.VISIBLE
mailboxActivity.swipe_refresh_layout.isRefreshing = true
mailboxActivity.no_messages_layout.visibility = View.GONE
mailboxActivity.spinner_layout.visibility = View.VISIBLE
}
mailboxActivity.mailboxSwipeRefreshLayout.visibility = View.VISIBLE
mailboxActivity.mailboxSwipeRefreshLayout.isRefreshing = true
mailboxActivity.noMessagesSwipeRefreshLayout.visibility = View.GONE
mailboxActivity.setElevationOnToolbarAndStatusView(false)
if (mailboxActivity.actionMode != null) {
mailboxActivity.actionMode!!.finish()
}

View File

@ -22,10 +22,8 @@ import androidx.recyclerview.widget.RecyclerView
import android.view.View
import ch.protonmail.android.views.messagesList.MessagesListFooterView
import ch.protonmail.android.views.messagesList.MessagesListItemView
import ch.protonmail.android.views.messagesList.MessagesListItemViewV4
sealed class MessagesListViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class MessageViewHolder(val view: MessagesListItemView) : MessagesListViewHolder(view)
class MessageViewHolderV4(val view: MessagesListItemViewV4) : MessagesListViewHolder(view)
class FooterViewHolder(val view: MessagesListFooterView) : MessagesListViewHolder(view)
}

View File

@ -19,19 +19,13 @@
package ch.protonmail.android.adapters.messages
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import ch.protonmail.android.BuildConfig
import android.view.ViewGroup
import ch.protonmail.android.core.Constants
import ch.protonmail.android.core.Constants.FLAVOR_V4
import ch.protonmail.android.data.local.model.*
import ch.protonmail.android.utils.ui.selection.SelectionModeEnum
import ch.protonmail.android.views.messagesList.MessagesListFooterView
import ch.protonmail.android.views.messagesList.MessagesListItemView
import ch.protonmail.android.views.messagesList.MessagesListItemViewV4
class MessagesRecyclerViewAdapter(
private val context: Context,
@ -40,7 +34,6 @@ class MessagesRecyclerViewAdapter(
private var mMailboxLocation = Constants.MessageLocationType.INVALID
private val typeface: Typeface = Typeface.createFromAsset(context.assets, "protonmail-mobile-icons.ttf")
private var labels = mapOf<String, Label>()
private val messages = mutableListOf<Message>()
@ -99,13 +92,7 @@ class MessagesRecyclerViewAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessagesListViewHolder {
return when (ElementType.values()[viewType]) {
ElementType.MESSAGE -> {
if (BuildConfig.FLAVOR == FLAVOR_V4 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MessagesListViewHolder.MessageViewHolderV4(MessagesListItemViewV4(context))
} else {
MessagesListViewHolder.MessageViewHolder(MessagesListItemView(context))
}
}
ElementType.MESSAGE -> MessagesListViewHolder.MessageViewHolder(MessagesListItemView(context))
ElementType.FOOTER -> MessagesListViewHolder.FooterViewHolder(MessagesListFooterView(context))
}
}
@ -115,13 +102,7 @@ class MessagesRecyclerViewAdapter(
override fun onBindViewHolder(holder: MessagesListViewHolder, position: Int) {
when (ElementType.values()[getItemViewType(position)]) {
ElementType.MESSAGE -> {
if (BuildConfig.FLAVOR == FLAVOR_V4) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
(holder as MessagesListViewHolder.MessageViewHolderV4).bindMessage(position)
}
} else {
(holder as MessagesListViewHolder.MessageViewHolder).bindMessage(position)
}
(holder as MessagesListViewHolder.MessageViewHolder).bindMessage(position)
}
ElementType.FOOTER -> {
// NOOP
@ -133,13 +114,9 @@ class MessagesRecyclerViewAdapter(
val message = messages[position]
val messageLabels = message.allLabelIDs.mapNotNull { labels[it] }
val pendingSend = pendingSendList?.find { it.messageId == message.messageId }
// under these conditions the message is in sending process
message.isBeingSent = pendingSend != null && pendingSend.sent == null
message.isAttachmentsBeingUploaded = pendingUploadList?.find { it.messageId == message.messageId } != null
message.senderDisplayName = contactsList?.find { message.senderEmail == it.email }?.name ?: message.senderName
this.view.bind(message, messageLabels, selectedMessageIds.isNotEmpty(), mMailboxLocation, typeface)
this.view.bind(message, messageLabels, mMailboxLocation)
val isSelected = selectedMessageIds.contains(message.messageId)
this.view.isActivated = isSelected
@ -164,35 +141,23 @@ class MessagesRecyclerViewAdapter(
}
}
this.view.setOnLongClickListener {
val messageId = it.tag as String
if (onSelectionModeChange == null) {
return@setOnLongClickListener false
}
if (selectedMessageIds.isEmpty()) {
selectedMessageIds.add(messageId)
onSelectionModeChange.invoke(SelectionModeEnum.STARTED)
notifyDataSetChanged()
}
return@setOnLongClickListener true
}
}
// TODO: Remove annotation when we drop Android 5
@RequiresApi(Build.VERSION_CODES.M)
private fun MessagesListViewHolder.MessageViewHolderV4.bindMessage(position: Int) {
val message = messages[position]
val messageLabels = message.allLabelIDs.mapNotNull { labels[it] }
message.senderDisplayName = contactsList?.find { message.senderEmail == it.email }?.name ?: message.senderName
this.view.bind(message, messageLabels, mMailboxLocation)
this.view.setOnClickListener {
onItemClick?.invoke(message)
}
// TODO: This will be changed with MAILAND-1501.
// I'm just disabling long click with commenting this code for now.
// this.view.setOnLongClickListener {
// val messageId = it.tag as String
// if (onSelectionModeChange == null) {
// return@setOnLongClickListener false
// }
//
// if (selectedMessageIds.isEmpty()) {
// selectedMessageIds.add(messageId)
// onSelectionModeChange.invoke(SelectionModeEnum.STARTED)
// notifyDataSetChanged()
// }
//
// return@setOnLongClickListener true
// }
}
fun endSelectionMode() {

View File

@ -25,9 +25,6 @@ import ch.protonmail.android.R
object Constants {
// flavors
const val FLAVOR_V4 = "v4"
// region Urls
const val REDIRECT_URI = "https://protonmail.ch"
const val ENDPOINT_URI = "https://api.protonmail.ch/"

View File

@ -18,18 +18,14 @@
*/
package ch.protonmail.android.views.messagesList
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.widget.TextViewCompat
import androidx.recyclerview.widget.RecyclerView
import ch.protonmail.android.R
import ch.protonmail.android.core.Constants
@ -37,278 +33,181 @@ import ch.protonmail.android.data.local.model.Label
import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.utils.DateUtil
import ch.protonmail.android.utils.UiUtil
import kotlinx.android.synthetic.main.messages_list_item_new.view.*
import kotlinx.android.synthetic.main.list_item_mailbox.view.*
import me.proton.core.presentation.utils.inflate
// region constants
private const val CHECKBOX_WIDTH_IN_DP = 34
private const val MAX_LABELS_WITH_TEXT = 1
// endregion
class MessagesListItemView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
/**
* A view that represents one item in the mailbox list when conversation mode is turned off.
*/
class MessagesListItemView constructor(
context: Context
) : ConstraintLayout(context) {
init {
inflate(context, R.layout.messages_list_item_new, this)
layoutParams = RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
}
private val mCheckBoxWidthInPixels: Int by lazy {
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
CHECKBOX_WIDTH_IN_DP.toFloat(),
context.resources.displayMetrics).toInt()
}
private val mStrokeWidth by lazy {
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, context
.resources.displayMetrics).toInt()
inflate(R.layout.list_item_mailbox, true)
layoutParams = RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
private var allFolders = HashMap<String, Label>()
private var mIsAnimating = false
fun onSelectionModeChanged(isInSelectionMode: Boolean) {
val start = if (isInSelectionMode) 0 else 1
val end = if (isInSelectionMode) 1 else 0
val animator = ValueAnimator.ofFloat(start.toFloat(), end.toFloat())
private val strokeWidth by lazy {
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
1f,
context
.resources.displayMetrics
).toInt()
}
val startMargin = if (isInSelectionMode) -mCheckBoxWidthInPixels else 0
val endMargin = if (isInSelectionMode) 0 else -mCheckBoxWidthInPixels
val animatorMargin = ValueAnimator.ofInt(startMargin, endMargin)
private fun setIconsTint(isRead: Boolean) {
val iconTint = if (isRead) context.getColor(R.color.icon_weak) else context.getColor(R.color.icon_norm)
animator.addUpdateListener { animation ->
val alpha = animation.animatedValue as Float
checkboxImageView.alpha = alpha
if (alpha == 1.0f) {
checkboxImageView.visibility = View.VISIBLE
} else if (alpha == 0.0f) {
checkboxImageView.visibility = View.GONE
replyImageView.setColorFilter(iconTint)
replyAllImageView.setColorFilter(iconTint)
forwardImageView.setColorFilter(iconTint)
firstLocationImageView.setColorFilter(iconTint)
secondLocationImageView.setColorFilter(iconTint)
thirdLocationImageView.setColorFilter(iconTint)
}
private fun setTextViewStyles(isRead: Boolean) {
if (isRead) {
senderTextView.setTextAppearance(R.style.Text_Default)
subjectTextView.setTextAppearance(R.style.Text_DefaultSmall_Weak)
timeDateTextView.setTextAppearance(R.style.Text_Caption_Weak)
} else {
senderTextView.setTextAppearance(R.style.Text_Default_Bold)
subjectTextView.setTextAppearance(R.style.Text_DefaultSmall_Medium)
timeDateTextView.setTextAppearance(R.style.Text_Caption_Strong)
}
}
private fun getSenderText(messageLocation: Constants.MessageLocationType, message: Message) = when {
messageLocation in arrayOf(
Constants.MessageLocationType.DRAFT,
Constants.MessageLocationType.SENT
) -> message.toListStringGroupsAware
!message.senderDisplayName.isNullOrEmpty() -> message.senderDisplayName
else -> message.senderEmail
}
private fun getIconForMessageLocation(messageLocation: Constants.MessageLocationType) = when (messageLocation) {
Constants.MessageLocationType.INBOX -> R.drawable.ic_inbox
Constants.MessageLocationType.SENT -> R.drawable.ic_send
Constants.MessageLocationType.DRAFT -> R.drawable.ic_draft
Constants.MessageLocationType.ALL_DRAFT -> R.drawable.ic_draft
Constants.MessageLocationType.ALL_SENT -> R.drawable.ic_send
Constants.MessageLocationType.ARCHIVE -> R.drawable.ic_archive
Constants.MessageLocationType.TRASH -> R.drawable.ic_trash
else -> null
}
fun bind(
message: Message,
labels: List<Label>,
mailboxLocation: Constants.MessageLocationType
) {
val readStatus = message.isRead
val messageLocation = Constants.MessageLocationType.fromInt(message.location)
setTextViewStyles(readStatus)
setIconsTint(readStatus)
val senderText = getSenderText(messageLocation, message)
senderTextView.text = senderText
senderInitialTextView.text =
if (senderText.isNullOrEmpty()) "D" else senderText.capitalize().subSequence(0, 1)
subjectTextView.text = message.subject
timeDateTextView.text = DateUtil.formatDateTime(context, message.timeMs)
replyImageView.visibility =
if (message.isReplied == true && message.isRepliedAll != true) View.VISIBLE else View.GONE
replyAllImageView.visibility = if (message.isRepliedAll == true) View.VISIBLE else View.GONE
forwardImageView.visibility = if (message.isForwarded == true) View.VISIBLE else View.GONE
draftImageView.visibility = if (mailboxLocation in arrayOf(
Constants.MessageLocationType.DRAFT,
Constants.MessageLocationType.ALL_DRAFT
)
) View.VISIBLE else View.GONE
// TODO: Currently there's a bug with showing the location on certain messages.
// Revisit the logic with MAILAND-1422
if (mailboxLocation in arrayOf(
Constants.MessageLocationType.ALL_MAIL,
Constants.MessageLocationType.STARRED,
Constants.MessageLocationType.LABEL,
Constants.MessageLocationType.SEARCH
)
) {
val icon = getIconForMessageLocation(messageLocation)
if (icon != null) {
firstLocationImageView.visibility = View.VISIBLE
firstLocationImageView.setImageDrawable(context.getDrawable(icon))
}
}
animatorMargin.addUpdateListener { animation ->
val leftMargin = animation.animatedValue as Int
val hasAttachments = message.Attachments.isNotEmpty() || message.numAttachments >= 1
attachmentImageView.visibility = if (hasAttachments) View.VISIBLE else View.GONE
val paramsTitle = messageTitleContainerLinearLayout.layoutParams as ConstraintLayout.LayoutParams
val paramsSender = messageSenderContainerLinearLayout.layoutParams as ConstraintLayout.LayoutParams
paramsTitle.setMargins(leftMargin, 0, 0, 0)
paramsSender.setMargins(leftMargin, 0, 0, 0)
messageTitleContainerLinearLayout.layoutParams = paramsTitle
messageSenderContainerLinearLayout.layoutParams = paramsSender
mIsAnimating = leftMargin != end
}
starImageView.visibility = if (message.isStarred == true) View.VISIBLE else View.GONE
mIsAnimating = true
animator.start()
animatorMargin.start()
emptySpaceView.visibility = if (
attachmentImageView.visibility == View.VISIBLE ||
starImageView.visibility == View.VISIBLE
) View.VISIBLE else View.GONE
expirationImageView.visibility = if (message.expirationTime > 0) View.VISIBLE else View.GONE
showLabels(labels)
}
// TODO simplify as much as possible
fun bind(message: Message,
labels: List<Label>,
isMultiSelectionMode: Boolean,
mailboxLocation: Constants.MessageLocationType,
typeface: Typeface
) {
val backgroundResId: Int
val primaryTextStyle: Int
val secondaryTextStyle: Int
val read = message.isRead
if (read) {
backgroundResId = R.drawable.read_message_bg_selector
primaryTextStyle = R.style.MessagePrimaryText_Read
secondaryTextStyle = R.style.MessageSecondaryText_Read
} else {
backgroundResId = R.drawable.unread_message_bg_selector
primaryTextStyle = R.style.MessagePrimaryText_Unread
secondaryTextStyle = R.style.MessageSecondaryText_Unread
}
dataContainerConstraintLayout.setBackgroundResource(backgroundResId)
messageTitleTextView.text = message.subject
TextViewCompat.setTextAppearance(messageTitleTextView, primaryTextStyle)
val messageSenderText = when {
Constants.MessageLocationType.fromInt(message.location) in arrayOf(Constants.MessageLocationType.DRAFT,
Constants.MessageLocationType.SENT) -> message.toListStringGroupsAware
!message.senderDisplayName.isNullOrEmpty() -> message.senderDisplayName
else -> message.senderEmail
}
messageSenderTextView.text = messageSenderText
TextViewCompat.setTextAppearance(messageSenderTextView, secondaryTextStyle)
labelsLinearLayout.removeAllViews()
labelsLinearLayout.visibility = View.GONE
val messageLabelsIDs = message.allLabelIDs
val isMessageSentAndTrashed =
message.searchForLocation(Constants.MessageLocationType.SENT.messageLocationTypeValue) &&
messageLabelsIDs.any { it == Constants.MessageLocationType.TRASH.messageLocationTypeValue.toString() }
val isMessageSentAndArchived =
message.searchForLocation(Constants.MessageLocationType.SENT.messageLocationTypeValue) &&
messageLabelsIDs.any { it == Constants.MessageLocationType.ARCHIVE.messageLocationTypeValue.toString() }
//region labels
private fun showLabels(labels: List<Label>) {
// TODO: This is the old labels logic and it should be changed with MAILAND-1502
labelsLayout.removeAllViews()
labelsLayout.visibility = View.GONE
labels.forEach { allFolders[it.id] = it }
val nonExclusiveLabels = labels.filter { !it.exclusive }
var commonHeight = 20
nonExclusiveLabels.forEachIndexed { i, (_, name, colorString) ->
val labelItemView = ItemLabelMarginlessSmallView(context)
val color = when {
colorString.isNotEmpty() -> {
val normalizedColor = UiUtil.normalizeColor(colorString)
Color.parseColor(normalizedColor)
}
else -> 0
}
val color = if (colorString.isNotEmpty()) {
val normalizedColor = UiUtil.normalizeColor(colorString)
Color.parseColor(normalizedColor)
} else 0
if (i < MAX_LABELS_WITH_TEXT) {
labelItemView.bind(name, color, mStrokeWidth)
labelsLinearLayout.visibility = View.VISIBLE
labelsLinearLayout.addView(labelItemView)
labelItemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
labelItemView.bind(name, color, strokeWidth)
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(labelItemView)
labelItemView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
commonHeight = labelItemView.measuredHeight
} else {
val imageView = ImageView(context)
val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
val lp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
lp.setMargins(0, 0, 0, 0)
imageView.layoutParams = lp
imageView.setImageResource(R.drawable.mail_label_collapsed)
imageView.setColorFilter(color)
imageView.layoutParams.height = commonHeight
labelsLinearLayout.visibility = View.VISIBLE
labelsLinearLayout.addView(imageView)
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(imageView)
}
labelItemView.requestLayout()
}
//endregion
messageLabelTrashTextView.visibility =
if (mailboxLocation != Constants.MessageLocationType.TRASH &&
isMessageSentAndTrashed) View.VISIBLE else View.GONE
messageLabelArchiveTextView.visibility =
if (mailboxLocation != Constants.MessageLocationType.ARCHIVE &&
isMessageSentAndArchived) View.VISIBLE else View.GONE
messageStarredTextView.typeface = typeface
messageExpirationTextView.typeface = typeface
messageAttachmentTextView.typeface = typeface
messageReplyTextView.typeface = typeface
messageLabelTrashTextView.typeface = typeface
messageLabelArchiveTextView.typeface = typeface
messageReplyAllTextView.typeface = typeface
messageForwardTextView.typeface = typeface
messageDateTextView.text = DateUtil.formatDateTime(context, message.timeMs)
TextViewCompat.setTextAppearance(messageDateTextView, secondaryTextStyle)
messageExpirationTextView.visibility = if (message.expirationTime > 0) View.VISIBLE else View.GONE
val hasAttachments = message.Attachments.isNotEmpty() || message.numAttachments >= 1 || message.hasPendingUploads()
messageAttachmentTextView.visibility = if (hasAttachments) View.VISIBLE else View.GONE
messageReplyTextView.visibility = if (message.isReplied == true && message.isRepliedAll != true) View.VISIBLE else View.GONE
messageReplyAllTextView.visibility = if (message.isRepliedAll == true) View.VISIBLE else View.GONE
messageForwardTextView.visibility = if (message.isForwarded == true) View.VISIBLE else View.GONE
messageStarredTextView.visibility = if (message.isStarred == true) View.VISIBLE else View.GONE
if (mailboxLocation in arrayOf(Constants.MessageLocationType.STARRED,
Constants.MessageLocationType.LABEL,
Constants.MessageLocationType.SEARCH,
Constants.MessageLocationType.ALL_MAIL,
Constants.MessageLocationType.SENT)) {
val title = if (mailboxLocation == Constants.MessageLocationType.SENT)
message.getFolderTitle()
else
message.getLocationOrFolderTitle()
if (!title.isNullOrEmpty()) {
messageLocationTextView.text = title
messageLocationTextView.visibility = View.VISIBLE
} else {
messageLocationTextView.visibility = View.GONE
}
} else {
messageLocationTextView.visibility = View.GONE
}
// Don't update the margins if the view is currently being animated
if (!mIsAnimating) {
val leftMargin = if (isMultiSelectionMode) 0 else -mCheckBoxWidthInPixels
if (leftMargin < 0) {
checkboxImageView.alpha = 0f
checkboxImageView.visibility = View.GONE
} else {
checkboxImageView.visibility = View.VISIBLE
checkboxImageView.alpha = 1f
}
val paramsTitle = messageTitleContainerLinearLayout.layoutParams as ConstraintLayout.LayoutParams
val paramsSender = messageSenderContainerLinearLayout.layoutParams as ConstraintLayout.LayoutParams
paramsTitle.setMargins(leftMargin, 0, 0, 0)
paramsSender.setMargins(leftMargin, 0, 0, 0)
messageTitleContainerLinearLayout.layoutParams = paramsTitle
messageSenderContainerLinearLayout.layoutParams = paramsSender
}
uploadCircularProgressBar.visibility = if (message.isBeingSent || message.isAttachmentsBeingUploaded) View.VISIBLE else View.GONE
if (message.isAttachmentsBeingUploaded) {
messageDateTextView.text = context.getString(R.string.draft_label_attachments_uploading)
}
if (message.isBeingSent) { // overwrite attachment text so there's no flickering between them
messageDateTextView.text = context.getString(R.string.draft_label_message_uploading)
}
}
private fun Message.hasPendingUploads(): Boolean {
val messageId = messageId
//TODO restore
return false
// return !messageId.isNullOrEmpty()&&PendingUpload.findByMessageId(messageId)!=null
}
private fun Message.getLocationOrFolderTitle(): String? {
var messageLocation = Constants.MessageLocationType.fromInt(location)
for (labelId in allLabelIDs) {
val label = allFolders[labelId]
if (label != null && label.exclusive && label.name.isNotEmpty()) {
return label.name
}
if (labelId.length <= 2) {
messageLocation = Constants.MessageLocationType.fromInt(Integer.valueOf(labelId))
if (messageLocation !in arrayOf(Constants.MessageLocationType.STARRED,
Constants.MessageLocationType.ALL_MAIL,
Constants.MessageLocationType.INVALID,
Constants.MessageLocationType.ALL_DRAFT,
Constants.MessageLocationType.ALL_SENT
)) {
break
}
}
}
return getLocationTitleId(messageLocation)?.let {
context.getString(it)
} ?: ""
}
private fun getLocationTitleId(mailboxLocation: Constants.MessageLocationType): Int? {
return when (mailboxLocation) {
Constants.MessageLocationType.INBOX -> R.string.inbox_option
Constants.MessageLocationType.STARRED -> R.string.starred_option
Constants.MessageLocationType.DRAFT -> R.string.drafts_option
Constants.MessageLocationType.SENT -> R.string.sent_option
Constants.MessageLocationType.ARCHIVE -> R.string.archive_option
Constants.MessageLocationType.TRASH -> R.string.trash_option
Constants.MessageLocationType.SPAM -> R.string.spam_option
Constants.MessageLocationType.ALL_MAIL -> null
else -> R.string.app_name
}
}
private fun Message.getFolderTitle(): String {
return allLabelIDs.asReversed().asSequence().map(allFolders::get).filterNotNull().filter(Label::exclusive).map { it.name }.lastOrNull()
?: ""
}
}

View File

@ -1,217 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.views.messagesList
import android.content.Context
import android.graphics.Color
import android.os.Build.VERSION_CODES.M
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.annotation.RequiresApi
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView
import ch.protonmail.android.R
import ch.protonmail.android.api.models.room.messages.Label
import ch.protonmail.android.api.models.room.messages.Message
import ch.protonmail.android.core.Constants
import ch.protonmail.android.utils.DateUtil
import ch.protonmail.android.utils.UiUtil
import kotlinx.android.synthetic.v4.list_item_mailbox.view.*
private const val MAX_LABELS_WITH_TEXT = 1
/**
* A view that represents one item in the mailbox list when conversation mode is turned off.
*/
// TODO: Remove annotation when we drop Android 5
@RequiresApi(M)
class MessagesListItemViewV4 constructor(
context: Context
) : ConstraintLayout(context) {
init {
inflate(context, R.layout.list_item_mailbox, this)
layoutParams = RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
private var allFolders = HashMap<String, Label>()
private val mStrokeWidth by lazy {
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
1f,
context
.resources.displayMetrics
).toInt()
}
private fun setIconsTint(isRead: Boolean) {
val iconTint = if (isRead) context.getColor(R.color.icon_weak) else context.getColor(R.color.icon_norm)
replyImageView.setColorFilter(iconTint)
replyAllImageView.setColorFilter(iconTint)
forwardImageView.setColorFilter(iconTint)
firstLocationImageView.setColorFilter(iconTint)
secondLocationImageView.setColorFilter(iconTint)
thirdLocationImageView.setColorFilter(iconTint)
}
private fun setTextViewStyles(isRead: Boolean) {
if (isRead) {
senderTextView.setTextAppearance(R.style.Text_Default)
subjectTextView.setTextAppearance(R.style.Text_DefaultSmall_Weak)
timeDateTextView.setTextAppearance(R.style.Text_Caption_Weak)
} else {
senderTextView.setTextAppearance(R.style.Text_Default_Strong)
subjectTextView.setTextAppearance(R.style.Text_DefaultSmall_Strong)
timeDateTextView.setTextAppearance(R.style.Text_Caption_Strong)
}
}
private fun getSenderText(messageLocation: Constants.MessageLocationType, message: Message) = when {
messageLocation in arrayOf(
Constants.MessageLocationType.DRAFT,
Constants.MessageLocationType.SENT
) -> message.toListStringGroupsAware
!message.senderDisplayName.isNullOrEmpty() -> message.senderDisplayName
else -> message.senderEmail
}
private fun getIconForMessageLocation(messageLocation: Constants.MessageLocationType) = when (messageLocation) {
Constants.MessageLocationType.INBOX -> R.drawable.ic_inbox
Constants.MessageLocationType.SENT -> R.drawable.ic_send
Constants.MessageLocationType.DRAFT -> R.drawable.ic_draft
Constants.MessageLocationType.ALL_DRAFT -> R.drawable.ic_draft
Constants.MessageLocationType.ALL_SENT -> R.drawable.ic_send
Constants.MessageLocationType.ARCHIVE -> R.drawable.ic_archive
Constants.MessageLocationType.TRASH -> R.drawable.ic_trash
else -> null
}
fun bind(
message: Message,
labels: List<Label>,
mailboxLocation: Constants.MessageLocationType
) {
val readStatus = message.isRead
val messageLocation = Constants.MessageLocationType.fromInt(message.location)
setTextViewStyles(readStatus)
setIconsTint(readStatus)
val senderText = getSenderText(messageLocation, message)
senderTextView.text = senderText
senderInitialTextView.text =
if (senderText.isNullOrEmpty()) "D" else senderText.capitalize().subSequence(0, 1)
subjectTextView.text = message.subject
timeDateTextView.text = DateUtil.formatDateTime(context, message.timeMs)
replyImageView.visibility =
if (message.isReplied == true && message.isRepliedAll != true) View.VISIBLE else View.GONE
replyAllImageView.visibility = if (message.isRepliedAll == true) View.VISIBLE else View.GONE
forwardImageView.visibility = if (message.isForwarded == true) View.VISIBLE else View.GONE
draftImageView.visibility = if (mailboxLocation in arrayOf(
Constants.MessageLocationType.DRAFT,
Constants.MessageLocationType.ALL_DRAFT
)
) View.VISIBLE else View.GONE
// TODO: Currently there's a bug with showing the location on certain messages.
// Revisit the logic with MAILAND-1422
if (mailboxLocation in arrayOf(
Constants.MessageLocationType.ALL_MAIL,
Constants.MessageLocationType.STARRED,
Constants.MessageLocationType.LABEL,
Constants.MessageLocationType.SEARCH
)
) {
val icon = getIconForMessageLocation(messageLocation)
if (icon != null) {
firstLocationImageView.visibility = View.VISIBLE
firstLocationImageView.setImageDrawable(context.getDrawable(icon))
}
}
val hasAttachments = message.Attachments.isNotEmpty() || message.numAttachments >= 1
attachmentImageView.visibility = if (hasAttachments) View.VISIBLE else View.GONE
starImageView.visibility = if (message.isStarred == true) View.VISIBLE else View.GONE
emptySpaceView.visibility = if (
attachmentImageView.visibility == View.VISIBLE ||
starImageView.visibility == View.VISIBLE
) View.VISIBLE else View.GONE
expirationImageView.visibility = if (message.expirationTime > 0) View.VISIBLE else View.GONE
showLabels(labels)
}
private fun showLabels(labels: List<Label>) {
// TODO: This is the old labels logic and it should be changed with MAILAND-1502
labelsLayout.removeAllViews()
labelsLayout.visibility = View.GONE
labels.forEach { allFolders[it.id] = it }
val nonExclusiveLabels = labels.filter { !it.exclusive }
var commonHeight = 20
nonExclusiveLabels.forEachIndexed { i, (_, name, colorString) ->
val labelItemView = ItemLabelMarginlessSmallView(context)
val color = if (colorString.isNotEmpty()) {
val normalizedColor = UiUtil.normalizeColor(colorString)
Color.parseColor(normalizedColor)
} else 0
if (i < MAX_LABELS_WITH_TEXT) {
labelItemView.bind(name, color, mStrokeWidth)
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(labelItemView)
labelItemView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
commonHeight = labelItemView.measuredHeight
} else {
val imageView = ImageView(context)
val lp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
lp.setMargins(0, 0, 0, 0)
imageView.layoutParams = lp
imageView.setImageResource(R.drawable.mail_label_collapsed)
imageView.setColorFilter(color)
imageView.layoutParams.height = commonHeight
labelsLayout.visibility = View.VISIBLE
labelsLayout.addView(imageView)
}
labelItemView.requestLayout()
}
}
}

View File

@ -22,7 +22,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="1dp" android:color="@color/text_weak" />
<stroke android:width="2px" android:color="@color/text_weak" />
<corners android:radius="3dp" />
</shape>
<corners android:radius="2dp" />
</shape>

View File

@ -25,4 +25,4 @@
<solid android:color="@color/interaction_weak" />
<corners android:radius="6dp" />
</shape>
</shape>

View File

@ -18,12 +18,10 @@
~ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<manifest
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
android:shape="oval">
<application
android:theme="@style/ProtonTheme.Mail"
tools:replace="android:theme" />
<solid android:color="@color/interaction_strong" />
</manifest>
</shape>

View File

@ -18,20 +18,10 @@
~ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<menu
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:shape="oval">
<item
android:id="@+id/search"
android:title="@string/search"
app:actionLayout="@layout/layout_search_action"
app:showAsAction="ifRoom" />
<solid android:color="@color/interaction_strong_pressed" />
<item
android:id="@+id/compose"
android:title="@string/compose_message"
app:actionLayout="@layout/layout_compose_action"
app:showAsAction="ifRoom" />
</menu>
</shape>

View File

@ -18,13 +18,10 @@
~ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<resources>
<string name="inbox_option">Inbox</string>
<string name="starred_option">Starred</string>
<string name="drafts_option">Drafts</string>
<string name="sent_option">Sent</string>
<string name="archive_option">Archive</string>
<string name="trash_option">Trash</string>
<string name="spam_option">Spam</string>
<string name="allmail_option">All Mail</string>
</resources>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/interaction_weak" />
</shape>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/interaction_weak_pressed" />
</shape>

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,12 +18,12 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M12.85,3.8499L12.15,3.1499L8,7.2899L3.85,3.1499L3.15,3.8499L7.29,7.9999L3.15,12.1499L3.85,12.8499L8,8.7099L12.15,12.8499L12.85,12.1499L8.71,7.9999L12.85,3.8499Z"
android:pathData="M15.3093,4.3435L12.8481,1.8799L7.1472,7.5943L6.7867,10.4187L9.6086,10.0577L15.3093,4.3435ZM8.1239,8.0737L12.8486,3.3377L13.8539,4.344L9.1289,9.0802L7.9766,9.2276L8.1239,8.0737ZM9.2558,2.427H2V14.1237H13.6967V8.7198H12.6667V13.0937H3.03V3.457H9.2558V2.427Z"
android:fillColor="@color/icon_norm"
android:fillType="evenOdd"/>
</vector>

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -0,0 +1,16 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportHeight="16"
android:viewportWidth="16">
<path
android:fillColor="@color/icon_norm"
android:pathData="M3,4H13V5H3V4Z"/>
<path
android:fillColor="@color/icon_norm"
android:pathData="M3,8H13V9H3V8Z"/>
<path
android:fillColor="@color/icon_norm"
android:pathData="M13,12H3V13H13V12Z"/>
</vector>

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,15 +18,12 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
android:fillColor="@color/interaction_strong"/>
<path
android:pathData="M30.964,14.5153L27.2722,10.8198L18.7209,19.3915L18.18,23.628L22.413,23.0866L30.964,14.5153ZM20.1859,20.1105L27.273,13.0066L28.7809,14.516L21.6934,21.6203L19.9649,21.8414L20.1859,20.1105ZM21.8837,11.6405H11V29.1856H28.5451V21.0797H27.0001V27.6406H12.545V13.1855H21.8837V11.6405Z"
android:fillColor="@color/icon_inverted"
android:pathData="M3.03,6.8707C3.03,4.7496 4.7496,3.03 6.8707,3.03C8.9919,3.03 10.7115,4.7496 10.7115,6.8707C10.7115,8.9919 8.9919,10.7115 6.8707,10.7115C4.7496,10.7115 3.03,8.9919 3.03,6.8707ZM6.8707,2C4.1807,2 2,4.1807 2,6.8707C2,9.5608 4.1807,11.7415 6.8707,11.7415C8.0302,11.7415 9.0951,11.3364 9.9315,10.6599L13.318,14.0464L14.0463,13.3181L10.6598,9.9316C11.3363,9.0952 11.7415,8.0303 11.7415,6.8707C11.7415,4.1807 9.5608,2 6.8707,2Z"
android:fillColor="@color/icon_norm"
android:fillType="evenOdd"/>
</vector>

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -18,8 +18,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path

View File

@ -24,6 +24,6 @@
<solid android:color="@color/separator_norm" />
<size android:height="1dp" />
<size android:height="2px" />
</shape>
</shape>

View File

@ -17,7 +17,10 @@
~ You should have received a copy of the GNU General Public License
~ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/dark_glacier_blue">
<item android:drawable="@color/glacier_blue" />
android:color="@color/background_secondary">
<item android:drawable="@color/background_norm" />
</ripple>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/circle_background_interaction_strong"
android:state_pressed="false" />
<item
android:drawable="@drawable/circle_background_interaction_strong_pressed"
android:state_pressed="true" />
</selector>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/circle_background_interaction_weak"
android:state_pressed="false" />
<item
android:drawable="@drawable/circle_background_interaction_weak_pressed"
android:state_pressed="true" />
</selector>

View File

@ -29,4 +29,4 @@
android:color="@color/cornflower_blue"
android:state_checked="true" />
</selector>
</selector>

View File

@ -29,4 +29,4 @@
android:color="@color/text_inverted"
android:state_checked="true" />
</selector>
</selector>

View File

@ -1,169 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2020 Proton Technologies AG
This file is part of ProtonMail.
ProtonMail 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.
ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<androidx.drawerlayout.widget.DrawerLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:fitsSystemWindows="true"
tools:context=".activities.mailbox.MailboxActivity">
<FrameLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/toolbar_mailbox"
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<include
layout="@layout/layout_mailbox_status_view"
android:id="@+id/mailboxStatusLayout"
android:layout_width="0dp"
android:layout_height="@dimen/mailbox_status_view_height"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<ch.protonmail.android.views.alerts.StorageLimitAlert
android:id="@+id/storageLimitAlert"
<!-- TODO: Should be removed and replaced with MAILAND-1503 -->
<ch.protonmail.android.views.alerts.StorageLimitAlert
android:id="@+id/storageLimitAlert"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/mailboxStatusLayout"
android:visibility="gone" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/mailboxSwipeRefreshLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/storageLimitAlert">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mailboxRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
tools:listitem="@layout/list_item_mailbox" />
<FrameLayout
android:id="@+id/swipe_refresh_wrapper"
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<!-- TODO: Should be removed and replaced with MAILAND-1549 -->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/noMessagesSwipeRefreshLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/storageLimitAlert"
android:visibility="gone">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mailboxRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
tools:listitem="@layout/messages_list_item_new" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<View
android:id="@+id/screenProtectorView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:id="@+id/layout_sync"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/rain_gray_50"
android:padding="5dp"
android:visibility="gone">
<ch.protonmail.android.views.CustomFontTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/syncing_messages"
android:textColor="@color/white"
android:textStyle="italic"
app:fontName="Roboto-Light.ttf" />
</FrameLayout>
android:text="@string/no_messages"
style="@style/Text.Caption.Hint" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/spinner_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<!-- TODO: Should be removed and replaced with MAILAND-1497 -->
<FrameLayout
android:id="@+id/layout_no_connectivity_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/no_messages_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/no_messages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/no_messages" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/shadow_height"
android:background="@drawable/actionbar_shadow" />
<TextView
android:id="@+id/move_to_trash"
android:layout_width="75dp"
android:layout_height="75dp"
android:background="@android:color/transparent"
android:text="@string/trash_icon"
android:visibility="gone" />
<FrameLayout
android:id="@+id/layout_no_connectivity_info"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<View
android:id="@+id/screenProtectorView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintRight_toRightOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintTop_toTopOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintBottom_toBottomOf="@id/mailboxSwipeRefreshLayout"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true" />
<View
android:id="@+id/screenShotPreventerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/background_norm"
android:clickable="true"
android:focusable="true"
android:visibility="gone" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<include layout="@layout/navigation_drawer" />

View File

@ -34,9 +34,7 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:divider="@null"
tools:listitem="@layout/messages_list_item_new"
/>
tools:listitem="@layout/list_item_mailbox" />
<TextView
android:id="@+id/no_messages"

View File

@ -23,12 +23,14 @@
android:layout_width="@dimen/toolbar_action_layout_size"
android:layout_height="@dimen/toolbar_action_layout_size">
<ImageView
android:id="@+id/composeImageView"
<ImageButton
android:id="@+id/composeImageButton"
android:layout_width="@dimen/button_nav_size"
android:layout_height="@dimen/button_nav_size"
android:layout_gravity="center"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_compose"
android:contentDescription="@null" />
android:tint="@color/icon_inverted"
android:background="@drawable/selector_circle_background_interaction_strong"
android:contentDescription="@string/compose" />
</FrameLayout>
</FrameLayout>

View File

@ -22,26 +22,25 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="@dimen/mailbox_status_view_height"
android:paddingHorizontal="@dimen/mailbox_status_view_padding_horizontal"
android:background="@color/background_norm">
<TextView
android:id="@+id/updatedStatusTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/updated_status_text_view_margin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="Updated Just now"
style="@style/Text.Caption.Hint" />
<!-- TODO: The component will likely have to be changed when the feature is implemented -->
<com.google.android.material.chip.Chip
android:id="@+id/unreadMessagesStatusChip"
android:layout_width="wrap_content"
android:layout_height="@dimen/unread_messages_chip_size"
android:layout_marginHorizontal="@dimen/unread_messages_chip_margin_horizontal"
android:layout_marginVertical="@dimen/unread_messages_chip_margin_vertical"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@ -52,4 +51,4 @@
android:checkable="true"
style="@style/UnreadMessagesStatusChip" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -23,12 +23,13 @@
android:layout_width="@dimen/toolbar_action_layout_size"
android:layout_height="@dimen/toolbar_action_layout_size">
<ImageView
android:id="@+id/searchImageView"
<ImageButton
android:id="@+id/searchImageButton"
android:layout_width="@dimen/button_nav_size"
android:layout_height="@dimen/button_nav_size"
android:layout_gravity="center"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_search"
android:contentDescription="@null" />
android:background="@drawable/selector_circle_background_interaction_weak"
android:contentDescription="@string/search" />
</FrameLayout>
</FrameLayout>

View File

@ -26,7 +26,8 @@
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/mailbox_list_item_padding_horizontal"
android:paddingVertical="@dimen/mailbox_list_item_padding_vertical"
android:orientation="vertical">
android:orientation="vertical"
android:background="@drawable/ripple_background_norm">
<TextView
android:id="@+id/senderInitialTextView"
@ -54,64 +55,64 @@
<ImageView
android:id="@+id/replyImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/senderInitialBarrier"
app:layout_constraintRight_toLeftOf="@id/replyAllImageView"
app:layout_constraintTop_toTopOf="@id/replyAllImageView"
app:layout_constraintBottom_toBottomOf="@id/replyAllImageView"
android:src="@drawable/ic_reply"
android:contentDescription="@null"
android:contentDescription="@string/reply"
app:tint="@color/icon_weak" />
<ImageView
android:id="@+id/replyAllImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/replyImageView"
app:layout_constraintRight_toLeftOf="@id/forwardImageView"
app:layout_constraintTop_toTopOf="@id/forwardImageView"
app:layout_constraintBottom_toBottomOf="@id/forwardImageView"
android:src="@drawable/ic_reply_all"
android:contentDescription="@null"
android:contentDescription="@string/reply_all"
app:tint="@color/icon_weak" />
<ImageView
android:id="@+id/forwardImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/replyAllImageView"
app:layout_constraintRight_toLeftOf="@id/draftImageView"
app:layout_constraintTop_toTopOf="@id/draftImageView"
app:layout_constraintBottom_toBottomOf="@id/draftImageView"
android:src="@drawable/ic_forward"
android:contentDescription="@null"
android:contentDescription="@string/forward"
app:tint="@color/icon_weak" />
<ImageView
android:id="@+id/draftImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/forwardImageView"
app:layout_constraintRight_toLeftOf="@id/senderTextView"
app:layout_constraintTop_toTopOf="@id/senderTextView"
app:layout_constraintBottom_toBottomOf="@id/senderTextView"
android:src="@drawable/ic_draft"
android:contentDescription="@null" />
android:src="@drawable/ic_draft" />
<TextView
android:id="@+id/senderTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_text_margin_horizontal"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/draftImageView"
app:layout_constraintRight_toLeftOf="@id/timeDateTextView"
app:layout_constraintTop_toTopOf="parent"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/Text.Default"
tools:text="@tools:sample/full_names" />
@ -137,16 +138,15 @@
<ImageView
android:id="@+id/firstLocationImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/senderInitialBarrier"
app:layout_constraintRight_toLeftOf="@id/secondLocationImageView"
app:layout_constraintTop_toTopOf="@id/secondLocationImageView"
app:layout_constraintBottom_toBottomOf="@id/secondLocationImageView"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0.0"
android:contentDescription="@null"
app:tint="@color/icon_weak"
android:visibility="gone"
tools:src="@drawable/ic_trash"
@ -154,14 +154,13 @@
<ImageView
android:id="@+id/secondLocationImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/firstLocationImageView"
app:layout_constraintRight_toLeftOf="@id/thirdLocationImageView"
app:layout_constraintTop_toTopOf="@id/thirdLocationImageView"
app:layout_constraintBottom_toBottomOf="@id/thirdLocationImageView"
android:contentDescription="@null"
app:tint="@color/icon_weak"
android:visibility="gone"
tools:src="@drawable/ic_trash"
@ -169,14 +168,13 @@
<ImageView
android:id="@+id/thirdLocationImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:layout_marginEnd="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/secondLocationImageView"
app:layout_constraintRight_toLeftOf="@id/subjectTextView"
app:layout_constraintTop_toTopOf="@id/subjectTextView"
app:layout_constraintBottom_toBottomOf="@id/subjectTextView"
android:contentDescription="@null"
app:tint="@color/icon_weak"
android:visibility="gone"
tools:src="@drawable/ic_trash"
@ -190,7 +188,8 @@
app:layout_constraintRight_toLeftOf="@id/messagesNumberTextView"
app:layout_constraintTop_toBottomOf="@id/firstRowBarrier"
app:layout_constrainedWidth="true"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/Text.DefaultSmall.Weak"
tools:text="@tools:sample/lorem" />
@ -198,7 +197,7 @@
android:id="@+id/messagesNumberTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/mailbox_list_item_icon_margin_horizontal"
android:layout_marginStart="@dimen/mailbox_list_item_views_margin"
android:paddingHorizontal="@dimen/message_number_view_padding_horizontal"
android:paddingVertical="@dimen/message_number_view_padding_vertical"
app:layout_constraintLeft_toRightOf="@id/subjectTextView"
@ -206,15 +205,14 @@
app:layout_constraintTop_toTopOf="@id/subjectTextView"
app:layout_constraintBottom_toBottomOf="@id/subjectTextView"
android:background="@drawable/background_messages_number"
android:textSize="11sp"
android:textColor="@color/text_weak"
android:textAppearance="@style/Text.Caption.Weak"
android:visibility="gone"
tools:text="3"
tools:visibility="visible" />
<View
android:id="@+id/emptySpaceView"
android:layout_width="@dimen/mailbox_list_item_text_margin_horizontal"
android:layout_width="@dimen/mailbox_list_item_views_margin"
android:layout_height="1dp"
app:layout_constraintLeft_toRightOf="@id/messagesNumberTextView"
app:layout_constraintRight_toLeftOf="@id/attachmentImageView"
@ -223,24 +221,23 @@
<ImageView
android:id="@+id/attachmentImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
app:layout_constraintRight_toLeftOf="@id/starImageView"
app:layout_constraintTop_toTopOf="@id/starImageView"
app:layout_constraintBottom_toBottomOf="@id/starImageView"
android:src="@drawable/ic_attachment"
android:contentDescription="@null"
app:tint="@color/icon_weak" />
<ImageView
android:id="@+id/starImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/subjectTextView"
app:layout_constraintBottom_toBottomOf="@id/subjectTextView"
android:src="@drawable/ic_star_filled"
android:contentDescription="@null"
android:contentDescription="@string/starred"
app:tint="@color/notification_warning" />
<androidx.constraintlayout.widget.Barrier
@ -254,24 +251,25 @@
<ImageView
android:id="@+id/expirationImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/mailbox_list_item_label_margin_top"
android:layout_width="@dimen/mailbox_list_item_icon_size"
android:layout_height="@dimen/mailbox_list_item_icon_size"
android:padding="@dimen/mailbox_list_item_expiration_icon_padding"
android:layout_marginTop="@dimen/mailbox_list_item_views_margin"
app:layout_constraintLeft_toRightOf="@id/senderInitialBarrier"
app:layout_constraintTop_toBottomOf="@id/secondRowBarrier"
android:src="@drawable/ic_expiration_pill"
android:contentDescription="@null" />
android:src="@drawable/ic_hourglass"
android:background="@drawable/circle_background_interaction_weak" />
<!-- TODO: Should be replaced in MAILAND-1502 -->
<LinearLayout
android:id="@+id/labelsLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/mailbox_list_item_label_margin_top"
android:layout_marginStart="@dimen/mailbox_list_item_label_margin_horizontal"
android:layout_marginTop="@dimen/mailbox_list_item_views_margin"
android:layout_marginStart="@dimen/mailbox_list_item_views_margin"
app:layout_goneMarginStart="0dp"
app:layout_constraintLeft_toRightOf="@id/expirationImageView"
app:layout_constraintTop_toBottomOf="@id/secondRowBarrier"
android:orientation="horizontal" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,375 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2020 Proton Technologies AG
This file is part of ProtonMail.
ProtonMail 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.
ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/swipe_bg_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/swipe_right_bg_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/data_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/unread_message_bg_selector"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/message_container"
android:layout_width="match_parent"
android:layout_height="65dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:paddingBottom="@dimen/fields_default_space_small"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/fields_default_space_small">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:duplicateParentState="true"
android:gravity="center_vertical">
<ImageView
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:duplicateParentState="true"
android:paddingEnd="16dp"
android:paddingLeft="0dp"
android:paddingRight="16dp"
android:paddingStart="0dp"
android:src="@drawable/inbox_check_selector"
android:tint="@color/dark_purple"/>
<RelativeLayout
android:id="@+id/message_title_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/checkbox"
android:layout_toRightOf="@id/checkbox"
android:gravity="bottom">
<LinearLayout
android:id="@+id/flow_indicators_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="@+id/message_label_trash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/trash_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/messageLabelArchiveTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/archive_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/message_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="4dp"
android:background="@color/location_gray"
android:gravity="bottom"
android:paddingBottom="0dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="0dp"
android:textAllCaps="true"
android:textColor="@color/name_gray"
android:textSize="@dimen/h7"
android:visibility="gone" />
<TextView
android:id="@+id/message_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/reply_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/message_replyall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/replyall_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/message_forward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/forward_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
</LinearLayout>
<TextView
android:id="@+id/message_date"
style="@style/MessageSecondaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginEnd="2dp"
android:layout_marginRight="2dp"
android:gravity="bottom" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/flow_indicators_container"
android:layout_toLeftOf="@id/message_date"
android:layout_toRightOf="@id/flow_indicators_container"
android:layout_toStartOf="@id/message_date"
android:gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="@+id/message_title"
style="@style/MessagePrimaryText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="bottom"
android:singleLine="true" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/message_sender_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/message_title_container"
android:layout_toEndOf="@id/checkbox"
android:layout_toRightOf="@id/checkbox"
android:gravity="top"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/attributes_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="end|top"
android:layout_marginLeft="@dimen/fields_default_space_small"
android:layout_marginStart="@dimen/fields_default_space_small"
android:gravity="end|top"
android:orientation="horizontal"
android:paddingBottom="0dp">
<TextView
android:id="@+id/message_starred"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/star2_icon"
android:textColor="@color/yellow"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/message_expiration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/expiration_icon"
android:textColor="@color/icon_purple"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/message_attachment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/attachment_icon"
android:textColor="@color/icon_purple"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/message_unencrypted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/lock_icon"
android:textColor="@color/icon_gray"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/message_encrypted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/lock_icon"
android:textColor="@color/icon_purple"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/message_pgp_mime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/fields_default_space_small"
android:paddingStart="@dimen/fields_default_space_small"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:text="@string/lock_icon"
android:textColor="@color/icon_green"
android:textSize="@dimen/abc_text_size_medium_material" />
<ProgressBar
android:id="@+id/upload_progress_circular"
android:layout_width="20dp"
android:layout_height="20dp"
android:indeterminate="true" />
</LinearLayout>
<TextView
android:id="@+id/message_sender"
style="@style/MessageSecondaryText"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:ellipsize="end"
android:gravity="top"
android:maxWidth="100dp"
android:singleLine="true" />
<LinearLayout
android:id="@+id/labels"
android:layout_width="@dimen/labels_container_size"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="right|top"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/message_sender"
android:layout_toLeftOf="@id/attributes_container"
android:layout_toRightOf="@id/message_sender"
android:layout_toStartOf="@id/attributes_container"
android:gravity="right|top"
android:orientation="horizontal"
android:padding="0dp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
<View
android:id="@+id/item_divider"
android:layout_width="match_parent"
android:layout_height="@dimen/divider_height"
android:background="@color/message_divider_gray" />
</LinearLayout>
</FrameLayout>

View File

@ -1,298 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2020 Proton Technologies AG
This file is part of ProtonMail.
ProtonMail 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.
ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dataContainerConstraintLayout"
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="@drawable/unread_message_bg_selector"
android:orientation="vertical"
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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/message_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:paddingBottom="@dimen/fields_default_space_small"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/fields_default_space_small"
android:duplicateParentState="true"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="0dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginRight="0dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/item_divider"
android:layout_marginBottom="8dp">
<ImageView
android:id="@+id/checkboxImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:duplicateParentState="true"
android:paddingEnd="16dp"
android:paddingStart="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:src="@drawable/inbox_check_selector"
app:tint="@color/dark_purple"
tools:visibility="gone"
/>
<LinearLayout
android:id="@+id/messageTitleContainerLinearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintLeft_toRightOf="@+id/checkboxImageView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:gravity="bottom">
<LinearLayout
android:id="@+id/flow_indicators_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/messageLabelTrashTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/trash_icon"
tools:text="Tr"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/messageLabelArchiveTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/archive_icon"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/messageLocationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="4dp"
android:background="@color/location_gray"
android:gravity="bottom"
android:paddingBottom="0dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="0dp"
android:textAllCaps="true"
android:textColor="@color/name_gray"
android:textSize="@dimen/h7"
android:visibility="gone" />
<TextView
android:id="@+id/messageReplyTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/reply_icon"
tools:text="&lt;-"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/messageReplyAllTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/replyall_icon"
tools:text="&lt;--"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
<TextView
android:id="@+id/messageForwardTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:gravity="bottom"
android:padding="0dp"
android:text="@string/forward_icon"
tools:text="-&gt;"
android:textColor="@color/location_gray"
android:textSize="@dimen/h4" />
</LinearLayout>
<TextView
android:id="@+id/messageTitleTextView"
style="@style/MessagePrimaryText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="bottom"
android:singleLine="true"
tools:text="@tools:sample/lorem"
/>
<TextView
android:id="@+id/messageDateTextView"
style="@style/MessageSecondaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="2dp"
android:gravity="bottom"
tools:text="@tools:sample/date/ddmmyy"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/messageSenderContainerLinearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/messageTitleContainerLinearLayout"
app:layout_constraintLeft_toRightOf="@+id/checkboxImageView"
app:layout_constraintRight_toRightOf="parent"
android:gravity="top"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/attributes_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
android:layout_marginStart="@dimen/fields_default_space_small"
android:gravity="end|top"
android:layout_alignParentEnd="true"
android:orientation="horizontal"
android:paddingBottom="0dp">
<TextView
android:id="@+id/messageStarredTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingEnd="0dp"
android:paddingStart="@dimen/fields_default_space_small"
android:text="@string/star2_icon"
tools:text="S"
android:textColor="@color/yellow"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/messageExpirationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingEnd="0dp"
android:paddingStart="@dimen/fields_default_space_small"
android:text="@string/expiration_icon"
tools:text="exp"
android:textColor="@color/icon_purple"
android:textSize="@dimen/abc_text_size_medium_material" />
<TextView
android:id="@+id/messageAttachmentTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:contentDescription="@null"
android:paddingBottom="0dp"
android:paddingEnd="0dp"
android:paddingStart="@dimen/fields_default_space_small"
android:text="@string/attachment_icon"
tools:text="A"
android:textColor="@color/icon_purple"
android:textSize="@dimen/abc_text_size_medium_material" />
<ProgressBar
android:id="@+id/uploadCircularProgressBar"
android:layout_width="20dp"
android:layout_height="20dp"
android:indeterminate="true" />
</LinearLayout>
<LinearLayout
android:id="@+id/labelsLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="end|top"
android:layout_marginStart="10dp"
android:layout_toStartOf="@id/attributes_container"
android:gravity="end|top"
android:orientation="horizontal"
android:padding="0dp" />
<TextView
android:id="@+id/messageSenderTextView"
style="@style/MessageSecondaryText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_toStartOf="@id/labelsLinearLayout"
android:ellipsize="end"
android:gravity="top"
android:singleLine="true"
tools:text="@tools:sample/full_names"
/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/item_divider"
android:layout_width="0dp"
android:layout_height="1px"
android:background="@color/message_divider_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:layout_height="1dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -66,4 +66,4 @@
</FrameLayout>
</RelativeLayout>
</ch.protonmail.android.views.ScrimInsetsFrameLayout>
</ch.protonmail.android.views.ScrimInsetsFrameLayout>

View File

@ -29,4 +29,4 @@
app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="@drawable/ic_hamburger"
app:titleTextAppearance="@style/Text.Headline.Small"
android:background="@color/background_norm" />
android:background="@color/background_norm" />

View File

@ -1,35 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2020 Proton Technologies AG
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
This file is part of ProtonMail.
ProtonMail 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.
ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_menu_search"
android:title="@string/search"
app:actionLayout="@layout/layout_search_action"
app:showAsAction="ifRoom" />
<item
android:id="@+id/compose"
android:icon="@drawable/ic_menu_compose"
android:title="@string/compose_message"
app:actionLayout="@layout/layout_compose_action"
app:showAsAction="ifRoom" />
<item
@ -37,5 +39,4 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
android:title="@string/empty_folder"
app:showAsAction="never" />
</menu>

View File

@ -19,6 +19,34 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
<resources>
<!-- V4 -->
<dimen name="toolbar_action_layout_size">48dp</dimen>
<dimen name="action_bar_padding_start">0dp</dimen>
<dimen name="action_bar_padding_end">8dp</dimen>
<dimen name="action_bar_elevation">8dp</dimen>
<dimen name="action_bar_no_elevation">0dp</dimen>
<dimen name="mailbox_status_view_height">48dp</dimen>
<dimen name="mailbox_status_view_padding_horizontal">16dp</dimen>
<dimen name="unread_messages_chip_size">20dp</dimen>
<dimen name="mailbox_list_item_padding_horizontal">16dp</dimen>
<dimen name="mailbox_list_item_padding_vertical">12dp</dimen>
<dimen name="mailbox_list_item_views_margin">8dp</dimen>
<dimen name="mailbox_list_item_icon_size">16dp</dimen>
<dimen name="mailbox_list_item_expiration_icon_padding">2dp</dimen>
<dimen name="sender_initial_view_size">28dp</dimen>
<dimen name="sender_initial_view_margin_start">2dp</dimen>
<dimen name="sender_initial_view_margin_end">16dp</dimen>
<dimen name="sender_initial_view_margin_top">2dp</dimen>
<dimen name="message_number_view_padding_horizontal">8dp</dimen>
<dimen name="message_number_view_padding_vertical">2dp</dimen>
<!-- V4 -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="activity_horizontal_margin_large">32dp</dimen>

View File

@ -65,13 +65,14 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
<string name="message_drafted">Message sending failed. Your messages are saved in drafts folder</string>
<string name="open_drawer">Open</string>
<string name="close_drawer">Close</string>
<string name="inbox_option">INBOX</string>
<string name="starred_option">STARRED</string>
<string name="drafts_option">DRAFTS</string>
<string name="sent_option">SENT</string>
<string name="archive_option">ARCHIVE</string>
<string name="trash_option">TRASH</string>
<string name="spam_option">SPAM</string>
<string name="inbox_option">Inbox</string>
<string name="starred_option">Starred</string>
<string name="drafts_option">Drafts</string>
<string name="sent_option">Sent</string>
<string name="archive_option">Archive</string>
<string name="trash_option">Trash</string>
<string name="spam_option">Spam</string>
<string name="allmail_option">All Mail</string>
<string name="inbox">Inbox</string>
<string name="starred">Starred</string>
<string name="drafts">Drafts</string>
@ -79,6 +80,7 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
<string name="archive">Archive</string>
<string name="trash">Trash</string>
<string name="spam">Spam</string>
<string name="all_mail">All Mail</string>
<string name="contacts">Contacts</string>
<string name="search_contacts">Search contacts</string>
<string name="fetching_contacts">Fetching ProtonMail contacts...</string>
@ -685,8 +687,6 @@ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
<string name="folder_deleted_error">Error while deleting folder</string>
<string name="save_new_folder">Save New Folder</string>
<string name="create_new_folder">Create Folder</string>
<string name="all_mail">All Mail</string>
<string name="allmail_option">ALL MAIL</string>
<string name="empty_emails">No emails</string>
<string name="empty_email_list">No email address</string>
<string name="no_contacts">No Contacts</string>

View File

@ -19,6 +19,101 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- V4 -->
<style name="ProtonTheme.Mail" parent="ProtonTheme">
<item name="brand_norm">@color/cornflower_blue</item>
<item name="brand_darken_20">@color/san_marino</item>
<item name="brand_darken_40">@color/chambray</item>
<item name="brand_lighten_20">@color/portage</item>
<item name="brand_lighten_40">@color/perano</item>
</style>
<style name="UnreadMessagesStatusChip" parent="Widget.MaterialComponents.Chip.Choice">
<item name="android:textAppearance">@style/Text.Caption.Strong</item>
<item name="android:textColor">@drawable/selector_unread_messages_status_text_color</item>
<item name="chipBackgroundColor">@drawable/selector_unread_messages_status_background</item>
<item name="chipCornerRadius">25dp</item>
</style>
<!-- Can be extracted to core -->
<style name="Text" parent="TextAppearance.AppCompat" />
<style name="Text.Headline">
<item name="android:textSize">20sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.01</item>
<item name="android:lineSpacingExtra">1sp</item>
</style>
<style name="Text.Headline.Hint">
<item name="android:textColor">@color/text_hint</item>
</style>
<style name="Text.Headline.Small">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">normal</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">5sp</item>
</style>
<style name="Text.Default">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">5sp</item>
</style>
<style name="Text.Default.Bold">
<item name="android:textStyle">bold</item>
</style>
<style name="Text.Default.Medium">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="Text.Default.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.Default.Hint">
<item name="android:textColor">@color/text_hint</item>
</style>
<style name="Text.Default.Inverted">
<item name="android:textColor">@color/text_inverted</item>
</style>
<style name="Text.DefaultSmall">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.02</item>
<item name="android:lineSpacingExtra">4sp</item>
</style>
<style name="Text.DefaultSmall.Medium">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="Text.DefaultSmall.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.DefaultSmall.Inverted">
<item name="android:textColor">@color/text_inverted</item>
</style>
<style name="Text.Caption">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">2sp</item>
</style>
<style name="Text.Caption.Strong">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="Text.Caption.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.Caption.Hint">
<item name="android:textColor">@color/text_hint</item>
</style>
<!-- V4 -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/dark_purple</item>
<item name="colorPrimaryDark">@color/dark_purple</item>

View File

@ -1,32 +0,0 @@
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="18dp"
android:viewportWidth="20"
android:viewportHeight="18">
<path
android:pathData="M9,0L11,0A9,9 0,0 1,20 9L20,9A9,9 0,0 1,11 18L9,18A9,9 0,0 1,0 9L0,9A9,9 0,0 1,9 0z"
android:fillColor="@color/interaction_weak"/>
<path
android:pathData="M12.0475,7.92C12.2263,7.7295 12.3846,7.5209 12.52,7.2975C12.7789,6.9083 12.9433,6.464 13,6V5.25H13.75V4.5H6.25V5.25H7V6C7.058,6.4567 7.2224,6.8934 7.48,7.275C7.6173,7.5014 7.7782,7.7125 7.96,7.905C8.1742,8.1327 8.4104,8.3387 8.665,8.52C8.9151,8.7115 9.187,8.8726 9.475,9C9.1897,9.1206 8.9181,9.2714 8.665,9.45C8.3982,9.6392 8.1474,9.8499 7.915,10.08C7.7382,10.2721 7.5799,10.4805 7.4425,10.7025C7.1938,11.0936 7.0421,11.5384 7,12V12.75H6.25V13.5H13.75V12.75H13V12C12.9399,11.5438 12.7757,11.1076 12.52,10.725C12.3806,10.5001 12.2199,10.2891 12.04,10.095C11.8238,9.8694 11.5878,9.6636 11.335,9.48C11.0849,9.2885 10.813,9.1274 10.525,9C10.8103,8.8794 11.0819,8.7286 11.335,8.55C11.5907,8.3615 11.8291,8.1507 12.0475,7.92ZM10.9,10.065C11.1133,10.2185 11.3117,10.3918 11.4925,10.5825C11.6414,10.7444 11.7745,10.9202 11.89,11.1075C12.0781,11.3867 12.2011,11.7045 12.25,12.0375V12.75H7.75V12.0525C7.7979,11.711 7.9236,11.3851 8.1175,11.1C8.2298,10.9191 8.3578,10.7484 8.5,10.59C8.6839,10.3946 8.8875,10.2186 9.1075,10.065C9.3807,9.8635 9.6812,9.7018 10,9.585C10.3205,9.7033 10.6233,9.8648 10.9,10.065ZM10,8.415C9.6795,8.2967 9.3767,8.1352 9.1,7.935C8.8838,7.7822 8.6829,7.6089 8.5,7.4175C8.3511,7.2556 8.218,7.0798 8.1025,6.8925C7.9252,6.6223 7.8052,6.3185 7.75,6V5.25H12.25V5.9475C12.2021,6.289 12.0764,6.6149 11.8825,6.9C11.7721,7.0822 11.644,7.253 11.5,7.41C11.3164,7.6057 11.1128,7.7817 10.8925,7.935C10.6193,8.1365 10.3188,8.2982 10,8.415Z"
android:fillColor="@color/icon_norm"
android:fillType="evenOdd"/>
</vector>

View File

@ -1,34 +0,0 @@
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="14dp"
android:viewportWidth="16"
android:viewportHeight="14">
<path
android:pathData="M0.5,0H15.5V1.5H0.5V0Z"
android:fillColor="@color/icon_norm"/>
<path
android:pathData="M0.5,6H15.5V7.5H0.5V6Z"
android:fillColor="@color/icon_norm"/>
<path
android:pathData="M15.5,12H0.5V13.5H15.5V12Z"
android:fillColor="@color/icon_norm"/>
</vector>

View File

@ -1,32 +0,0 @@
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
android:fillColor="@color/interaction_weak"/>
<path
android:pathData="M12.545,18.3061C12.545,15.1243 15.1243,12.545 18.3061,12.545C21.4879,12.545 24.0673,15.1243 24.0673,18.3061C24.0673,21.4879 21.4879,24.0673 18.3061,24.0673C15.1243,24.0673 12.545,21.4879 12.545,18.3061ZM18.3061,11C14.2711,11 11,14.2711 11,18.3061C11,22.3412 14.2711,25.6123 18.3061,25.6123C20.0454,25.6123 21.6427,25.0045 22.8973,23.9898L27.977,29.0696L29.0695,27.9771L23.9897,22.8974C25.0045,21.6428 25.6123,20.0454 25.6123,18.3061C25.6123,14.2711 22.3412,11 18.3061,11Z"
android:fillColor="@color/icon_norm"
android:fillType="evenOdd"/>
</vector>

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.mailbox.MailboxActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/toolbar_mailbox"
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
layout="@layout/layout_mailbox_status_view"
android:id="@+id/mailboxStatusLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<!-- TODO: Should be removed and replaced with MAILAND-1503 -->
<ch.protonmail.android.views.alerts.StorageLimitAlert
android:id="@+id/storageLimitAlert"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/mailboxStatusLayout"
android:visibility="gone" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/mailboxSwipeRefreshLayout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/storageLimitAlert">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mailboxRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/list_item_mailbox" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<!-- TODO: Should be removed and replaced with MAILAND-1497 -->
<FrameLayout
android:id="@+id/layout_no_connectivity_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<View
android:id="@+id/screenProtectorView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintRight_toRightOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintTop_toTopOf="@id/mailboxSwipeRefreshLayout"
app:layout_constraintBottom_toBottomOf="@id/mailboxSwipeRefreshLayout"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true" />
<View
android:id="@+id/screenShotPreventerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/background_norm"
android:clickable="true"
android:focusable="true"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include layout="@layout/navigation_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<resources>
<!-- TODO: Move to values/styles.xml when min sdk is changed to 23 -->
<style name="ProtonTheme.Mail" parent="ProtonTheme">
<item name="brand_norm">@color/cornflower_blue</item>
<item name="brand_darken_20">@color/san_marino</item>
<item name="brand_darken_40">@color/chambray</item>
<item name="brand_lighten_20">@color/portage</item>
<item name="brand_lighten_40">@color/perano</item>
<item name="android:statusBarColor">@color/background_norm</item>
<item name="android:windowLightStatusBar">true</item>
</style>
</resources>

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<resources>
<dimen name="toolbar_action_layout_size">48dp</dimen>
<dimen name="action_bar_padding_start">0dp</dimen>
<dimen name="action_bar_padding_end">8dp</dimen>
<dimen name="updated_status_text_view_margin">16dp</dimen>
<dimen name="unread_messages_chip_size">20dp</dimen>
<dimen name="unread_messages_chip_margin_horizontal">16dp</dimen>
<dimen name="unread_messages_chip_margin_vertical">14dp</dimen>
<dimen name="mailbox_list_item_padding_horizontal">16dp</dimen>
<dimen name="mailbox_list_item_padding_vertical">12dp</dimen>
<dimen name="mailbox_list_item_text_margin_horizontal">8dp</dimen>
<dimen name="mailbox_list_item_icon_margin_horizontal">4dp</dimen>
<dimen name="mailbox_list_item_label_margin_top">8dp</dimen>
<dimen name="mailbox_list_item_label_margin_horizontal">4dp</dimen>
<dimen name="sender_initial_view_size">28dp</dimen>
<dimen name="sender_initial_view_margin_start">2dp</dimen>
<dimen name="sender_initial_view_margin_end">16dp</dimen>
<dimen name="sender_initial_view_margin_top">2dp</dimen>
<dimen name="message_number_view_padding_horizontal">6dp</dimen>
<dimen name="message_number_view_padding_vertical">3dp</dimen>
</resources>

View File

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2020 Proton Technologies AG
~
~ This file is part of ProtonMail.
~
~ ProtonMail 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.
~
~ ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
-->
<resources>
<style name="ProtonTheme.Mail" parent="ProtonTheme">
<item name="brand_norm">@color/cornflower_blue</item>
<item name="brand_darken_20">@color/san_marino</item>
<item name="brand_darken_40">@color/chambray</item>
<item name="brand_lighten_20">@color/portage</item>
<item name="brand_lighten_40">@color/perano</item>
</style>
<style name="UnreadMessagesStatusChip" parent="Widget.MaterialComponents.Chip.Choice">
<item name="android:textAppearance">@style/Text.Caption.Strong</item>
<item name="android:textColor">@drawable/selector_unread_messages_status_text_color</item>
<item name="chipBackgroundColor">@drawable/selector_unread_messages_status_background</item>
<item name="chipCornerRadius">25dp</item>
</style>
<!-- Can be extracted to core -->
<style name="Text" parent="TextAppearance.AppCompat" />
<style name="Text.Headline">
<item name="android:textSize">20sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.01</item>
<item name="android:lineSpacingExtra">1sp</item>
</style>
<style name="Text.Headline.Hint">
<item name="android:textColor">@color/text_hint</item>
</style>
<style name="Text.Headline.Small">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">normal</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">5sp</item>
</style>
<style name="Text.Default">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">5sp</item>
</style>
<style name="Text.Default.Strong">
<item name="android:textStyle">bold</item>
</style>
<style name="Text.Default.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.DefaultSmall">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.02</item>
<item name="android:lineSpacingExtra">4sp</item>
</style>
<style name="Text.DefaultSmall.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.DefaultSmall.Strong">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="Text.DefaultSmall.Weak.Italic">
<item name="android:textStyle">italic</item>
</style>
<style name="Text.DefaultSmall.Strong.Inverted">
<item name="android:textColor">@color/text_inverted</item>
</style>
<style name="Text.Caption">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/text_norm</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:lineSpacingExtra">2sp</item>
</style>
<style name="Text.Caption.Strong">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="Text.Caption.Weak">
<item name="android:textColor">@color/text_weak</item>
</style>
<style name="Text.Caption.Hint">
<item name="android:textColor">@color/text_hint</item>
</style>
</resources>