Skip to content

Commit

Permalink
new navigation tabs final work + bugfix on fragment navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmarinangeli committed Mar 19, 2020
1 parent c1ea6de commit 004bce5
Show file tree
Hide file tree
Showing 24 changed files with 475 additions and 183 deletions.
1 change: 1 addition & 0 deletions dashboard/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ dependencies {
implementation 'androidx.navigation:navigation-ui:2.2.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.1'
implementation 'com.facebook.shimmer:shimmer:0.5.0'

implementation 'androidx.legacy:legacy-support-v4:1.0.0'
kapt "com.google.dagger:dagger-compiler:$dagger_version"
Expand Down
4 changes: 0 additions & 4 deletions dashboard/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
package="com.davidm.ui">

<application>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme"></activity>
<activity android:name=".HomepageActivity" />
</application>

Expand Down
4 changes: 4 additions & 0 deletions dashboard/src/main/java/com/davidm/entities/DateInterval.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.davidm.entities


data class DateInterval(val startDate: String, val endDate: String, val month: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package com.davidm.entities

import com.davidm.account.entities.Amount
import com.squareup.moshi.Json
import java.util.*

data class Purchases(
val feedItems: List<Purchase>
val feedItems: List<StarlingTransaction>
)

data class Purchase(
data class StarlingTransaction(

val feedItemUid: String,
val categoryUid: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.davidm.repository

import com.davidm.account.entities.Account
import com.davidm.entities.Purchase
import com.davidm.entities.StarlingTransaction
import com.davidm.network.DashboardApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.Instant
import java.util.*
import javax.inject.Inject

class DashboardRepository @Inject constructor(
Expand All @@ -20,7 +18,7 @@ class DashboardRepository @Inject constructor(
account: Account,
startDate: String,
endDate: String
): List<Purchase> {
): List<StarlingTransaction> {

return withContext(Dispatchers.IO) {
return@withContext dashboardApi.getPurchasesInAWeek(
Expand Down
69 changes: 45 additions & 24 deletions dashboard/src/main/java/com/davidm/ui/DashboardFragment.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package com.davidm.ui

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import com.davidm.utils.DashboardLocalMapper
import androidx.viewpager2.widget.ViewPager2
import com.davidm.utils.DateIntervalHelper
import com.facebook.shimmer.Shimmer
import com.facebook.shimmer.ShimmerFrameLayout
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_dashboard.*
import java.text.DateFormatSymbols
import java.util.*
import javax.inject.Inject

class DashboardFragment : Fragment() {
Expand All @@ -21,7 +24,9 @@ class DashboardFragment : Fragment() {
lateinit var viewModelFactory: ViewModelProvider.Factory

private lateinit var viewModel: DashboardViewModel
lateinit var adapter: DashboardListAdapter
lateinit var parentListAdapter: DashboardParentListAdapter
lateinit var nestedListAdapter: DashboardNestedListAdapter
lateinit var calendar: Calendar

override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
Expand All @@ -40,36 +45,52 @@ class DashboardFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val recyclerView = view.findViewById<RecyclerView>(R.id.purchase_list)
val viewPager = view.findViewById<ViewPager2>(R.id.parent_list)
val balanceCardTextView = view.findViewById<TextView>(R.id.balance_amount)
val balanceCentsTextView = view.findViewById<TextView>(R.id.cents)
val emptyListImageView = view.findViewById<ImageView>(R.id.empty_list_illustration)

calendar = Calendar.getInstance()
viewModel =
ViewModelProvider(this, viewModelFactory).get(DashboardViewModel::class.java)

adapter = DashboardListAdapter()

recyclerView.adapter = adapter
recyclerView.addItemDecoration(
DividerItemDecoration(
recyclerView.context,
DividerItemDecoration.VERTICAL
)
)
ViewModelProvider(
activity!!.viewModelStore,
viewModelFactory
).get(DashboardViewModel::class.java)

viewModel.accountBalanceLiveData.observe(viewLifecycleOwner, Observer {
balanceCardTextView.text = it.amount
balanceCentsTextView.text = it.amountCents
})

viewModel.purchasesLiveData.observe(viewLifecycleOwner, Observer {
if(it.isEmpty()){
emptyListImageView.visibility = View.VISIBLE
} else {
adapter.data = it
nestedListAdapter = DashboardNestedListAdapter()

val data: List<DashboardParentListAdapter.ParentListItem> =
DateIntervalHelper().generateDateIntervalList().map {
DashboardParentListAdapter.ParentListItem(it.month, nestedListAdapter)
}

parentListAdapter = DashboardParentListAdapter(data, context!!, true)
viewPager.adapter = parentListAdapter

viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {

date_interval_text.text = DateFormatSymbols().months[position]

viewModel.getPurchases(DateIntervalHelper().generateDateIntervalList()[position])
parentListAdapter.loading = true
parentListAdapter.notifyDataSetChanged()
}
})

viewModel.purchasesLiveData.observe(viewLifecycleOwner, Observer {
nestedListAdapter.data = it
parentListAdapter.data[viewPager.currentItem].listAdapter = nestedListAdapter
parentListAdapter.loading = false
parentListAdapter.notifyDataSetChanged()

})

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,37 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import com.davidm.utils.DashboardLocalMapper
import kotlinx.android.synthetic.main.balance_card_item.view.*
import kotlinx.android.synthetic.main.purchase_list_item.view.*

class DashboardListAdapter : RecyclerView.Adapter<DashboardListAdapter.DashboardViewHolder>() {
class DashboardNestedListAdapter : RecyclerView.Adapter<DashboardNestedListAdapter.DashboardNestedListViewHolder>() {

var data = listOf<DashboardLocalMapper.LocalPurchase>()
set(value) {
field = value
notifyDataSetChanged()
}

inner class DashboardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
inner class DashboardNestedListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val mCounterParty: TextView = itemView.title
val mDate: TextView = itemView.date
val mAmount: TextView = itemView.amount
val mSpendingCategory: ImageView = itemView.spendingCategoryBox
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashboardViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashboardNestedListViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.purchase_list_item, parent, false)
return DashboardViewHolder(view)
return DashboardNestedListViewHolder(view)
}

override fun getItemCount(): Int {
return data.size
}

override fun onBindViewHolder(holder: DashboardViewHolder, position: Int) {
override fun onBindViewHolder(holder: DashboardNestedListViewHolder, position: Int) {
val item = data[position]
holder.mCounterParty.text = item.counterPartyName
holder.mSpendingCategory.setImageResource(item.spendingCategoryIcon)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.davidm.ui

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.facebook.shimmer.ShimmerFrameLayout
import kotlinx.android.synthetic.main.empty_list_item.view.*
import kotlinx.android.synthetic.main.parent_list_item.view.*
import kotlinx.android.synthetic.main.shimmer_layout.view.*
import java.text.DateFormatSymbols


class DashboardParentListAdapter(
val data: List<ParentListItem>,
val context: Context,
var loading: Boolean
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(
) {


inner class DashboardLoadingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val shimmer: ShimmerFrameLayout = itemView.shimmer_view_container
}

inner class DashboardParentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val list: RecyclerView = itemView.purchase_list
}

inner class DashboardEmptyListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val emptyListTextView: TextView = itemView.no_results
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
0 ->
DashboardLoadingViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.shimmer_layout, parent, false)
)
1 -> DashboardEmptyListViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.empty_list_item, parent, false)
)
else -> DashboardParentViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.parent_list_item, parent, false)
)
}

}

override fun getItemCount(): Int {
return data.size
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = data[position]

when (holder) {
is DashboardParentViewHolder -> holder.list.adapter = item.listAdapter
is DashboardEmptyListViewHolder -> holder.emptyListTextView.text =
context.resources.getString(
R.string.no_result_string,
DateFormatSymbols().months[item.month]
)
is DashboardLoadingViewHolder -> holder.shimmer.run { stopShimmer() }

}

}

override fun getItemViewType(position: Int): Int {
return when {
loading -> 0
data[position].listAdapter.data.isEmpty() -> 1
else -> 2
}
}

data class ParentListItem(
val month: Int,
var listAdapter: DashboardNestedListAdapter
)
}
32 changes: 9 additions & 23 deletions dashboard/src/main/java/com/davidm/ui/DashboardViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@ package com.davidm.ui
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.davidm.account.entities.Account
import com.davidm.account.entities.AccountBalance
import com.davidm.account.repository.AccountRepository
import com.davidm.entities.Purchase
import com.davidm.entities.DateInterval
import com.davidm.entities.StarlingTransaction
import com.davidm.repository.DashboardRepository
import com.davidm.utils.AmountConverter
import com.davidm.utils.DashboardLocalMapper
import kotlinx.coroutines.*
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject

class DashboardViewModel @Inject constructor(
Expand All @@ -31,39 +28,28 @@ class DashboardViewModel @Inject constructor(

init {
getAccountBalance()
getPurchases()
}

private fun getPurchases() {

val calendar = Calendar.getInstance()
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
val endDate = calendar.time

val startDate = run {
calendar.add(Calendar.DATE, -5)
calendar.time
}
fun getPurchases(dateInterval: DateInterval) {

coroutineScope.launch {
val result = withContext(Dispatchers.IO) {

try {

val accounts = accountRepository.retrieveAccounts()

dashboardRepository.retrievePurchases(
accounts.firstOrNull()!!,
dateFormat.format(startDate),
dateFormat.format(endDate)
dateInterval.startDate,
dateInterval.endDate
)

} catch (e: Exception) {
Log.e("network_error", e.message!!)
emptyList<Purchase>()
emptyList<StarlingTransaction>()
}
}
updateView(purchaseList = result)
updateView(starlingTransactionList = result)
}
}

Expand Down Expand Up @@ -102,8 +88,8 @@ class DashboardViewModel @Inject constructor(
}


private fun updateView(purchaseList: List<Purchase>) {
purchasesLiveData.postValue(purchaseList.map {
private fun updateView(starlingTransactionList: List<StarlingTransaction>) {
purchasesLiveData.postValue(starlingTransactionList.map {
dashboardLocalMapper.convertPurchases(converter, it)
})
}
Expand Down
Loading

0 comments on commit 004bce5

Please sign in to comment.