Skip to content

Commit cb2aefd

Browse files
lukstbitaniri
andauthored
Enable screen for visited polling stations (#241)
* Enable screen for visited polling stations * Enable selecting from previously visited stations * added visited stations icon from figma * Implement requested changes * Hide station selection on first run Co-authored-by: Irina Borozan <anirib@gmail.com>
1 parent 499cbf6 commit cb2aefd

26 files changed

+683
-25
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@
5858
android:launchMode="singleTop"
5959
android:theme="@style/AppTheme.NoActionBar"
6060
tools:ignore="LockedOrientationActivity" />
61+
<activity
62+
android:name=".ui.section.VisitedPollingStationsActivity"
63+
android:parentActivityName=".ui.main.MainActivity"
64+
android:label="@string/title_visited_stations"
65+
android:screenOrientation="portrait"
66+
android:launchMode="singleTop"
67+
android:theme="@style/AppTheme.NoActionBar"
68+
tools:ignore="LockedOrientationActivity" />
6169
<activity
6270
android:name=".ui.onboarding.OnboardingActivity"
6371
android:screenOrientation="portrait"
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package ro.code4.monitorizarevot.adapters
2+
3+
import android.content.Context
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import android.widget.TextView
8+
import androidx.recyclerview.widget.DiffUtil
9+
import androidx.recyclerview.widget.ListAdapter
10+
import androidx.recyclerview.widget.RecyclerView
11+
import ro.code4.monitorizarevot.R
12+
import ro.code4.monitorizarevot.data.pojo.CountyAndPollingStation
13+
14+
class VisitedStationsAdapter(
15+
private val context: Context,
16+
private val itemSelected: (CountyAndPollingStation) -> Unit
17+
) : ListAdapter<CountyAndPollingStation, VisitedStationsAdapter.VisitedStationViewHolder>(
18+
DIFF_CALLBACK
19+
) {
20+
21+
private val layoutInflater = LayoutInflater.from(context)
22+
23+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VisitedStationViewHolder {
24+
return VisitedStationViewHolder(
25+
layoutInflater.inflate(
26+
R.layout.item_visited_section,
27+
parent,
28+
false
29+
)
30+
)
31+
}
32+
33+
override fun onBindViewHolder(holder: VisitedStationViewHolder, position: Int) {
34+
val currentStation = getItem(position)
35+
holder.textView.text = currentStation.displayName
36+
holder.rowView.setOnClickListener {
37+
itemSelected(currentStation)
38+
}
39+
}
40+
41+
class VisitedStationViewHolder(
42+
val rowView: View
43+
) : RecyclerView.ViewHolder(rowView) {
44+
val textView: TextView = rowView.findViewById(R.id.visitedStation)
45+
}
46+
47+
private val CountyAndPollingStation.displayName: String
48+
get() = countyOrNull()?.let {
49+
context.getString(R.string.polling_station_visited, idPollingStation, it.name)
50+
} ?: "Not Available" // TODO extract string?
51+
52+
companion object {
53+
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<CountyAndPollingStation>() {
54+
override fun areItemsTheSame(
55+
oldItem: CountyAndPollingStation,
56+
newItem: CountyAndPollingStation
57+
): Boolean =
58+
oldItem == newItem
59+
60+
override fun areContentsTheSame(
61+
oldItem: CountyAndPollingStation,
62+
newItem: CountyAndPollingStation
63+
): Boolean =
64+
oldItem.idPollingStation == newItem.idPollingStation &&
65+
oldItem.observerArrivalTime == newItem.observerArrivalTime &&
66+
oldItem.countyCode == newItem.countyCode &&
67+
oldItem.county == newItem.county
68+
69+
}
70+
}
71+
}

app/src/main/java/ro/code4/monitorizarevot/data/dao/PollingStationDao.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package ro.code4.monitorizarevot.data.dao
33
import androidx.lifecycle.LiveData
44
import androidx.room.*
55
import io.reactivex.Maybe
6+
import io.reactivex.Observable
67
import ro.code4.monitorizarevot.data.model.PollingStation
8+
import ro.code4.monitorizarevot.data.pojo.CountyAndPollingStation
79
import ro.code4.monitorizarevot.data.pojo.PollingStationInfo
810

911
@Dao
@@ -31,4 +33,7 @@ interface PollingStationDao {
3133

3234
@Query("DELETE FROM polling_station")
3335
fun deleteAll()
36+
37+
@Query("SELECT * FROM polling_station WHERE observerArrivalTime NOT NULL")
38+
fun getVisitedPollingStations(): Observable<List<CountyAndPollingStation>>
3439
}

app/src/main/java/ro/code4/monitorizarevot/data/model/PollingStation.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,35 @@ class PollingStation() {
6565
this.observerLeaveTime = departureTime
6666
}
6767

68+
override fun equals(other: Any?): Boolean {
69+
if (this === other) return true
70+
if (javaClass != other?.javaClass) return false
71+
72+
other as PollingStation
73+
74+
if (id != other.id) return false
75+
if (countyCode != other.countyCode) return false
76+
if (idPollingStation != other.idPollingStation) return false
77+
if (urbanArea != other.urbanArea) return false
78+
if (isPollingStationPresidentFemale != other.isPollingStationPresidentFemale) return false
79+
if (observerArrivalTime != other.observerArrivalTime) return false
80+
if (observerLeaveTime != other.observerLeaveTime) return false
81+
if (synced != other.synced) return false
82+
83+
return true
84+
}
85+
86+
override fun hashCode(): Int {
87+
var result = id.hashCode()
88+
result = 31 * result + countyCode.hashCode()
89+
result = 31 * result + idPollingStation
90+
result = 31 * result + urbanArea.hashCode()
91+
result = 31 * result + isPollingStationPresidentFemale.hashCode()
92+
result = 31 * result + (observerArrivalTime?.hashCode() ?: 0)
93+
result = 31 * result + (observerLeaveTime?.hashCode() ?: 0)
94+
result = 31 * result + synced.hashCode()
95+
return result
96+
}
97+
98+
6899
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package ro.code4.monitorizarevot.data.pojo
2+
3+
import androidx.room.Relation
4+
import ro.code4.monitorizarevot.data.model.County
5+
6+
class CountyAndPollingStation {
7+
var idPollingStation: Int = 0
8+
lateinit var countyCode: String
9+
lateinit var observerArrivalTime: String
10+
11+
@Relation(parentColumn = "countyCode", entityColumn = "code", entity = County::class)
12+
lateinit var county: List<County>
13+
14+
fun countyOrNull(): County? =
15+
if (::county.isInitialized && county.isNotEmpty()) county[0] else null
16+
17+
override fun equals(other: Any?): Boolean {
18+
if (this === other) return true
19+
if (javaClass != other?.javaClass) return false
20+
other as CountyAndPollingStation
21+
if (idPollingStation != other.idPollingStation) return false
22+
if (countyCode != other.countyCode) return false
23+
if (observerArrivalTime != other.observerArrivalTime) return false
24+
if (county != other.county) return false
25+
return true
26+
}
27+
28+
override fun hashCode(): Int {
29+
var result = idPollingStation
30+
result = 31 * result + countyCode.hashCode()
31+
result = 31 * result + observerArrivalTime.hashCode()
32+
result = 31 * result + county.hashCode()
33+
return result
34+
}
35+
}

app/src/main/java/ro/code4/monitorizarevot/helper/Constants.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ object Constants {
2727

2828
const val PUSH_NOTIFICATION_TITLE = "title"
2929
const val PUSH_NOTIFICATION_BODY = "body"
30+
31+
const val HAS_SELECTED_STATIONS = "has_selected_station"
3032
}

app/src/main/java/ro/code4/monitorizarevot/helper/Utils.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ import okhttp3.MultipartBody
3838
import okhttp3.RequestBody.Companion.toRequestBody
3939
import ro.code4.monitorizarevot.BuildConfig
4040
import ro.code4.monitorizarevot.R
41+
import ro.code4.monitorizarevot.data.model.County
4142
import ro.code4.monitorizarevot.helper.Constants.REQUEST_CODE_RECORD_VIDEO
4243
import ro.code4.monitorizarevot.helper.Constants.REQUEST_CODE_TAKE_PHOTO
4344
import ro.code4.monitorizarevot.interfaces.ExcludeFromCodeCoverage
4445
import ro.code4.monitorizarevot.ui.section.PollingStationActivity
46+
import ro.code4.monitorizarevot.ui.section.VisitedPollingStationsActivity
4547
import java.io.File
4648
import java.text.SimpleDateFormat
4749
import java.util.*
@@ -82,8 +84,17 @@ fun FragmentManager.replaceFragment(
8284
ft.commit()
8385
}
8486

85-
fun AppCompatActivity.changePollingStation() {
86-
startActivity(Intent(this, PollingStationActivity::class.java))
87+
fun AppCompatActivity.changePollingStation(county: County? = null, pollingStationId: Int = -1) {
88+
val intent = Intent(this, PollingStationActivity::class.java)
89+
if (county != null && pollingStationId > 0) {
90+
intent.putExtra(PollingStationActivity.EXTRA_POLLING_STATION_ID, pollingStationId)
91+
intent.putExtra(PollingStationActivity.EXTRA_COUNTY_NAME, county.name)
92+
}
93+
startActivity(intent)
94+
}
95+
96+
fun AppCompatActivity.showVisitedPollingStations() {
97+
startActivity(Intent(this, VisitedPollingStationsActivity::class.java))
8798
}
8899

89100
fun Calendar.updateTime(year: Int, month: Int, dayOfMonth: Int, hourOfDay: Int, minute: Int) {

app/src/main/java/ro/code4/monitorizarevot/modules/Modules.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import ro.code4.monitorizarevot.BuildConfig.DEBUG
2121
import ro.code4.monitorizarevot.data.AppDatabase
2222
import ro.code4.monitorizarevot.helper.getToken
2323
import ro.code4.monitorizarevot.repositories.Repository
24+
import ro.code4.monitorizarevot.ui.section.VisitedPollingStationsViewModel
2425
import ro.code4.monitorizarevot.ui.forms.FormsViewModel
2526
import ro.code4.monitorizarevot.ui.forms.questions.QuestionsDetailsViewModel
2627
import ro.code4.monitorizarevot.ui.forms.questions.QuestionsViewModel
@@ -106,6 +107,7 @@ val viewModelsModule = module {
106107
viewModel { MainViewModel() }
107108
viewModel { PollingStationViewModel() }
108109
viewModel { PollingStationSelectionViewModel() }
110+
viewModel { VisitedPollingStationsViewModel(get()) }
109111
viewModel { FormsViewModel() }
110112
viewModel { QuestionsViewModel() }
111113
viewModel { QuestionsDetailsViewModel() }

app/src/main/java/ro/code4/monitorizarevot/repositories/Repository.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,5 +408,7 @@ class Repository : KoinComponent {
408408
db.pollingStationDao().deleteAll()
409409
}
410410
}
411+
412+
fun getVisitedStations() = db.pollingStationDao().getVisitedPollingStations()
411413
}
412414

app/src/main/java/ro/code4/monitorizarevot/ui/main/MainActivity.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ class MainActivity : BaseActivity<MainViewModel>() {
9595
}
9696
true
9797
}
98+
R.id.nav_visited_stations -> {
99+
showVisitedPollingStations()
100+
true
101+
}
98102
else -> false
99103
}
100104
}

0 commit comments

Comments
 (0)