Skip to content

Commit

Permalink
feat: add pinning
Browse files Browse the repository at this point in the history
  • Loading branch information
cquintana92 committed Jun 26, 2024
1 parent f9aa49d commit 76a0205
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,7 @@ class AliasListFragment : BaseFragment(), Toolbar.OnMenuItemClickListener,

setUpRecyclerView()
setLoading(false)
// Do not fetch more aliases on configuration changed
if (viewModel.filteredAliases.isEmpty()) {
viewModel.fetchAliases()
}

activity?.intent?.let { viewModel.getMailToEmail(it) }

return binding.root
Expand Down Expand Up @@ -90,6 +87,9 @@ class AliasListFragment : BaseFragment(), Toolbar.OnMenuItemClickListener,

viewModel.onHandleShowPricingComplete()
}

// Do not fetch more aliases on configuration changed
viewModel.refreshAliases()
}

private fun setLoading(loading: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class AliasListViewModel(application: Application) : AndroidViewModel(applicatio
}

fun refreshAliases() {
if (_isFetchingAliases) return
currentPage = -1
moreAliasesToLoad = true
_aliases = mutableListOf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ package io.simplelogin.android.module.alias.activity
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.ContextMenu
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
Expand All @@ -14,6 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.simplelogin.android.R
import io.simplelogin.android.databinding.DialogViewEditTextBinding
import io.simplelogin.android.databinding.FragmentAliasActivityBinding
import io.simplelogin.android.module.alias.AliasListViewModel
Expand Down Expand Up @@ -44,8 +50,10 @@ class AliasActivityListFragment : BaseFragment(), HomeActivity.OnBackPressed {
setUpViewModel()

binding.toolbar.setNavigationOnClickListener { updateAliasListViewModelAndNavigateUp() }
binding.toolbar.setOnMenuItemClickListener { onMenuItemClicked(it) }
binding.toolbarTitleText.text = viewModel.alias.email
binding.toolbarTitleText.isSelected = true // to trigger marquee animation
setPinIconMode(viewModel.alias.pinned)

binding.scrollToTopButton.hide()
binding.scrollToTopButton.setOnClickListener {
Expand Down Expand Up @@ -239,6 +247,7 @@ class AliasActivityListFragment : BaseFragment(), HomeActivity.OnBackPressed {

result.onSuccess { alias ->
viewModel.alias = alias
setPinIconMode(alias.pinned)
headerAdapter.notifyDataSetChanged()
}

Expand All @@ -256,4 +265,39 @@ class AliasActivityListFragment : BaseFragment(), HomeActivity.OnBackPressed {
override fun onBackPressed() {
updateAliasListViewModelAndNavigateUp()
}

// Pinning
private fun setPinIconMode(pinned: Boolean) {
val icon = if (pinned) R.drawable.ic_pinned_24dp else R.drawable.ic_pin_outline_24
binding.toolbar.menu.findItem(R.id.pinAliasMenuItem)?.setIcon(icon)
}

private fun onMenuItemClicked(item: MenuItem): Boolean {
when (item.itemId) {
R.id.pinAliasMenuItem -> {
if (!binding.swipeRefreshLayout.isRefreshing) {
updatePinStatus()
}
}
}
return true
}

private fun updatePinStatus() {
binding.swipeRefreshLayout.isRefreshing = true
setLoading(true)

val newValue = !viewModel.alias.pinned
SLApiService.changeAliasPinStatus(viewModel.apiKey, viewModel.alias, newValue) { result ->
activity?.runOnUiThread {
setLoading(false)
binding.swipeRefreshLayout.isRefreshing = false
aliasListViewModel.updateAlias(viewModel.alias.copy(pinned = newValue))

result.onSuccess { refreshAlias() }

result.onFailure(requireContext()::toastThrowable)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,38 @@ object SLApiService {
}
})
}

fun changeAliasPinStatus(
apiKey: String,
alias: Alias,
pinned: Boolean,
completion: (Result<Unit>) -> Unit
) {
val requestBody = mapOf("pinned" to pinned).toRequestBody()

val request = Request.Builder()
.url("${BASE_URL}/api/aliases/${alias.id}")
.header("Authentication", apiKey)
.put(requestBody)
.build()

client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
completion(Result.failure(SLError.UnknownError(e.notNullLocalizedMessage())))
}

override fun onResponse(call: Call, response: Response) {
when (response.code) {
200 -> completion(Result.success(Unit))
400 -> completion(Result.failure(SLError.from(response.body?.string())))
401 -> completion(Result.failure(SLError.InvalidApiKey))
500 -> completion(Result.failure(SLError.InternalServerError))
502 -> completion(Result.failure(SLError.BadGateway))
else -> completion(Result.failure(SLError.ResponseError(response.code)))
}
}
})
}
//endregion

//region Contact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ data class Alias(
@SerializedName("nb_block") val blockCount: Int,
@SerializedName("nb_forward") val forwardCount: Int,
@SerializedName("nb_reply") val replyCount: Int,
@SerializedName("latest_activity") val latestActivity: LatestActivity?
@SerializedName("latest_activity") val latestActivity: LatestActivity?,
@SerializedName("pinned") val pinned: Boolean
) : Parcelable {
// Expose enabled
val enabled: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class AliasViewHolder(val binding: RecyclerItemAliasBinding) : RecyclerView.View
binding.noteTextView.text = alias.note
binding.noteTextView.visibility = if (alias.note.isNullOrEmpty()) View.GONE else View.VISIBLE

binding.aliasPinnedImageView.visibility = if (alias.pinned) View.VISIBLE else View.GONE

// Add click events
binding.rootRelativeLayout.setOnClickListener { clickListener.onClick(alias) }
binding.enabledSwitch.setOnClickListener { clickListener.onSwitch(alias, bindingAdapterPosition) }
Expand Down
5 changes: 5 additions & 0 deletions SimpleLogin/app/src/main/res/drawable/ic_pin_outline_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M14,4v5c0,1.12 0.37,2.16 1,3H9c0.65,-0.86 1,-1.9 1,-3V4H14M17,2H7C6.45,2 6,2.45 6,3c0,0.55 0.45,1 1,1c0,0 0,0 0,0l1,0v5c0,1.66 -1.34,3 -3,3v2h5.97v7l1,1l1,-1v-7H19v-2c0,0 0,0 0,0c-1.66,0 -3,-1.34 -3,-3V4l1,0c0,0 0,0 0,0c0.55,0 1,-0.45 1,-1C18,2.45 17.55,2 17,2L17,2z"/>

</vector>
5 changes: 5 additions & 0 deletions SimpleLogin/app/src/main/res/drawable/ic_pinned_24dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:fillType="evenOdd" android:pathData="M16,9V4l1,0c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1H7C6.45,2 6,2.45 6,3v0c0,0.55 0.45,1 1,1l1,0v5c0,1.66 -1.34,3 -3,3h0v2h5.97v7l1,1l1,-1v-7H19v-2h0C17.34,12 16,10.66 16,9z"/>

</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_chevron_left_24dp"
android:background="@color/colorItemBackground"
app:menu="@menu/menu_alias_activity"
app:contentInsetStartWithNavigation="0dp">

<TextView
Expand Down
35 changes: 27 additions & 8 deletions SimpleLogin/app/src/main/res/layout/recycler_item_alias.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,34 @@
android:layout_toStartOf="@+id/arrowImageView"
android:orientation="vertical">

<TextView
android:id="@+id/emailTextView"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_4"
android:textAppearance="?attr/textAppearanceSubtitle2"
android:textColor="@color/colorText"
tools:text="[email protected]"
android:textSize="16sp"/>
android:layout_height="wrap_content">

<ImageView
android:id="@+id/aliasPinnedImageView"
android:layout_width="24dp"
android:layout_height="24dp"
android:visibility="gone"
android:paddingEnd="8dp"
android:src="@drawable/ic_pinned_24dp"
android:layout_centerVertical="true"
android:contentDescription="Pinned alias" />


<TextView
android:id="@+id/emailTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_4"
android:layout_toEndOf="@id/aliasPinnedImageView"
android:layout_centerVertical="true"
android:textAppearance="?attr/textAppearanceSubtitle2"
android:textColor="@color/colorText"
tools:text="[email protected]"
android:textSize="16sp"/>

</RelativeLayout>

<TextView
android:id="@+id/creationDateTextView"
Expand Down
11 changes: 11 additions & 0 deletions SimpleLogin/app/src/main/res/menu/menu_alias_activity.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/pinAliasMenuItem"
android:icon="@drawable/ic_pinned_24dp"
android:title="Pin alias"
app:showAsAction="always"
tools:ignore="HardcodedText" />
</menu>

0 comments on commit 76a0205

Please sign in to comment.