Skip to content

Commit

Permalink
Merge pull request #245 from rfcx/feature/add-icon-to-show-that-this-…
Browse files Browse the repository at this point in the history
…incident-has-a-report-already

Add icon to show that this incident has a report already
  • Loading branch information
RatreeOchn authored Apr 4, 2022
2 parents 9e9617f + 2327382 commit 4598deb
Show file tree
Hide file tree
Showing 17 changed files with 371 additions and 236 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ android {
defaultConfig {
applicationId 'org.rfcx.incidents'
manifestPlaceholders = [auth0Domain: "@string/auth0_domain", auth0Scheme: "@string/auth0_scheme"]
versionCode 23
versionName '1.0.3'
versionCode 27
versionName '1.0.4'
minSdkVersion 19
targetSdkVersion 30
multiDexEnabled true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class StreamsRepositoryImp(

private fun refreshFromAPI(projectId: String, offset: Int): Single<List<Stream>> {
return endpoint.getStreams(projects = listOf(projectId), offset = offset).observeOn(postExecutionThread.scheduler).flatMap { rawStreams ->
if (offset == 0) streamDb.deleteByProject(projectId)
rawStreams.forEachIndexed { index, streamRes ->
val stream = streamRes.toStream()
stream.order = offset + index
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/java/org/rfcx/incidents/data/local/StreamDb.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ class StreamDb(private val realm: Realm) {

fun insertOrUpdate(stream: Stream) {
stream.lastIncident?.let {
val existingIncident = realm.where(Incident::class.java).equalTo(Incident.FIELD_ID, it.id).findFirst() ?: return@let
stream.lastIncident = existingIncident
realm.executeTransaction { r ->
val existingIncident = realm.where(Incident::class.java).equalTo(Incident.FIELD_ID, it.id).findFirst()
existingIncident?.deleteFromRealm()
r.insertOrUpdate(it)
}
val existing = realm.where(Incident::class.java).equalTo(Incident.FIELD_ID, it.id).findFirst()
stream.lastIncident = existing
}
realm.executeTransaction {
it.insertOrUpdate(stream)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import io.realm.exceptions.RealmMigrationNeededException
import org.rfcx.incidents.BuildConfig
import org.rfcx.incidents.entity.response.Asset
import org.rfcx.incidents.entity.response.Response
import org.rfcx.incidents.entity.stream.Incident
import org.rfcx.incidents.entity.stream.Stream
import org.rfcx.incidents.entity.stream.User
import java.util.Date

class AppRealm {

companion object {
private const val schemaVersion = 20L
private const val schemaVersion = 21L

fun init(context: Context) {
Realm.init(context)
Expand Down Expand Up @@ -67,6 +69,10 @@ private class Migrations : RealmMigration {
if (oldVersion < 20L && newVersion >= 20) {
migrateToV20(c)
}

if (oldVersion < 21L && newVersion >= 21) {
migrateToV21(c)
}
}

private fun migrateToV20(realm: DynamicRealm) {
Expand All @@ -91,6 +97,18 @@ private class Migrations : RealmMigration {
}
}

private fun migrateToV21(realm: DynamicRealm) {
val user = realm.schema.create(User.TABLE_NAME)
user?.apply {
addField(User.FIRSTNAME, String::class.java)
}

val incident = realm.schema.get(Incident.TABLE_NAME)
incident?.apply {
addRealmListField(Incident.FIELD_RESPONSES, user)
}
}

override fun hashCode(): Int {
return 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.rfcx.incidents.entity.event.Classification
import org.rfcx.incidents.entity.event.Event
import org.rfcx.incidents.entity.stream.Incident
import org.rfcx.incidents.entity.stream.Stream
import org.rfcx.incidents.entity.stream.User
import java.util.Date

data class StreamResponse(
Expand Down Expand Up @@ -33,7 +34,8 @@ data class IncidentResponse(
var createdAt: Date,
var updatedAt: Date,
var firstEventId: String,
var events: List<EventResponse> = listOf()
var events: List<EventResponse> = listOf(),
var responses: List<ResponseItemResponse> = listOf()
)

data class EventResponse(
Expand All @@ -44,6 +46,15 @@ data class EventResponse(
var classification: ClassificationResponse
)

data class ResponseItemResponse(
var id: String = "",
var createdBy: UserResponse? = null
)

data class UserResponse(
var firstname: String = ""
)

data class ClassificationResponse(
var value: String = "",
var title: String = ""
Expand All @@ -70,7 +81,8 @@ private fun IncidentResponse.toIncident(): Incident = Incident(
id = this.id,
ref = this.ref.toString(),
closedAt = this.closedAt,
createdAt = this.createdAt
createdAt = this.createdAt,
responses = realmList(this.responses.map { User(it.createdBy?.firstname ?: "") })
)

fun EventResponse.toEvent(streamId: String): Event = Event(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.rfcx.incidents.entity.stream

import io.realm.RealmList
import io.realm.RealmModel
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
Expand All @@ -13,10 +14,12 @@ open class Incident(
var ref: String = "",
var closedAt: Date? = null,
var createdAt: Date = Date(),
var responses: RealmList<User>? = null,
@LinkingObjects("incident") val events: RealmResults<Event>? = null
) : RealmModel {
companion object {
const val TABLE_NAME = "Incident"
const val FIELD_ID = "id"
const val FIELD_RESPONSES = "responses"
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/org/rfcx/incidents/entity/stream/Stream.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.rfcx.incidents.entity.stream

import com.google.gson.annotations.SerializedName
import io.realm.RealmList
import io.realm.RealmModel
import io.realm.annotations.PrimaryKey
Expand All @@ -13,6 +14,7 @@ open class Stream(
var name: String = "",
var latitude: Double = 0.0,
var longitude: Double = 0.0,
@SerializedName("timezone")
var timezoneRaw: String = "",
var projectId: String = "",
var tags: RealmList<String>? = null,
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/org/rfcx/incidents/entity/stream/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.rfcx.incidents.entity.stream

import io.realm.RealmObject
import io.realm.annotations.RealmClass

@RealmClass(embedded = true)
open class User(
var firstname: String = ""
) : RealmObject() {
companion object {
const val TABLE_NAME = "User"
const val FIRSTNAME = "firstname"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,8 @@ class StreamsFragment :

layers.forEachIndexed { i, ly ->
val unClustered = CircleLayer("UN_CLUSTERED_POINTS-$i", SOURCE_EVENT)
val color = if (Expression.toString(Expression.get(PROPERTY_MARKER_EVENT_COUNT))
.toString() != "0"
) Color.parseColor("#e41a1a") else Color.parseColor("#2FB04A")
val color = if (Expression.toString(Expression.get(PROPERTY_MARKER_EVENT_COUNT)).toString() != "0")
resources.getColor(R.color.text_error) else resources.getColor(R.color.text_green)
unClustered.setProperties(PropertyFactory.circleColor(color), PropertyFactory.circleRadius(14f))
val eventsSize = Expression.toNumber(Expression.get(PROPERTY_MARKER_EVENT_COUNT))
unClustered.setFilter(
Expand Down Expand Up @@ -659,14 +658,8 @@ class StreamsFragment :
// Activate the LocationComponent with options
activateLocationComponent(locationComponentActivationOptions)
// Enable to make the LocationComponent visible
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.rfcx.incidents.view.events.adapter

import android.content.Context
import android.content.res.Resources
import android.util.TypedValue
import android.view.LayoutInflater
Expand Down Expand Up @@ -62,6 +63,8 @@ class StreamAdapter(private val onClickListener: (Stream) -> Unit) :
private val numOfDogBarkTextView = binding.numOfDogBarkTextView
private val elephantLayout = binding.elephantLayout
private val numOfElephantTextView = binding.numOfElephantTextView
private val reportImageView = binding.reportImageView
private val createByTextView = binding.createByTextView

fun bind(stream: Stream) {
// Reset
Expand All @@ -70,6 +73,8 @@ class StreamAdapter(private val onClickListener: (Stream) -> Unit) :
hotTextView,
timeTextView,
bellImageView,
createByTextView,
reportImageView,
chainsawLayout,
gunLayout,
otherLayout,
Expand Down Expand Up @@ -129,6 +134,19 @@ class StreamAdapter(private val onClickListener: (Stream) -> Unit) :
}
}

reportImageView.visibility = if (incident.responses?.isNotEmpty() == true) View.VISIBLE else View.GONE
createByTextView.visibility = if (incident.responses?.isNotEmpty() == true) View.VISIBLE else View.GONE

incident.responses?.let { res ->
val userText = if (res.size == 1) {
itemView.context.getString(R.string.response_by) + " " + res[0]?.firstname.toString().firstCharUppercase
} else {
setCreatedByText(itemView.context, res.map { u -> u?.firstname ?: "" })
}

createByTextView.text = userText
}

stream.tags?.let { tags ->
if (tags.contains(Stream.TAG_RECENT) && events.isNotEmpty()) recentTextView.visibility = View.VISIBLE
if (tags.contains(Stream.TAG_HOT) && events.isNotEmpty()) hotTextView.visibility = View.VISIBLE
Expand Down Expand Up @@ -173,6 +191,32 @@ class StreamAdapter(private val onClickListener: (Stream) -> Unit) :
}
}

fun setCreatedByText(context: Context, users: List<String>): String {
val userFilter = users.toCheckDuplicate()
var createByText = ""
userFilter.forEach { firstname ->
createByText += when (firstname) {
userFilter.first() -> firstname
userFilter.last() -> " " + context.getString(R.string.and) + " " + firstname
else -> ", $firstname"
}
}
return users.size.toString() + " " + context.getString(R.string.responses_by) + " " + createByText
}

private fun List<String>.toCheckDuplicate(): ArrayList<String> {
val values = arrayListOf<String>()
this.forEach { s ->
if (!values.contains(s)) {
values.add(s.firstCharUppercase)
}
}
return values
}

val String.firstCharUppercase
get() = this.replaceFirstChar { it.uppercase() }

val Number.toPx
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.rfcx.incidents.entity.stream.GuardianType
import org.rfcx.incidents.util.getTokenID
import org.rfcx.incidents.util.setReportImage
import org.rfcx.incidents.util.toTimeSinceStringAlternativeTimeAgo
import org.rfcx.incidents.view.events.adapter.StreamAdapter
import org.rfcx.incidents.view.events.detail.EventViewModel.Companion.maxProgress
import java.util.Date
import java.util.TimeZone
Expand Down Expand Up @@ -50,7 +51,16 @@ class EventActivity : AppCompatActivity() {
setupToolbar()

val event = eventId?.let { viewModel.getEvent(it) }
binding.guardianNameTextView.text = event?.classification?.title
val valueTitle: Int? = when (event?.classification?.value) {
StreamAdapter.GUNSHOT -> R.string.gunshot
StreamAdapter.CHAINSAW -> R.string.chainsaw
StreamAdapter.VEHICLE -> R.string.vehicle
StreamAdapter.VOICE -> R.string.human_voice
StreamAdapter.DOG_BARK -> R.string.dog_bark
StreamAdapter.ELEPHANT -> R.string.elephant
else -> null
}
binding.guardianNameTextView.text = if (valueTitle != null) getString(valueTitle) else event?.classification?.title
binding.toolbarLayout.title = event?.streamId?.let { viewModel.getStream(it) }?.name
val timezoneString = event?.streamId?.let { viewModel.getStream(it) }?.timezoneRaw
val timezone = if (timezoneString == null) TimeZone.getDefault() else TimeZone.getTimeZone(timezoneString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,23 +163,15 @@ class CreateReportActivity : AppCompatActivity(), CreateReportListener {
}

private fun setNumberOnTitle(step: Int, isSelectedBoth: Boolean) {
when (step) {
StepCreateReport.EVIDENCE.step -> if (isSelectedBoth) setTitleToolbar(
getString(
R.string.create_report_title,
5
)
) else setTitleToolbar(getString(R.string.create_report_title, 3))
StepCreateReport.SCALE.step -> if (isSelectedBoth) setTitleToolbar(
getString(
R.string.create_report_title,
4
)
) else setTitleToolbar(getString(R.string.create_report_title, 2))
StepCreateReport.POACHING_EVIDENCE.step -> setTitleToolbar(getString(R.string.create_report_title, 3))
StepCreateReport.SCALE_POACHING.step -> setTitleToolbar(getString(R.string.create_report_title, 2))
StepCreateReport.ACTION.step -> setTitleToolbar(getString(R.string.create_report_title_one_step))
val text = when (step) {
StepCreateReport.EVIDENCE.step -> if (isSelectedBoth) getString(R.string.create_report_title, 5) else getString(R.string.create_report_title, 3)
StepCreateReport.SCALE.step -> if (isSelectedBoth) getString(R.string.create_report_title, 4) else getString(R.string.create_report_title, 2)
StepCreateReport.POACHING_EVIDENCE.step -> getString(R.string.create_report_title, 3)
StepCreateReport.SCALE_POACHING.step -> getString(R.string.create_report_title, 2)
StepCreateReport.ACTION.step -> getString(R.string.create_report_title_one_step)
else -> ""
}
setTitleToolbar(getString(R.string.create_report_steps) + " " + text)
}

private fun setColorOfTitle(str: String): SpannableString {
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_task.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14,2H6C4.9,2 4.01,2.9 4.01,4L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8L14,2zM18,20H6V4h7v5h5V20zM8.82,13.05L7.4,14.46L10.94,18l5.66,-5.66l-1.41,-1.41l-4.24,4.24L8.82,13.05z"
android:fillColor="#969faa"/>
</vector>
Loading

0 comments on commit 4598deb

Please sign in to comment.