-
Notifications
You must be signed in to change notification settings - Fork 0
/
Extensions.kt
167 lines (157 loc) · 5.66 KB
/
Extensions.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package aze.talmir.task.ratesconversions.helpers
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import aze.talmir.task.ratesconversions.R
import aze.talmir.task.ratesconversions.data.model.CurrencyData
import aze.talmir.task.ratesconversions.data.remotesource.network.RatesConversionsApiModel
import java.math.BigDecimal
import kotlin.reflect.full.memberProperties
/**
* An extension function that maps network call result type value
* to the type UI type value to show data to the user.
*/
fun RatesConversionsApiModel.asCurrencyData(coefficient: BigDecimal): Sequence<CurrencyData> {
val currencyData = mutableListOf<CurrencyData>()
// Give unique id to each list item.
// This will be used in our recycler view adapter class.
var itemId = 1
currencyData.add(
CurrencyData(
itemId,
baseCurrency,
baseCurrency.currencyName(),
coefficient,
baseCurrency.flag(),
true
)
)
// Instead of getting all property values one-by-one,
// use reflection and let it do it for us :D
for (prop in RatesConversionsApiModel.Rates::class.memberProperties) {
itemId += 1
prop.run {
currencyData.add(
CurrencyData(
itemId,
name,
name.currencyName(),
coefficient.times(prop.get(rates).toString().toBigDecimal()),
name.flag()
)
)
}
}
// Don't show base currency from previous list...
// filter ext function could also be used instead of distinctBy.
return currencyData.asSequence().distinctBy { it.code }
}
/**
* The lazy function has an argument with a default value
* that controls its synchronization behaviour. If a lazy
* property is accessed from multiple threads concurrently,
* synchronization will need to be handled by choosing an
* appropriate [LazyThreadSafetyMode].
*
* The default value [LazyThreadSafetyMode.SYNCHRONIZED]
* will ensure only a single thread can initialize the
* property using locks. If we are sure the property will
* only be accessed by a single thread we can switch to
* [LazyThreadSafetyMode.NONE] to avoid the overhead of
* performing the synchronization. There is also the option
* of using [LazyThreadSafetyMode.PUBLICATION] which allows
* multiple threads to call the initializer, but only the
* first returned value being used.
*
* Most UI code, such as in an Activity or Fragment, will
* run on the UI thread and so properties that are only used
* here can use the [LazyThreadSafetyMode.NONE]. We could
* even add an extension to avoid specifying this each time.
*/
private val mapOfCountryFlags by lazy(LazyThreadSafetyMode.NONE) {
mapOf(
"AUD" to R.drawable.aud,
"BGN" to R.drawable.bgn,
"BRL" to R.drawable.brl,
"CAD" to R.drawable.cad,
"CHF" to R.drawable.chf,
"CNY" to R.drawable.cny,
"CZK" to R.drawable.czk,
"DKK" to R.drawable.dkk,
"EUR" to R.drawable.eur,
"GBP" to R.drawable.gbp,
"HKD" to R.drawable.hkd,
"HRK" to R.drawable.hrk,
"HUF" to R.drawable.huf,
"IDR" to R.drawable.idr,
"ILS" to R.drawable.ils,
"INR" to R.drawable.inr,
"ISK" to R.drawable.isk,
"JPY" to R.drawable.jpy,
"KRW" to R.drawable.krw,
"MXN" to R.drawable.mxn,
"MYR" to R.drawable.myr,
"NOK" to R.drawable.nok,
"NZD" to R.drawable.nzd,
"PHP" to R.drawable.php,
"PLN" to R.drawable.pln,
"RON" to R.drawable.ron,
"RUB" to R.drawable.rub,
"SEK" to R.drawable.sek,
"SGD" to R.drawable.sgd,
"THB" to R.drawable.thb,
"USD" to R.drawable.usd,
"ZAR" to R.drawable.zar
)
}
@DrawableRes
private fun String.flag() = mapOfCountryFlags[this] ?: R.drawable.errno
private val mapOfCurrencyNameByCode by lazy(LazyThreadSafetyMode.NONE) {
mapOf(
"AUD" to "Australian Dollar",
"BGN" to "Bulgarian Lev",
"BRL" to "Brazilian Real",
"CAD" to "Canadian Dollar",
"CHF" to "Swiss Franc",
"CNY" to "Chinese Yuan",
"CZK" to "Czech Koruna",
"DKK" to "Danish Krone",
"EUR" to "Euro",
"GBP" to "Pound sterling",
"HKD" to "Hong Kong Dollar",
"HRK" to "Croatian Kuna",
"HUF" to "Hungarian Forint",
"IDR" to "Indonesian Rupiah",
"ILS" to "Israeli New Shekel",
"INR" to "Indian Rupee",
"ISK" to "Icelandic Króna",
"JPY" to "Japanese Yen",
"KRW" to "South Korean won",
"MXN" to "Mexican Peso",
"MYR" to "Malaysian Ringgit",
"NOK" to "Norwegian Krone",
"NZD" to "New Zealand Dollar",
"PHP" to "Philippine peso",
"PLN" to "Poland złoty",
"RON" to "Romanian Leu",
"RUB" to "Russian Ruble",
"SEK" to "Swedish Krona",
"SGD" to "Singapore Dollar",
"THB" to "Thai Baht",
"USD" to "United States Dollar",
"ZAR" to "South African Rand"
)
}
private fun String.currencyName() = mapOfCurrencyNameByCode[this] ?: "Unknown Currency"
/**
* An extension function for [RecyclerView] to set inset divider to it.
*/
fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {
val divider = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
val drawable = ContextCompat.getDrawable(context, drawableRes)
drawable?.let {
divider.setDrawable(it)
addItemDecoration(divider)
}
}