mirror of
https://github.com/AU-COVIDSafe/mobile-android.git
synced 2025-01-18 16:56:34 +00:00
COVIDSafe code from version 2.3
This commit is contained in:
parent
66200cfa15
commit
f582698fce
43 changed files with 1595 additions and 75 deletions
|
@ -29,8 +29,8 @@ android {
|
|||
applicationId "au.gov.health.covidsafe"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 109
|
||||
versionName "2.2"
|
||||
versionCode 114
|
||||
versionName "2.4"
|
||||
buildConfigField "String", "GITHASH", "\"${getGitHash()}\""
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<activity android:name="au.gov.health.covidsafe.ui.devicename.DeviceNameChangePromptActivity" />
|
||||
<activity android:name="au.gov.health.covidsafe.ui.connection.InternetConnectionIssuesActivity" />
|
||||
<activity android:name="au.gov.health.covidsafe.ui.settings.ChanePostCodeActivity" />
|
||||
<activity android:name="au.gov.health.covidsafe.ui.restriction.RestrictionDescActivity" />
|
||||
|
||||
<activity
|
||||
android:name="au.gov.health.covidsafe.HomeActivity"
|
||||
|
|
|
@ -2,6 +2,8 @@ package au.gov.health.covidsafe
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import au.gov.health.covidsafe.app.TracerApp
|
||||
|
@ -15,13 +17,19 @@ import au.gov.health.covidsafe.sensor.SensorDelegate
|
|||
import au.gov.health.covidsafe.sensor.ble.BLEDevice
|
||||
import au.gov.health.covidsafe.sensor.datatype.*
|
||||
import au.gov.health.covidsafe.ui.devicename.DeviceNameChangePromptActivity
|
||||
import au.gov.health.covidsafe.ui.home.HomeFragment
|
||||
import au.gov.health.covidsafe.ui.restriction.RestrictionFragment
|
||||
import au.gov.health.covidsafe.ui.settings.SettingsFragment
|
||||
import au.gov.health.covidsafe.ui.utils.Utils
|
||||
import au.gov.health.covidsafe.utils.NetworkConnectionCheck
|
||||
import com.google.android.gms.tasks.OnCompleteListener
|
||||
import com.google.firebase.iid.FirebaseInstanceId
|
||||
import kotlinx.android.synthetic.main.activity_home.*
|
||||
|
||||
|
||||
private const val TAG = "HomeActivity"
|
||||
private const val UNAUTHORIZED = "Unauthorized"
|
||||
private const val UNAUTHENTICATED = "unauthenticated"
|
||||
|
||||
class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectionListener, SensorDelegate {
|
||||
|
||||
|
@ -29,6 +37,7 @@ class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectio
|
|||
var appUpdateAvailableMessageResponseLiveData = MutableLiveData<MessagesResponse>()
|
||||
var isWindowFocusChangeLiveData = MutableLiveData<Boolean>()
|
||||
var isJWTCorrupted = MutableLiveData<Boolean>()
|
||||
var isJWTExpired = MutableLiveData<Boolean>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -39,14 +48,50 @@ class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectio
|
|||
|
||||
setContentView(R.layout.activity_home)
|
||||
|
||||
Utils.startBluetoothMonitoringService(this)
|
||||
Utils.startBluetoothMonitoringService(this)
|
||||
|
||||
//Get Firebase Token
|
||||
getInstanceID()
|
||||
onClickListener()
|
||||
|
||||
NetworkConnectionCheck.addNetworkChangedListener(this, this)
|
||||
}
|
||||
|
||||
private fun onClickListener() {
|
||||
navigationView.setOnNavigationItemSelectedListener {
|
||||
when (it.itemId) {
|
||||
R.id.navigation_home -> {
|
||||
val homeFragment = HomeFragment()
|
||||
openFragment(homeFragment, "home")
|
||||
return@setOnNavigationItemSelectedListener true
|
||||
}
|
||||
R.id.navigation_restriction -> {
|
||||
val restrictionFragment = RestrictionFragment()
|
||||
openFragment(restrictionFragment, "restriction")
|
||||
return@setOnNavigationItemSelectedListener true
|
||||
}
|
||||
R.id.navigation_settings -> {
|
||||
val settingsFragment = SettingsFragment()
|
||||
openFragment(settingsFragment, "setting")
|
||||
return@setOnNavigationItemSelectedListener true
|
||||
}
|
||||
}
|
||||
false
|
||||
return@setOnNavigationItemSelectedListener false
|
||||
}
|
||||
}
|
||||
|
||||
private fun openFragment(fragment: Fragment, tag: String) {
|
||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.home_nav_host)?.tag
|
||||
if (tag != currentFragment) {
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.addToBackStack(tag)
|
||||
.replace(R.id.home_nav_host, fragment, tag)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
|
@ -65,11 +110,11 @@ class HomeActivity : FragmentActivity(), NetworkConnectionCheck.NetworkConnectio
|
|||
|
||||
private fun checkAndUpdateHealthStatus() {
|
||||
GetMessagesScheduler.scheduleGetMessagesJob {
|
||||
|
||||
if (it.errorBodyMessage.equals(UNAUTHORIZED)) {
|
||||
if (it.errorBodyMessage.equals(UNAUTHORIZED) || it.errorBodyMessage.equals(UNAUTHENTICATED)) {
|
||||
isJWTCorrupted.postValue(true)
|
||||
} else{
|
||||
} else {
|
||||
isJWTCorrupted.postValue(false)
|
||||
isJWTExpired.postValue(false)
|
||||
}
|
||||
|
||||
val isAppWithLatestVersion = it.messages.isNullOrEmpty()
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package au.gov.health.covidsafe.interactor.usecase
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import au.gov.health.covidsafe.interactor.Either
|
||||
import au.gov.health.covidsafe.interactor.Failure
|
||||
import au.gov.health.covidsafe.interactor.Success
|
||||
import au.gov.health.covidsafe.interactor.UseCase
|
||||
import au.gov.health.covidsafe.logging.CentralLog
|
||||
import au.gov.health.covidsafe.networking.request.GetRestrictionRequest
|
||||
import au.gov.health.covidsafe.networking.response.RestrictionResponse
|
||||
import au.gov.health.covidsafe.networking.service.AwsClient
|
||||
import au.gov.health.covidsafe.preference.Preference
|
||||
|
||||
private const val TAG = "GetCaseStatisticsUseCase"
|
||||
|
||||
class GetRestrictionUseCase(private val awsClient: AwsClient, lifecycle: Lifecycle, private val context: Context?, val state: String) : UseCase<RestrictionResponse, String>(lifecycle) {
|
||||
|
||||
override suspend fun run(params: String): Either<Exception, RestrictionResponse> {
|
||||
val token = Preference.getEncrypterJWTToken(context)
|
||||
return token?.let { jwtToken ->
|
||||
try {
|
||||
CentralLog.d(TAG, "GetCaseStatisticsUseCase run request")
|
||||
val response = retryRetrofitCall {
|
||||
awsClient.getRestriction("Bearer $jwtToken", state).execute()
|
||||
}
|
||||
|
||||
when {
|
||||
response?.code() == 200 -> {
|
||||
response.body()?.let { body ->
|
||||
Success(body)
|
||||
} ?: run {
|
||||
CentralLog.d(TAG, "GetCaseStatistics Invalid response")
|
||||
Failure(GetRestrictionUseCaseException.GetRestrictionUseCaseServiceException(response.code()))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
CentralLog.d(TAG, "GetCaseStatistics AWSAuthServiceError")
|
||||
Failure(GetRestrictionUseCaseException.GetRestrictionUseCaseServiceException(response?.code()))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Failure(e)
|
||||
}
|
||||
} ?: run {
|
||||
return Failure(Exception())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class GetRestrictionUseCaseException : Exception() {
|
||||
class GetRestrictionUseCaseServiceException(val code: Int? = null) : GetRestrictionUseCaseException()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package au.gov.health.covidsafe.interactor.usecase
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import au.gov.health.covidsafe.interactor.Either
|
||||
import au.gov.health.covidsafe.interactor.Failure
|
||||
import au.gov.health.covidsafe.interactor.Success
|
||||
import au.gov.health.covidsafe.interactor.UseCase
|
||||
import au.gov.health.covidsafe.logging.CentralLog
|
||||
import au.gov.health.covidsafe.networking.response.IssueInitialRefreshtokenResponse
|
||||
import au.gov.health.covidsafe.networking.service.AwsClient
|
||||
import au.gov.health.covidsafe.preference.Preference
|
||||
|
||||
private const val TAG = "GetCaseStatisticsUseCase"
|
||||
|
||||
class IssueInitialRefreshTokenUseCase(private val awsClient: AwsClient, lifecycle: Lifecycle, private val context: Context?) : UseCase<IssueInitialRefreshtokenResponse, String>(lifecycle) {
|
||||
|
||||
override suspend fun run(params: String): Either<Exception, IssueInitialRefreshtokenResponse> {
|
||||
val token = Preference.getEncrypterJWTToken(context)
|
||||
return token?.let { jwtToken ->
|
||||
try {
|
||||
CentralLog.d(TAG, "GetCaseStatisticsUseCase run request")
|
||||
val response = retryRetrofitCall {
|
||||
awsClient.issueInitialRefreshToken("Bearer $jwtToken").execute()
|
||||
}
|
||||
|
||||
when {
|
||||
response?.code() == 200 -> {
|
||||
response.body()?.let { body ->
|
||||
CentralLog.d(TAG, "IssueInitialRefreshTokenUseCase Success")
|
||||
Success(body)
|
||||
} ?: run {
|
||||
CentralLog.d(TAG, "GetCaseStatistics Invalid response")
|
||||
Failure(GetInitialRefreshtokenException.GetInitialRefreshtokenServiceException(response.code()))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
CentralLog.d(TAG, "GetCaseStatistics AWSAuthServiceError")
|
||||
Failure(GetInitialRefreshtokenException.GetInitialRefreshtokenServiceException(response?.code()))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Failure(e)
|
||||
}
|
||||
} ?: run {
|
||||
return Failure(Exception())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class GetInitialRefreshtokenException : Exception() {
|
||||
class GetInitialRefreshtokenServiceException(val code: Int? = null) : GetInitialRefreshtokenException()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package au.gov.health.covidsafe.interactor.usecase
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import au.gov.health.covidsafe.interactor.Either
|
||||
import au.gov.health.covidsafe.interactor.Failure
|
||||
import au.gov.health.covidsafe.interactor.Success
|
||||
import au.gov.health.covidsafe.interactor.UseCase
|
||||
import au.gov.health.covidsafe.logging.CentralLog
|
||||
import au.gov.health.covidsafe.networking.request.ReIssueAuthRequest
|
||||
import au.gov.health.covidsafe.networking.response.IssueInitialRefreshtokenResponse
|
||||
import au.gov.health.covidsafe.networking.service.AwsClient
|
||||
import au.gov.health.covidsafe.preference.Preference
|
||||
|
||||
private const val TAG = "GetCaseStatisticsUseCase"
|
||||
|
||||
class ReIssueAuth(private val awsClient: AwsClient, lifecycle: Lifecycle, private val context: Context?,
|
||||
private val subject: String?, private val refreshToken: String?) : UseCase<IssueInitialRefreshtokenResponse, String>(lifecycle) {
|
||||
|
||||
override suspend fun run(params: String): Either<Exception, IssueInitialRefreshtokenResponse> {
|
||||
val token = Preference.getEncrypterJWTToken(context)
|
||||
return try {
|
||||
val response = retryRetrofitCall {
|
||||
awsClient.reIssueAuth(ReIssueAuthRequest(subject, refreshToken)).execute()
|
||||
}
|
||||
|
||||
when {
|
||||
response?.code() == 200 -> {
|
||||
response.body()?.let { body ->
|
||||
CentralLog.d(TAG, "ReIssueAuth Success")
|
||||
Success(body)
|
||||
} ?: run {
|
||||
CentralLog.d(TAG, "ReIssueAuth Invalid response")
|
||||
Failure(GetReIssueAuthException.GetReIssueAuthExceptionServiceException(response.code()))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
CentralLog.d(TAG, "ReIssueAuth AWSAuthServiceError")
|
||||
Failure(GetReIssueAuthException.GetReIssueAuthExceptionServiceException(response?.code()))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class GetReIssueAuthException : Exception() {
|
||||
class GetReIssueAuthExceptionServiceException(val code: Int? = null) : GetReIssueAuthException()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package au.gov.health.covidsafe.networking.request
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class GetRestrictionRequest(val state: String?)
|
|
@ -0,0 +1,6 @@
|
|||
package au.gov.health.covidsafe.networking.request
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class ReIssueAuthRequest(val subject: String?, val refresh: String?)
|
|
@ -3,4 +3,4 @@ package au.gov.health.covidsafe.networking.response
|
|||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class AuthChallengeResponse(val token: String, val uuid: String, val token_expiry: String, val pin: String)
|
||||
data class AuthChallengeResponse(val token: String, val uuid: String, val token_expiry: String, val pin: String, val refreshToken: String)
|
|
@ -0,0 +1,6 @@
|
|||
package au.gov.health.covidsafe.networking.response
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class IssueInitialRefreshtokenResponse(val token: String, val refreshToken: String)
|
|
@ -0,0 +1,21 @@
|
|||
package au.gov.health.covidsafe.networking.response
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import au.gov.health.covidsafe.status.persistence.StatusRecord
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@Keep
|
||||
data class RestrictionResponse(@SerializedName("state") val state: String?,
|
||||
@SerializedName("activities") val activities: ArrayList<Activities>?)
|
||||
|
||||
@Keep
|
||||
data class Activities(
|
||||
@SerializedName("activity") val activity: String?,
|
||||
@SerializedName("activity-title") val activitiyTitle: String?,
|
||||
@SerializedName("content-date-title") val contentDateTitle: String?,
|
||||
@SerializedName("subheadings") val subheadings: ArrayList<Subheadings>,
|
||||
@SerializedName("content") val content: String?)
|
||||
@Keep
|
||||
data class Subheadings(
|
||||
@SerializedName("title") val title: String?,
|
||||
@SerializedName("content") val content: String?)
|
|
@ -1,10 +1,13 @@
|
|||
package au.gov.health.covidsafe.networking.service
|
||||
|
||||
import android.service.restrictions.RestrictionsReceiver
|
||||
import au.gov.health.covidsafe.BuildConfig
|
||||
import au.gov.health.covidsafe.networking.response.CaseStatisticResponse
|
||||
import au.gov.health.covidsafe.networking.request.AuthChallengeRequest
|
||||
import au.gov.health.covidsafe.networking.request.ChangePostcodeRequest
|
||||
import au.gov.health.covidsafe.networking.request.GetRestrictionRequest
|
||||
import au.gov.health.covidsafe.networking.request.OTPChallengeRequest
|
||||
import au.gov.health.covidsafe.networking.request.ReIssueAuthRequest
|
||||
import au.gov.health.covidsafe.networking.response.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.*
|
||||
|
@ -14,7 +17,7 @@ interface AwsClient {
|
|||
@POST(BuildConfig.END_POINT_PREFIX + "/initiateAuth")
|
||||
fun initiateAuth(@Body body: OTPChallengeRequest): Call<OTPChallengeResponse>
|
||||
|
||||
@POST(BuildConfig.END_POINT_PREFIX + "/respondToAuthChallenge")
|
||||
@POST(BuildConfig.END_POINT_PREFIX + "/v2/respondToAuthChallenge")
|
||||
fun respondToAuthChallenge(@Body body: AuthChallengeRequest): Call<AuthChallengeResponse>
|
||||
|
||||
@GET(BuildConfig.END_POINT_PREFIX + "/getTempId")
|
||||
|
@ -55,4 +58,15 @@ interface AwsClient {
|
|||
@POST(BuildConfig.END_POINT_PREFIX + "/device")
|
||||
fun changePostcode(@Header("Authorization") jwtToken: String?,
|
||||
@Body body: ChangePostcodeRequest): Call<UploadPostcodeResponse>
|
||||
|
||||
@POST(BuildConfig.END_POINT_PREFIX + "/issueInitialRefreshToken")
|
||||
fun issueInitialRefreshToken(@Header("Authorization") jwtToken: String?): Call<IssueInitialRefreshtokenResponse>
|
||||
|
||||
@POST(BuildConfig.END_POINT_PREFIX + "/reissueAuth")
|
||||
fun reIssueAuth(@Body body: ReIssueAuthRequest): Call<IssueInitialRefreshtokenResponse>
|
||||
|
||||
@GET(BuildConfig.END_POINT_PREFIX + "/restrictions")
|
||||
fun getRestriction(@Header("Authorization") jwtToken: String?,
|
||||
@Query("state") os: String): Call<RestrictionResponse>
|
||||
|
||||
}
|
|
@ -39,7 +39,10 @@ object Preference {
|
|||
private const val TURN_CASE_NUMBER = "TURN_CASE_NUMBER"
|
||||
private const val IS_REREGISTER = "IS_REREGISTER"
|
||||
private const val SELECTED_STATE = "SELECTED_STATE"
|
||||
private const val SELECTED_RESTRICTION_STATE = "SELECTED_STATE"
|
||||
private const val SENSOR_START = "SENSOR_START"
|
||||
private const val ADVERTISE_STOP = "ADVERTISE_STOP"
|
||||
private const val REFRESH_TOKEN = "REFRESH_TOKEN"
|
||||
|
||||
fun putDeviceID(context: Context, value: String) {
|
||||
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
|
@ -342,4 +345,57 @@ object Preference {
|
|||
return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
.getBoolean(ADVERTISE_STOP, false)
|
||||
}
|
||||
|
||||
fun putEncryptRefreshToken(context: Context?, refreshToken: String?) {
|
||||
context?.let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||
EncryptedSharedPreferences.create(
|
||||
PREF_ID,
|
||||
masterKeyAlias,
|
||||
context,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
).edit()?.putString(REFRESH_TOKEN, refreshToken)?.apply()
|
||||
} else {
|
||||
val aesEncryptedJwtToken = refreshToken?.let {
|
||||
AESEncryptionForPreAndroidM.encrypt(it)
|
||||
}
|
||||
|
||||
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
.edit().putString(REFRESH_TOKEN, aesEncryptedJwtToken)?.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getEncryptRefreshToken(context: Context?): String? {
|
||||
return context?.let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||
EncryptedSharedPreferences.create(
|
||||
PREF_ID,
|
||||
masterKeyAlias,
|
||||
context,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
).getString(REFRESH_TOKEN, null)
|
||||
} else {
|
||||
context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
?.getString(REFRESH_TOKEN, null)?.let {
|
||||
AESEncryptionForPreAndroidM.decrypt(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun putSelectedRestrictionState(context: Context, selectState: String): Boolean {
|
||||
return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
.edit().putString(SELECTED_RESTRICTION_STATE, selectState).commit()
|
||||
}
|
||||
|
||||
fun getSelectedRestrictionState(context: Context): String? {
|
||||
return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE)
|
||||
.getString(SELECTED_RESTRICTION_STATE, null)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import android.view.View
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.Navigator
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import au.gov.health.covidsafe.R
|
||||
import au.gov.health.covidsafe.ui.home.HomeFragmentDirections
|
||||
import java.lang.Exception
|
||||
|
||||
open class BaseFragment : Fragment() {
|
||||
|
||||
|
@ -22,7 +25,12 @@ open class BaseFragment : Fragment() {
|
|||
if (activity is HasBlockingState) {
|
||||
activity.isUiBlocked = true
|
||||
}
|
||||
NavHostFragment.findNavController(this).navigate(actionId, bundle, null, navigatorExtras)
|
||||
try {
|
||||
NavHostFragment.findNavController(this).navigate(actionId, bundle, null, navigatorExtras)
|
||||
} catch (e: Exception) {
|
||||
NavHostFragment.findNavController(this).navigateUp()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected fun popBackStack() {
|
||||
|
|
|
@ -52,6 +52,7 @@ import kotlinx.android.synthetic.main.view_national_case_statistics.national_cas
|
|||
import kotlinx.android.synthetic.main.view_state_case_statistics.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
import pub.devrel.easypermissions.AppSettingsDialog
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.text.SimpleDateFormat
|
||||
|
@ -153,6 +154,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
private fun initializeObservers() {
|
||||
(activity as HomeActivity?)?.run {
|
||||
isJWTCorrupted.observe(this@HomeFragment, isJwtExpired)
|
||||
isJWTExpired.observe(this@HomeFragment, isJwtExpired)
|
||||
isAppUpdateAvailableLiveData.observe(this@HomeFragment, latestAppAvailable)
|
||||
isWindowFocusChangeLiveData.observe(this@HomeFragment, refreshUiObserver)
|
||||
}
|
||||
|
@ -190,6 +192,25 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
txt_hotspot.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
})
|
||||
|
||||
homeFragmentViewModel.reIssueFail.observe(this, Observer {
|
||||
it?.let {
|
||||
if (it) {
|
||||
permissions_card_subtitle.visibility = GONE
|
||||
registration_layout.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
homeFragmentViewModel.reIssueSuccess.observe(this, Observer {
|
||||
it?.let {
|
||||
if (it) {
|
||||
jwtExpired = false
|
||||
refreshSetupCompleteOrIncompleteUi()
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val latestAppAvailable = Observer<Boolean> {
|
||||
|
@ -215,7 +236,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
|
||||
// disable the app update reminder for now
|
||||
app_update_reminder.visibility = GONE
|
||||
|
||||
getRefreshToken()
|
||||
initializePermissionViewButtonClickListeners()
|
||||
|
||||
initializeUploadTestDataNavigation()
|
||||
|
@ -233,6 +254,12 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
loadStateAndListener()
|
||||
}
|
||||
|
||||
private fun getRefreshToken() {
|
||||
if (Preference.getEncryptRefreshToken(this.requireContext()).isNullOrEmpty()) {
|
||||
homeFragmentViewModel.getRefreshToken(lifecycle)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadStateAndListener() {
|
||||
stateListAdapter = StateAdapter(this.requireContext())
|
||||
select_state.adapter = stateListAdapter
|
||||
|
@ -460,8 +487,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
|
||||
private fun updateJwtExpiredHeader() {
|
||||
if (jwtExpired) {
|
||||
permissions_card_subtitle.visibility = GONE
|
||||
registration_layout.visibility = VISIBLE
|
||||
homeFragmentViewModel.getReissueAuth(lifecycle)
|
||||
} else {
|
||||
permissions_card_subtitle.visibility = VISIBLE
|
||||
registration_layout.visibility = GONE
|
||||
|
@ -691,7 +717,7 @@ class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks, Networ
|
|||
battery_card_view.isEnabled = enableParent
|
||||
}
|
||||
|
||||
private fun createStateList(): ArrayList<String>{
|
||||
fun createStateList(): ArrayList<String>{
|
||||
val list = ArrayList<String>()
|
||||
list.add("Australia")
|
||||
list.add("Australian Capital Territory")
|
||||
|
|
|
@ -2,6 +2,7 @@ package au.gov.health.covidsafe.ui.home
|
|||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
@ -11,6 +12,8 @@ import au.gov.health.covidsafe.R
|
|||
import au.gov.health.covidsafe.extensions.isInternetAvailable
|
||||
import au.gov.health.covidsafe.factory.RetrofitServiceGenerator
|
||||
import au.gov.health.covidsafe.interactor.usecase.GetCaseStatisticsUseCase
|
||||
import au.gov.health.covidsafe.interactor.usecase.IssueInitialRefreshTokenUseCase
|
||||
import au.gov.health.covidsafe.interactor.usecase.ReIssueAuth
|
||||
import au.gov.health.covidsafe.logging.CentralLog
|
||||
import au.gov.health.covidsafe.networking.response.CaseDetailsData
|
||||
import au.gov.health.covidsafe.networking.response.CaseStatisticResponse
|
||||
|
@ -21,6 +24,8 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
private const val TAG = "HomeFragmentViewModel"
|
||||
|
||||
|
@ -49,6 +54,8 @@ class HomeFragmentViewModel(application: Application) : AndroidViewModel(applica
|
|||
val aquiredOversea = MutableLiveData<String>()
|
||||
val totalyDeathe = MutableLiveData<String>()
|
||||
val isV2Available = MutableLiveData<Boolean>()
|
||||
val reIssueFail = MutableLiveData<Boolean>(false)
|
||||
val reIssueSuccess = MutableLiveData<Boolean>(false)
|
||||
|
||||
private val viewModelJob = SupervisorJob()
|
||||
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
|
||||
|
@ -82,6 +89,73 @@ class HomeFragmentViewModel(application: Application) : AndroidViewModel(applica
|
|||
}
|
||||
}
|
||||
|
||||
fun getRefreshToken(lifecycle: Lifecycle) {
|
||||
context = getApplication() as Context
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
IssueInitialRefreshTokenUseCase(awsClient, lifecycle, getApplication()).invoke("",
|
||||
onSuccess = {
|
||||
it.refreshToken.let {
|
||||
Preference.putEncryptRefreshToken(context, it)
|
||||
}
|
||||
it.token.let {
|
||||
Preference.putEncrypterJWTToken(context, it)
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
CentralLog.e(TAG, "On Failure: ${it.message}")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getReissueAuth(lifecycle: Lifecycle) {
|
||||
var subject: String? = null
|
||||
context = getApplication() as Context
|
||||
|
||||
val token = Preference.getEncrypterJWTToken(context)
|
||||
val refreshToken = Preference.getEncryptRefreshToken(context)
|
||||
|
||||
val tokenSeparate = token?.split(".")
|
||||
var subjectItem: String? = null
|
||||
if (tokenSeparate?.size !=null && tokenSeparate.size >= 3) {
|
||||
subjectItem = tokenSeparate.let {
|
||||
it[1]
|
||||
}
|
||||
}
|
||||
|
||||
var subjectByte: ByteArray? = null
|
||||
subjectItem?.let { subjectByte = android.util.Base64.decode(subjectItem, android.util.Base64.DEFAULT)}
|
||||
val charset = Charsets.UTF_8
|
||||
|
||||
subjectByte?.let {
|
||||
val jsonModel = String(it, charset)
|
||||
val jsonObj = JSONObject(jsonModel)
|
||||
subject = jsonObj.get("sub").toString()
|
||||
}
|
||||
if (subject.isNullOrEmpty()) {
|
||||
reIssueFail.value = true
|
||||
} else {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
ReIssueAuth(awsClient, lifecycle, getApplication(), subject, refreshToken).invoke("",
|
||||
onSuccess = {
|
||||
it.refreshToken.let {
|
||||
Preference.putEncryptRefreshToken(context, it)
|
||||
}
|
||||
it.token.let {
|
||||
Preference.putEncrypterJWTToken(context, it)
|
||||
}
|
||||
reIssueSuccess.value = true
|
||||
},
|
||||
onFailure = {
|
||||
reIssueFail.value = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateOnSuccess(caseStatisticResponse: CaseStatisticResponse) {
|
||||
viewModelScope.launch {
|
||||
isRefreshing.value = false
|
||||
|
|
|
@ -86,9 +86,13 @@ class EnterPinPresenter(private val enterPinFragment: EnterPinFragment,
|
|||
Preference.putHandShakePin(enterPinFragment.context, handShakePin)
|
||||
}
|
||||
val jwtToken = authChallengeResponse?.token
|
||||
val refreshToken = authChallengeResponse?.refreshToken
|
||||
jwtToken.let {
|
||||
Preference.putEncrypterJWTToken(enterPinFragment.requireContext(), jwtToken)
|
||||
}
|
||||
refreshToken?.let {
|
||||
Preference.putEncryptRefreshToken(enterPinFragment.requireContext(), refreshToken)
|
||||
}
|
||||
enterPinFragment.hideKeyboard()
|
||||
enterPinFragment.navigateToNextPage()
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import au.gov.health.covidsafe.R
|
||||
import au.gov.health.covidsafe.networking.response.Subheadings
|
||||
|
||||
class RestrictionAdapter internal constructor(context: Context) :
|
||||
RecyclerView.Adapter<RestrictionAdapter.RestrictionViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
private var restrictionList = emptyList<Subheadings>()
|
||||
private var mListener: OnStateListClickListener? = null
|
||||
|
||||
interface OnStateListClickListener {
|
||||
fun onSectionClick(title: String?, content: String?)
|
||||
}
|
||||
|
||||
inner class RestrictionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val txtRestriction: TextView = itemView.findViewById(R.id.restriction_title)
|
||||
val listLayout: ConstraintLayout = itemView.findViewById(R.id.restriction_layout)
|
||||
}
|
||||
|
||||
fun setOnStateListClickListener(actionListener: OnStateListClickListener) {
|
||||
mListener = actionListener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RestrictionAdapter.RestrictionViewHolder {
|
||||
val itemView = inflater.inflate(R.layout.view_list_item_restriction, parent, false)
|
||||
return RestrictionViewHolder(itemView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RestrictionAdapter.RestrictionViewHolder, position: Int) {
|
||||
holder.txtRestriction.text = restrictionList[position].title
|
||||
|
||||
holder.listLayout.setOnClickListener {
|
||||
// setRecords(reestrictionList)
|
||||
mListener?.onSectionClick(restrictionList[position].title, restrictionList[position].content)
|
||||
}
|
||||
}
|
||||
|
||||
fun setRecords(list: List<Subheadings>) {
|
||||
this.restrictionList = list
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount() = restrictionList.size
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import au.gov.health.covidsafe.R
|
||||
import kotlinx.android.synthetic.main.activity_restriction_desc.*
|
||||
|
||||
class RestrictionDescActivity : AppCompatActivity() {
|
||||
|
||||
var htmlText: String = ""
|
||||
var title:String = ""
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// TO make sure scroll works with editTexts
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
setContentView(R.layout.activity_restriction_desc)
|
||||
val toolbar = findViewById<View>(R.id.toolbar_restriction_desc) as Toolbar
|
||||
setSupportActionBar(toolbar)
|
||||
val actionBar = supportActionBar
|
||||
actionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
toolbar.setNavigationOnClickListener { finish() }
|
||||
|
||||
val extras = intent.extras
|
||||
extras?.let {
|
||||
val toolbarTitle = intent.extras?.getString("toolbarTitle","")
|
||||
val titleSplit = toolbarTitle?.split(" ")
|
||||
if (titleSplit != null && titleSplit.size > 5) {
|
||||
supportActionBar?.setTitle("").toString()
|
||||
txt_toolbar_title2.text = toolbarTitle.toString()
|
||||
} else {
|
||||
supportActionBar?.setTitle(intent.extras?.getString("toolbarTitle","")).toString()
|
||||
txt_toolbar_title2.visibility = View.GONE
|
||||
}
|
||||
txt_activity.text = intent.extras?.getString("ActivityTitle","").toString()
|
||||
htmlText = intent.extras?.getString("htmlDesc","0").toString()
|
||||
}
|
||||
|
||||
val summary = "<html><head><style>a{color:#00661B}</style></head>" +
|
||||
"<body >$htmlText.</body></html>"
|
||||
|
||||
web_view.loadDataWithBaseURL(null, summary, "text/html", "utf-8", null)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import au.gov.health.covidsafe.R
|
||||
import au.gov.health.covidsafe.databinding.FragmentRestrictionBinding
|
||||
import au.gov.health.covidsafe.links.LinkBuilder
|
||||
import au.gov.health.covidsafe.networking.response.Subheadings
|
||||
import au.gov.health.covidsafe.preference.Preference
|
||||
import au.gov.health.covidsafe.ui.base.BaseFragment
|
||||
import au.gov.health.covidsafe.utils.AnimationUtils.slideAnimation
|
||||
import au.gov.health.covidsafe.utils.SlideDirection
|
||||
import au.gov.health.covidsafe.utils.SlideType
|
||||
import kotlinx.android.synthetic.main.fragment_restriction.*
|
||||
import kotlinx.android.synthetic.main.fragment_restriction.select_state
|
||||
|
||||
class RestrictionFragment: BaseFragment() {
|
||||
|
||||
private val viewModelRestriction: RestrictionViewModel by viewModels()
|
||||
private lateinit var stateListAdapter: StateAdapter
|
||||
private lateinit var stateActivityListAdapter: StateActivityAdapter
|
||||
private lateinit var restrictionListAdapter: RestrictionAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
initializeObservers()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return FragmentRestrictionBinding.inflate(layoutInflater).apply {
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
viewModel = viewModelRestriction
|
||||
}.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
viewModelRestriction.setup()
|
||||
loadStateAndListener()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupListener()
|
||||
}
|
||||
|
||||
private fun initializeObservers() {
|
||||
viewModelRestriction.activityList.observe(this, Observer { list ->
|
||||
list?.let {
|
||||
if (it.size > 0) {
|
||||
stateActivityListAdapter = StateActivityAdapter(this.requireContext())
|
||||
select_state_activity.adapter = stateActivityListAdapter
|
||||
val layoutManager = LinearLayoutManager(this.requireContext())
|
||||
select_state_activity.layoutManager = layoutManager
|
||||
|
||||
stateActivityListAdapter.setRecords(it, 0)
|
||||
|
||||
stateActivityListAdapter.setOnStateListClickListener(object : StateActivityAdapter.OnStateListClickListener {
|
||||
override fun onStateClick(subheading: List<Subheadings>, activity: String?, activityTitle: String?, time: String?, content: String?) {
|
||||
select_state_activity_layout.slideAnimation(SlideDirection.DOWN, SlideType.HIDE, 300)
|
||||
viewModelRestriction.setSelectedStateActivity(activity, activityTitle, time)
|
||||
loadRestrictionSection(subheading,activity, activityTitle, time, content)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadRestrictionSection(subheading: List<Subheadings>, activity: String? , activityTitle: String?, time: String?, content: String?) {
|
||||
restrictionListAdapter = RestrictionAdapter(this.requireContext())
|
||||
restriction_list.adapter = restrictionListAdapter
|
||||
val layoutManager = LinearLayoutManager(this.requireContext())
|
||||
restriction_list.layoutManager = layoutManager
|
||||
|
||||
val subContent = ArrayList<Subheadings>()
|
||||
if (!content.isNullOrEmpty()) {
|
||||
subContent.add(Subheadings(requireContext().getString(R.string.main_restrictions), content))
|
||||
}
|
||||
subheading.forEach {
|
||||
subContent.add(it)
|
||||
}
|
||||
restrictionListAdapter.setRecords(subContent)
|
||||
restrictionListAdapter.setOnStateListClickListener(object : RestrictionAdapter.OnStateListClickListener{
|
||||
override fun onSectionClick(title: String?, content: String?) {
|
||||
|
||||
val intent = Intent(requireContext(), RestrictionDescActivity::class.java)
|
||||
intent.putExtra("toolbarTitle", title)
|
||||
intent.putExtra("ActivityTitle", activityTitle)
|
||||
intent.putExtra("htmlDesc", content)
|
||||
requireContext().startActivity(intent)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadStateAndListener() {
|
||||
stateListAdapter = StateAdapter(this.requireContext())
|
||||
select_state.adapter = stateListAdapter
|
||||
val layoutManager = LinearLayoutManager(this.requireContext())
|
||||
select_state.layoutManager = layoutManager
|
||||
|
||||
stateListAdapter.setRecords(createStateList(), 0)
|
||||
|
||||
stateListAdapter.setOnStateListClickListener(object : StateAdapter.OnStateListClickListener{
|
||||
override fun onStateClick(state: String) {
|
||||
select_state_layout.slideAnimation(SlideDirection.DOWN, SlideType.HIDE, 300)
|
||||
viewModelRestriction.stateListVisible.value = false
|
||||
viewModelRestriction.setSelectedState(state, lifecycle)
|
||||
}
|
||||
})
|
||||
if (Preference.getSelectedRestrictionState(requireContext())!=null && Preference.getSelectedRestrictionState(requireContext())!="") {
|
||||
viewModelRestriction.loadActivity(Preference.getSelectedRestrictionState(requireContext()).toString(), lifecycle)
|
||||
}
|
||||
|
||||
btn_dissmiss.setOnClickListener {
|
||||
activity?.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
fun setupListener() {
|
||||
layout_select_activity.setOnClickListener {
|
||||
select_state_activity_layout.slideAnimation(SlideDirection.UP, SlideType.SHOW, 300)
|
||||
viewModelRestriction.stateActivityListVisible.value = true
|
||||
}
|
||||
|
||||
layout_select_state.setOnClickListener {
|
||||
select_state_layout.slideAnimation(SlideDirection.UP, SlideType.SHOW, 300)
|
||||
viewModelRestriction.stateListVisible.value = true
|
||||
}
|
||||
}
|
||||
|
||||
fun createStateList(): ArrayList<String> {
|
||||
val list = ArrayList<String>()
|
||||
list.add(requireContext().getString(R.string.australian_capital_territory))
|
||||
list.add(requireContext().getString(R.string.new_south_wales))
|
||||
list.add(requireContext().getString(R.string.northern_territory))
|
||||
list.add(requireContext().getString(R.string.queensland))
|
||||
list.add(requireContext().getString(R.string.south_australia))
|
||||
list.add(requireContext().getString(R.string.tasmania))
|
||||
list.add(requireContext().getString(R.string.victoria))
|
||||
list.add(requireContext().getString(R.string.western_australia))
|
||||
return list
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import au.gov.health.covidsafe.R
|
||||
import au.gov.health.covidsafe.factory.RetrofitServiceGenerator
|
||||
import au.gov.health.covidsafe.interactor.usecase.GetRestrictionUseCase
|
||||
import au.gov.health.covidsafe.networking.response.Activities
|
||||
import au.gov.health.covidsafe.networking.service.AwsClient
|
||||
import au.gov.health.covidsafe.preference.Preference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class RestrictionViewModel(application: Application): AndroidViewModel(application) {
|
||||
|
||||
val stateListVisible = MutableLiveData<Boolean>()
|
||||
val stateActivityListVisible = MutableLiveData<Boolean>()
|
||||
lateinit var context: Context
|
||||
val selectedState = MutableLiveData<String>()
|
||||
val selectedStateActivity = MutableLiveData<String>()
|
||||
val currentTime = MutableLiveData<String>()
|
||||
val linkVisible = MutableLiveData<Boolean>()
|
||||
val activityList = MutableLiveData<ArrayList<Activities>>()
|
||||
val errorLayout = MutableLiveData<Boolean>()
|
||||
|
||||
val awsClient: AwsClient by lazy {
|
||||
RetrofitServiceGenerator.createService(AwsClient::class.java)
|
||||
}
|
||||
|
||||
fun setup() {
|
||||
context = getApplication() as Context
|
||||
if (Preference.getSelectedRestrictionState(context) != "" && Preference.getSelectedRestrictionState(context) != null) {
|
||||
selectedState.value = Preference.getSelectedRestrictionState(context)
|
||||
}
|
||||
}
|
||||
init {
|
||||
stateListVisible.value = false
|
||||
stateActivityListVisible.value = false
|
||||
linkVisible.value = false
|
||||
errorLayout.value = false
|
||||
}
|
||||
|
||||
fun setSelectedState(state: String, lifecycle: Lifecycle) {
|
||||
linkVisible.value = false
|
||||
stateListVisible.value = false
|
||||
selectedState.value = state
|
||||
Preference.putSelectedRestrictionState(context, state)
|
||||
selectedStateActivity.value = ""
|
||||
|
||||
loadActivity(state, lifecycle)
|
||||
}
|
||||
|
||||
fun loadActivity(state: String, lifecycle: Lifecycle) {
|
||||
errorLayout.value = false
|
||||
val stateAbrv = getState(state)
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
GetRestrictionUseCase(awsClient, lifecycle, getApplication(), stateAbrv).invoke("",
|
||||
onSuccess = {
|
||||
val list = ArrayList<Activities>()
|
||||
it.activities?.forEach { activity ->
|
||||
list.add(activity)
|
||||
}
|
||||
activityList.value = list
|
||||
},
|
||||
onFailure = {
|
||||
errorLayout.value = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSelectedStateActivity(activity: String?, activityTitle: String?, time: String?) {
|
||||
stateActivityListVisible.value = false
|
||||
selectedStateActivity.value = activityTitle
|
||||
linkVisible.value = true
|
||||
currentTime.value = time
|
||||
}
|
||||
|
||||
fun tryAgain() {
|
||||
errorLayout.value = false
|
||||
}
|
||||
|
||||
fun getState(state: String?): String {
|
||||
return when(state) {
|
||||
context.getString(R.string.australian_capital_territory) -> "act"
|
||||
context.getString(R.string.new_south_wales) -> "nsw"
|
||||
context.getString(R.string.northern_territory) -> "nt"
|
||||
context.getString(R.string.queensland) -> "qld"
|
||||
context.getString(R.string.south_australia) -> "sa"
|
||||
context.getString(R.string.tasmania) -> "tas"
|
||||
context.getString(R.string.victoria) -> "vic"
|
||||
context.getString(R.string.western_australia) -> "wa"
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import au.gov.health.covidsafe.R
|
||||
import au.gov.health.covidsafe.networking.response.Activities
|
||||
import au.gov.health.covidsafe.networking.response.Subheadings
|
||||
|
||||
|
||||
class StateActivityAdapter internal constructor(context: Context) :
|
||||
RecyclerView.Adapter<StateActivityAdapter.StateViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
private var stateList = emptyList<Activities>()
|
||||
private var selectedState: Int = 0
|
||||
private var mListener: OnStateListClickListener? = null
|
||||
|
||||
interface OnStateListClickListener {
|
||||
fun onStateClick(subHeading: List<Subheadings>, activity: String?, activityTitle: String?, time: String?, content: String?)
|
||||
}
|
||||
|
||||
inner class StateViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val txtStateName: TextView = itemView.findViewById(R.id.state_name)
|
||||
val imageStateSelect: ImageView = itemView.findViewById(R.id.img_state_select)
|
||||
val endLine: View = itemView.findViewById(R.id.end_line)
|
||||
val countryListLayout: ConstraintLayout = itemView.findViewById(R.id.country_list_item)
|
||||
}
|
||||
|
||||
fun setOnStateListClickListener(actionListener: OnStateListClickListener) {
|
||||
mListener = actionListener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StateActivityAdapter.StateViewHolder {
|
||||
val itemView = inflater.inflate(R.layout.view_list_item_state, parent, false)
|
||||
return StateViewHolder(itemView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: StateActivityAdapter.StateViewHolder, position: Int) {
|
||||
holder.txtStateName.text = stateList[position].activitiyTitle
|
||||
holder.imageStateSelect.visibility = View.GONE
|
||||
holder.endLine.visibility = View.VISIBLE
|
||||
|
||||
if (position == selectedState) {
|
||||
holder.imageStateSelect.visibility = View.VISIBLE
|
||||
}
|
||||
if (position == (this.stateList.size - 1)) {
|
||||
holder.endLine.visibility = View.GONE
|
||||
}
|
||||
holder.countryListLayout.setOnClickListener {
|
||||
setRecords(stateList, position)
|
||||
mListener?.onStateClick(stateList[position].subheadings, stateList[position].activity, stateList[position].activitiyTitle, stateList[position].contentDateTitle, stateList[position].content)
|
||||
}
|
||||
}
|
||||
|
||||
fun setRecords(stateList: List<Activities>, selectedState: Int) {
|
||||
this.stateList = stateList
|
||||
this.selectedState = selectedState
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount() = stateList.size
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package au.gov.health.covidsafe.ui.restriction
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import au.gov.health.covidsafe.R
|
||||
|
||||
|
||||
class StateAdapter internal constructor(context: Context) :
|
||||
RecyclerView.Adapter<StateAdapter.StateViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
private var stateList = emptyList<String>()
|
||||
private var selectedState: Int = 0
|
||||
private var mListener: OnStateListClickListener? = null
|
||||
|
||||
interface OnStateListClickListener {
|
||||
fun onStateClick(state: String)
|
||||
}
|
||||
|
||||
inner class StateViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val txtStateName: TextView = itemView.findViewById(R.id.state_name)
|
||||
val imageStateSelect: ImageView = itemView.findViewById(R.id.img_state_select)
|
||||
val endLine: View = itemView.findViewById(R.id.end_line)
|
||||
val countryListLayout: ConstraintLayout = itemView.findViewById(R.id.country_list_item)
|
||||
}
|
||||
|
||||
fun setOnStateListClickListener(actionListener: OnStateListClickListener) {
|
||||
mListener = actionListener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StateAdapter.StateViewHolder {
|
||||
val itemView = inflater.inflate(R.layout.view_list_item_state, parent, false)
|
||||
return StateViewHolder(itemView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: StateAdapter.StateViewHolder, position: Int) {
|
||||
holder.txtStateName.text = stateList[position]
|
||||
holder.imageStateSelect.visibility = View.GONE
|
||||
holder.endLine.visibility = View.VISIBLE
|
||||
|
||||
if (position == selectedState) {
|
||||
holder.imageStateSelect.visibility = View.VISIBLE
|
||||
}
|
||||
if (position == (this.stateList.size - 1)) {
|
||||
holder.endLine.visibility = View.GONE
|
||||
}
|
||||
holder.countryListLayout.setOnClickListener {
|
||||
setRecords(stateList, position)
|
||||
mListener?.onStateClick(stateList[position])
|
||||
}
|
||||
}
|
||||
|
||||
fun setRecords(stateList: List<String>, selectedState: Int) {
|
||||
this.stateList = stateList
|
||||
this.selectedState = selectedState
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount() = stateList.size
|
||||
|
||||
}
|
5
app/src/main/res/drawable/btm_navigation.xml
Normal file
5
app/src/main/res/drawable/btm_navigation.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/dark_green" android:state_checked="true"/>
|
||||
<item android:color="@color/black"/>
|
||||
</selector>
|
23
app/src/main/res/drawable/btm_navigation_background.xml
Normal file
23
app/src/main/res/drawable/btm_navigation_background.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="false">
|
||||
<layer-list>
|
||||
<item android:bottom="-8dp" android:left="-8dp" android:right="-8dp">
|
||||
<shape>
|
||||
<solid android:color="@color/lighter_green"/>
|
||||
<stroke android:color="@color/dark_green" android:width="1dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
</item>
|
||||
<item android:state_checked="true">
|
||||
<layer-list>
|
||||
<item android:bottom="-8dp" android:left="-8dp" android:right="-8dp">
|
||||
<shape>
|
||||
<solid android:color="@color/lighter_green"/>
|
||||
<stroke android:color="@color/dark_green" android:width="4dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
</item>
|
||||
</selector>
|
6
app/src/main/res/drawable/home_menu.xml
Normal file
6
app/src/main/res/drawable/home_menu.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/lighter_green"/>
|
||||
<item android:color="@color/dark_green" android:state_checked="true"/>
|
||||
<item android:state_pressed="true" android:state_enabled="true" android:color="@color/black" />
|
||||
</selector>
|
12
app/src/main/res/drawable/ic_home.xml
Normal file
12
app/src/main/res/drawable/ic_home.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="22">
|
||||
<path
|
||||
android:pathData="M23.846,10.3569C24.0094,10.6444 24.0176,10.9958 23.8705,11.2913L20.9534,17.2807C20.7818,17.64 20.4059,17.8716 20.0055,17.8716H17.2927C16.9985,17.8716 16.7207,17.7518 16.5246,17.5442L13.9098,14.805L21.9257,6.8991L23.846,10.3569ZM6.1308,11.6906C5.4689,10.9958 5.5098,9.9097 6.2207,9.2629C6.9316,8.616 8.0429,8.6559 8.7047,9.3427L11.5074,12.2815L20.1689,3.7367L18.2405,0.2708C18.0117,-0.1445 17.3825,-0.0646 17.2681,0.3906L16.4919,3.4492C16.4183,3.7287 16.1405,3.8964 15.8545,3.8245L13.1417,3.1697C12.8557,3.0978 12.6841,2.8263 12.7576,2.5468L13.0191,1.5086C13.1008,1.1812 12.8475,0.8697 12.5043,0.8697H9.8242C9.7016,0.8697 9.579,0.9177 9.481,0.9975L0.3701,8.632C0.0187,8.9275 -0.0957,9.4066 0.0841,9.8139L2.4701,15.3082C2.846,16.1786 3.9246,16.514 4.7499,16.0189L8.2553,13.9186L6.1308,11.6906ZM19.3845,20.6826L19.981,19.6684C20.2833,19.1493 19.9074,18.5105 19.2946,18.5105H18.1016C17.4969,18.5105 17.1129,19.1573 17.4152,19.6684L18.0117,20.6826C18.3222,21.2017 19.0822,21.2017 19.3845,20.6826Z"
|
||||
android:fillColor="#131313"/>
|
||||
<path
|
||||
android:pathData="M11.4664,15.8354H11.4501C11.1477,15.8274 10.8699,15.7076 10.6656,15.492L6.6127,11.2515C6.196,10.8203 6.2205,10.1415 6.6699,9.7342C7.1112,9.3269 7.8057,9.3509 8.2225,9.7901L11.4991,13.216L22.1217,2.7386C22.5466,2.3154 23.2411,2.3154 23.6742,2.7306C24.1073,3.1459 24.1073,3.8247 23.6824,4.2479L12.2509,15.5239C12.0384,15.7236 11.7606,15.8354 11.4664,15.8354Z"
|
||||
android:fillColor="#131313"/>
|
||||
</vector>
|
20
app/src/main/res/drawable/ic_restriction.xml
Normal file
20
app/src/main/res/drawable/ic_restriction.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<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="M19,11H5C3.8954,11 3,11.8954 3,13V20C3,21.1046 3.8954,22 5,22H19C20.1046,22 21,21.1046 21,20V13C21,11.8954 20.1046,11 19,11Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M7,11V7C6.9988,5.7601 7.4583,4.5639 8.2894,3.6437C9.1205,2.7235 10.2638,2.1449 11.4975,2.0203C12.7312,1.8957 13.9671,2.2339 14.9655,2.9693C15.9638,3.7048 16.6533,4.7849 16.9,6"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
20
app/src/main/res/drawable/ic_setting.xml
Normal file
20
app/src/main/res/drawable/ic_setting.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<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="M12,15C13.6569,15 15,13.6569 15,12C15,10.3431 13.6569,9 12,9C10.3431,9 9,10.3431 9,12C9,13.6569 10.3431,15 12,15Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M19.4,15C19.2669,15.3016 19.2272,15.6362 19.286,15.9606C19.3448,16.285 19.4995,16.5843 19.73,16.82L19.79,16.88C19.976,17.0657 20.1235,17.2863 20.2241,17.5291C20.3248,17.7719 20.3766,18.0322 20.3766,18.295C20.3766,18.5578 20.3248,18.8181 20.2241,19.0609C20.1235,19.3037 19.976,19.5243 19.79,19.71C19.6043,19.896 19.3837,20.0435 19.1409,20.1441C18.8981,20.2448 18.6378,20.2966 18.375,20.2966C18.1122,20.2966 17.8519,20.2448 17.6091,20.1441C17.3663,20.0435 17.1457,19.896 16.96,19.71L16.9,19.65C16.6643,19.4195 16.365,19.2648 16.0406,19.206C15.7162,19.1472 15.3816,19.1869 15.08,19.32C14.7842,19.4468 14.532,19.6572 14.3543,19.9255C14.1766,20.1938 14.0813,20.5082 14.08,20.83V21C14.08,21.5304 13.8693,22.0391 13.4942,22.4142C13.1191,22.7893 12.6104,23 12.08,23C11.5496,23 11.0409,22.7893 10.6658,22.4142C10.2907,22.0391 10.08,21.5304 10.08,21V20.91C10.0723,20.579 9.9651,20.258 9.7725,19.9887C9.5799,19.7194 9.3107,19.5143 9,19.4C8.6984,19.2669 8.3638,19.2272 8.0394,19.286C7.715,19.3448 7.4157,19.4995 7.18,19.73L7.12,19.79C6.9342,19.976 6.7137,20.1235 6.4709,20.2241C6.2281,20.3248 5.9678,20.3766 5.705,20.3766C5.4422,20.3766 5.1819,20.3248 4.9391,20.2241C4.6963,20.1235 4.4757,19.976 4.29,19.79C4.1041,19.6043 3.9565,19.3837 3.8559,19.1409C3.7552,18.8981 3.7034,18.6378 3.7034,18.375C3.7034,18.1122 3.7552,17.8519 3.8559,17.6091C3.9565,17.3663 4.1041,17.1457 4.29,16.96L4.35,16.9C4.5805,16.6643 4.7352,16.365 4.794,16.0406C4.8528,15.7162 4.8131,15.3816 4.68,15.08C4.5532,14.7842 4.3428,14.532 4.0745,14.3543C3.8062,14.1766 3.4918,14.0813 3.17,14.08H3C2.4696,14.08 1.9609,13.8693 1.5858,13.4942C1.2107,13.1191 1,12.6104 1,12.08C1,11.5496 1.2107,11.0409 1.5858,10.6658C1.9609,10.2907 2.4696,10.08 3,10.08H3.09C3.421,10.0723 3.742,9.9651 4.0113,9.7725C4.2806,9.5799 4.4857,9.3107 4.6,9C4.7331,8.6984 4.7728,8.3638 4.714,8.0394C4.6552,7.715 4.5005,7.4157 4.27,7.18L4.21,7.12C4.0241,6.9342 3.8765,6.7137 3.7759,6.4709C3.6752,6.2281 3.6234,5.9678 3.6234,5.705C3.6234,5.4422 3.6752,5.1819 3.7759,4.9391C3.8765,4.6963 4.0241,4.4757 4.21,4.29C4.3958,4.1041 4.6163,3.9565 4.8591,3.8559C5.1019,3.7552 5.3622,3.7034 5.625,3.7034C5.8878,3.7034 6.1481,3.7552 6.3909,3.8559C6.6337,3.9565 6.8542,4.1041 7.04,4.29L7.1,4.35C7.3357,4.5805 7.635,4.7352 7.9594,4.794C8.2838,4.8528 8.6184,4.8131 8.92,4.68H9C9.2958,4.5532 9.548,4.3428 9.7257,4.0745C9.9034,3.8062 9.9987,3.4918 10,3.17V3C10,2.4696 10.2107,1.9609 10.5858,1.5858C10.9609,1.2107 11.4696,1 12,1C12.5304,1 13.0391,1.2107 13.4142,1.5858C13.7893,1.9609 14,2.4696 14,3V3.09C14.0013,3.4118 14.0966,3.7262 14.2743,3.9945C14.452,4.2628 14.7042,4.4732 15,4.6C15.3016,4.7331 15.6362,4.7728 15.9606,4.714C16.285,4.6552 16.5843,4.5005 16.82,4.27L16.88,4.21C17.0657,4.0241 17.2863,3.8765 17.5291,3.7759C17.7719,3.6752 18.0322,3.6234 18.295,3.6234C18.5578,3.6234 18.8181,3.6752 19.0609,3.7759C19.3037,3.8765 19.5243,4.0241 19.71,4.21C19.896,4.3958 20.0435,4.6163 20.1441,4.8591C20.2448,5.1019 20.2966,5.3622 20.2966,5.625C20.2966,5.8878 20.2448,6.1481 20.1441,6.3909C20.0435,6.6337 19.896,6.8542 19.71,7.04L19.65,7.1C19.4195,7.3357 19.2648,7.635 19.206,7.9594C19.1472,8.2838 19.1869,8.6184 19.32,8.92V9C19.4468,9.2958 19.6572,9.548 19.9255,9.7257C20.1938,9.9034 20.5082,9.9987 20.83,10H21C21.5304,10 22.0391,10.2107 22.4142,10.5858C22.7893,10.9609 23,11.4696 23,12C23,12.5304 22.7893,13.0391 22.4142,13.4142C22.0391,13.7893 21.5304,14 21,14H20.91C20.5882,14.0013 20.2738,14.0966 20.0055,14.2743C19.7372,14.452 19.5268,14.7042 19.4,15V15Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
|
@ -1,9 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/home_nav_host"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_home" />
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@color/splash_background"
|
||||
android:backgroundTint="@color/splash_frame_background"
|
||||
tools:context=".HomeActivity"
|
||||
>
|
||||
<fragment
|
||||
android:id="@+id/home_nav_host"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_home"
|
||||
app:layout_constraintBottom_toTopOf="@+id/navigationView"/>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/navigationView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginStart="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:itemBackground="@drawable/btm_navigation_background"
|
||||
app:itemIconTint="@drawable/btm_navigation"
|
||||
app:itemTextColor="@drawable/btm_navigation"
|
||||
app:menu="@menu/navigation"
|
||||
android:elevation="@dimen/space_24">
|
||||
</com.google.android.material.bottomnavigation.BottomNavigationView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
68
app/src/main/res/layout/activity_restriction_desc.xml
Normal file
68
app/src/main/res/layout/activity_restriction_desc.xml
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="@dimen/space_24">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar_restriction_desc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/lighter_green"
|
||||
app:title="@string/main_restrictions"
|
||||
app:popupTheme="@style/MobileKit.FeedbackTheme.PopupOverlay" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_toolbar_title2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/space_16"
|
||||
android:paddingBottom="@dimen/space_16"
|
||||
android:ellipsize="end"
|
||||
style="?textAppearanceBody2"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/black"
|
||||
android:textStyle="bold"
|
||||
android:background="@color/lighter_green"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_activity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/space_16"
|
||||
android:paddingBottom="@dimen/space_16"
|
||||
style="?textAppearanceBody2"
|
||||
android:textColor="@color/dark_green"
|
||||
android:background="@color/lighter_green"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/space_16"
|
||||
android:layout_marginEnd="@dimen/space_16"
|
||||
android:orientation="vertical">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/space_16"
|
||||
android:layout_marginBottom="@dimen/space_16"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
|
@ -19,21 +19,21 @@
|
|||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/home_header_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
android:gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/settings_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:src="@drawable/ic_settings_outline_black"/>
|
||||
<ImageView
|
||||
android:id="@+id/settings_image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:src="@drawable/ic_settings_outline_black"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -49,7 +49,6 @@
|
|||
android:textAllCaps="false"
|
||||
android:textColor="@color/slate_black_1" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
|
|
326
app/src/main/res/layout/fragment_restriction.xml
Normal file
326
app/src/main/res/layout/fragment_restriction.xml
Normal file
|
@ -0,0 +1,326 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="au.gov.health.covidsafe.ui.restriction.RestrictionViewModel" />
|
||||
</data>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/home_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/screen_background">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/restriction_toolbar"
|
||||
app:titleTextAppearance="@style/ToolbarStyle.TitleTextStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/settings_toolbar_height"
|
||||
android:background="@color/lighter_green"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:buttonGravity="center_vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navigationContentDescription="@string/navigation_back_button_content_description"
|
||||
app:title="@string/restrictions_heading"
|
||||
app:titleTextColor="@color/slate_black_1"
|
||||
tools:layout_editor_absoluteX="0dp" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="50dp"
|
||||
android:layout_marginTop="@dimen/settings_toolbar_height">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_select_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/space_16"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_select_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:lineSpacingExtra="5dp"
|
||||
style="?textAppearanceBody1"
|
||||
android:text="@string/restrictions_select_state" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_selected_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
style="?textAppearanceBody1"
|
||||
android:textColor="@color/dark_green"
|
||||
android:text="@{viewModel.selectedState}"
|
||||
tools:ignore="MissingConstraints"
|
||||
visibility="@{viewModel.selectedState != null}"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_select_activity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/space_16"
|
||||
android:layout_marginTop="1dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@+id/layout_select_state"
|
||||
android:background="@color/white"
|
||||
visibility="@{viewModel.selectedState != null}">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_select_activity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:lineSpacingExtra="5dp"
|
||||
style="?textAppearanceBody1"
|
||||
android:text="@string/restrictions_select_activity" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_selected_activity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
style="?textAppearanceBody1"
|
||||
android:textColor="@color/dark_green"
|
||||
android:text="@{viewModel.selectedStateActivity}"
|
||||
visibility="@{viewModel.selectedStateActivity != null}"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txt_time"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/space_32"
|
||||
android:paddingStart="@dimen/space_16"
|
||||
android:paddingEnd="@dimen/space_16"
|
||||
android:paddingBottom="@dimen/space_16"
|
||||
style="?textAppearanceBody1"
|
||||
android:textColor="@color/error_red"
|
||||
android:text="@{viewModel.currentTime}"
|
||||
app:layout_constraintTop_toBottomOf="@+id/layout_select_activity"
|
||||
visibility="@{viewModel.linkVisible}"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/restriction_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/txt_time"
|
||||
visibility="@{viewModel.linkVisible}"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/space_16"
|
||||
android:layout_marginLeft="@dimen/space_16"
|
||||
android:layout_marginBottom="@dimen/settings_toolbar_height"
|
||||
android:lineSpacingExtra="5dp"
|
||||
style="?textAppearanceBody1"
|
||||
android:layout_gravity="bottom"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/grey5"
|
||||
android:text="@string/restrictions_disclaimer"
|
||||
visibility="@{!viewModel.linkVisible}"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/select_state_layout"
|
||||
android:layout_marginRight="@dimen/space_24"
|
||||
android:layout_marginLeft="@dimen/space_24"
|
||||
android:layout_marginTop="@dimen/space_24"
|
||||
android:layout_marginBottom="@dimen/settings_toolbar_height"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/space_16"
|
||||
app:layout_anchorGravity="center"
|
||||
android:background="@color/white"
|
||||
android:elevation="12dp"
|
||||
visibility="@{viewModel.stateListVisible}"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:animateLayoutChanges="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_select_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/space_16"
|
||||
android:layout_marginEnd="@dimen/space_16"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:text="@string/restrictions_select_state" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/grey4"
|
||||
android:layout_marginTop="@dimen/space_12"
|
||||
android:layout_marginBottom="@dimen/space_12"
|
||||
app:layout_constraintTop_toBottomOf="@+id/layout_select_activity"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/select_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/space_16"
|
||||
android:layout_marginEnd="@dimen/space_16" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/select_state_activity_layout"
|
||||
android:layout_marginRight="@dimen/space_24"
|
||||
android:layout_marginLeft="@dimen/space_24"
|
||||
android:layout_marginTop="@dimen/space_24"
|
||||
android:layout_marginBottom="@dimen/settings_toolbar_height"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/space_16"
|
||||
app:layout_anchorGravity="center"
|
||||
android:background="@color/white"
|
||||
android:elevation="12dp"
|
||||
visibility="@{viewModel.stateActivityListVisible}"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:animateLayoutChanges="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/space_16"
|
||||
android:layout_marginEnd="@dimen/space_16"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/slate_black_2"
|
||||
android:gravity="center"
|
||||
android:text="@string/restrictions_select_activity" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/grey4"
|
||||
android:layout_marginTop="@dimen/space_12"
|
||||
android:layout_marginBottom="@dimen/space_12"
|
||||
app:layout_constraintTop_toBottomOf="@+id/layout_select_activity"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/select_state_activity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/space_16"
|
||||
android:layout_marginEnd="@dimen/space_16" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_layout_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
visibility="@{viewModel.errorLayout}"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="top">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/case_loading_animation_view"
|
||||
android:layout_width="@dimen/covidsafe_loading_animation_size"
|
||||
android:layout_height="@dimen/covidsafe_loading_animation_size"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/space_40"
|
||||
android:layout_marginBottom="@dimen/space_24"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_fileName="loading_upload.json"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_speed="1"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/space_16"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black"
|
||||
android:gravity="center"
|
||||
android:text="@string/restrictions_error_heading" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/space_16"
|
||||
style="?textAppearanceBody2"
|
||||
android:gravity="center"
|
||||
android:text="@string/restrictions_error_message" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/try_again"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_marginTop="@dimen/space_40"
|
||||
android:layout_marginStart="@dimen/space_32"
|
||||
android:layout_marginEnd="@dimen/space_32"
|
||||
android:text="@string/restrictions_error_try"
|
||||
android:onClick="@{() -> viewModel.tryAgain()}"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btn_dissmiss"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/space_16"
|
||||
style="?textAppearanceBody2"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/dark_green"
|
||||
android:text="@string/restrictions_error_dismiss" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
|
@ -18,7 +18,6 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navigationContentDescription="@string/navigation_back_button_content_description"
|
||||
app:navigationIcon="@drawable/ic_up"
|
||||
app:title="@string/settings"
|
||||
app:titleTextColor="@color/slate_black_1"
|
||||
tools:layout_editor_absoluteX="0dp" />
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
android:layout_height="match_parent"
|
||||
android:id="@+id/root"
|
||||
android:orientation="vertical"
|
||||
tools:context=".HomeActivity">
|
||||
tools:context=".HomeActivity"
|
||||
android:background="@color/white">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
|
@ -17,50 +18,59 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navigationIcon="@drawable/ic_up"
|
||||
app:navigationContentDescription="@string/navigation_back_button_content_description"/>
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_nav_host_upload"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_upload" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/keyline_5"
|
||||
android:layout_marginTop="@dimen/keyline_4"
|
||||
android:layout_marginEnd="@dimen/keyline_5"
|
||||
android:layout_marginBottom="@dimen/keyline_7"
|
||||
android:orientation="horizontal">
|
||||
<fragment
|
||||
android:id="@+id/fragment_nav_host_upload"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_upload" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/upload_answerNo"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/keyline_0"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/upload_answer_no" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/keyline_5"
|
||||
android:layout_marginTop="@dimen/keyline_4"
|
||||
android:layout_marginEnd="@dimen/keyline_5"
|
||||
android:layout_marginBottom="@dimen/keyline_7"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/upload_answerYes"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/keyline_0"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/upload_answer_yes" />
|
||||
<Button
|
||||
android:id="@+id/upload_answerNo"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/keyline_0"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/upload_answer_no" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/upload_continue"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/action_continue" />
|
||||
</LinearLayout>
|
||||
<Button
|
||||
android:id="@+id/upload_answerYes"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/keyline_0"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/upload_answer_yes" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/upload_continue"
|
||||
style="?attr/textAppearanceButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/action_continue" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
|
@ -20,7 +20,6 @@
|
|||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="@dimen/space_16"
|
||||
android:layout_toStartOf="@+id/active_tick_image_view"
|
||||
android:accessibilityTraversalBefore="@id/home_header_settings"
|
||||
android:text="@string/home_header_active_title"
|
||||
android:textColor="@color/dark_green"
|
||||
android:textSize="@dimen/text_size_20" />
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/permission_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:text="@string/jwt_heading"
|
||||
android:text="@string/jwt_expired"
|
||||
tools:text="Please register again" />
|
||||
|
||||
<TextView
|
||||
|
@ -147,7 +147,7 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ic_register_again"
|
||||
tools:visibility="visible"
|
||||
android:text="@string/jwt_description"
|
||||
android:text="@string/jwt_expired_description"
|
||||
tools:text="There is an issue with your registration details." />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
40
app/src/main/res/layout/view_list_item_restriction.xml
Normal file
40
app/src/main/res/layout/view_list_item_restriction.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/restriction_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/space_16"
|
||||
android:paddingBottom="@dimen/space_16"
|
||||
android:paddingStart="@dimen/space_16"
|
||||
android:paddingEnd="@dimen/space_24"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/restriction_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/space_24"
|
||||
android:paddingEnd="@dimen/space_32"
|
||||
android:gravity="start"
|
||||
android:text="@string/country_region_name_au"
|
||||
android:textSize="18sp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="viewStart"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_state_select"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/keyline_1"
|
||||
android:layout_marginEnd="@dimen/space_4"
|
||||
android:layout_marginStart="@dimen/space_4"
|
||||
android:src="@drawable/ic_chevron_right_black"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/restriction_title" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -12,13 +12,15 @@
|
|||
<TextView
|
||||
android:id="@+id/state_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/keyline_5"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/keyline_4"
|
||||
android:layout_marginEnd="@dimen/space_24"
|
||||
android:lines="1"
|
||||
android:paddingEnd="@dimen/space_24"
|
||||
android:singleLine="false"
|
||||
android:gravity="start"
|
||||
android:text="@string/country_region_name_au"
|
||||
android:textSize="16sp"
|
||||
android:maxLines="2"
|
||||
android:textAlignment="viewStart"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
|
17
app/src/main/res/menu/navigation.xml
Normal file
17
app/src/main/res/menu/navigation.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/navigation_home"
|
||||
android:icon="@drawable/ic_home"
|
||||
android:title="@string/home_bottom_nav" />
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_restriction"
|
||||
android:icon="@drawable/ic_restriction"
|
||||
android:title="@string/restrictions_heading"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_settings"
|
||||
android:icon="@drawable/ic_setting"
|
||||
android:title="@string/settings"/>
|
||||
</menu>
|
|
@ -13,6 +13,7 @@
|
|||
<color name="grey">#E2E2E2</color>
|
||||
<color name="grey4">#E1E5E5</color>
|
||||
<color name="lighter_green">#C8FFB9</color>
|
||||
<color name="grey5">#959595</color>
|
||||
|
||||
<!-- Splash Screen -->
|
||||
<color name="splash_background">#E5E5E5</color>
|
||||
|
|
|
@ -304,6 +304,7 @@
|
|||
<string name="home_app_permission_status_title">Check your settings</string>
|
||||
<string name="home_been_tested_title">Has a health official asked you to upload your data?</string>
|
||||
<string name="home_bluetooth_permission">Bluetooth®: %s</string>
|
||||
<string name="home_bottom_nav">Home</string>
|
||||
<string name="home_data_has_been_uploaded">Your data has been uploaded</string>
|
||||
<string name="home_data_has_been_uploaded_message">You\’re helping stop the spread of COVID-19 by uploading your data daily while in self-isolation.</string>
|
||||
<string name="home_data_uploaded">Register for self isolation</string>
|
||||
|
@ -396,6 +397,7 @@
|
|||
<string name="learn_more">Learn more</string>
|
||||
<string name="loading_numbers">Loading latest numbers</string>
|
||||
<string name="locally_acquired">%@ locally acquired</string>
|
||||
<string name="main_restrictions">Main restrictions</string>
|
||||
<!-- Splash Screen -->
|
||||
<string name="migration_in_progress"> COVIDSafe update in progress. \n\n Please make sure you phone is not switched off until the update is complete.</string>
|
||||
<string name="minute">Minute</string>
|
||||
|
@ -482,6 +484,27 @@
|
|||
<!-- Onboarding Registration Consent -->
|
||||
<string name="registration_consent_headline">Registration consent</string>
|
||||
<string name="registration_consent_second_paragraph">information about my contact with other COVIDSafe users, if another user I have come into contact with tests positive for COVID-19 and uploads their contact data</string>
|
||||
<string name="restrictions_accommodation">Accommodation</string>
|
||||
<string name="restrictions_activity">Activity</string>
|
||||
<string name="restrictions_cafes">Cafes and Restaurants</string>
|
||||
<string name="restrictions_disclaimer">Your selection will only be used to show restrictions in your area. COVIDSafe does not store or use location data.</string>
|
||||
<string name="restrictions_domestic_travel">Domestic Travel</string>
|
||||
<string name="restrictions_education">Education and Childcare</string>
|
||||
<string name="restrictions_entertainment">Entertainment Venues</string>
|
||||
<string name="restrictions_error_dismiss">Dismiss</string>
|
||||
<string name="restrictions_error_heading">Restrictions are not available</string>
|
||||
<string name="restrictions_error_message">Check your internet connection or try again later.</string>
|
||||
<string name="restrictions_error_try">Try again</string>
|
||||
<string name="restrictions_gatherings_work">Gatherings and Work</string>
|
||||
<string name="restrictions_hair_beauty">Hair and Beauty Services</string>
|
||||
<string name="restrictions_heading">Restrictions</string>
|
||||
<string name="restrictions_hotspots">Hotspots and Case Locations</string>
|
||||
<string name="restrictions_retail">Retail and Sales</string>
|
||||
<string name="restrictions_select_activity">Select activity</string>
|
||||
<string name="restrictions_select_state">Select state or territory</string>
|
||||
<string name="restrictions_sports">Sports and Recreation</string>
|
||||
<string name="restrictions_state">State or territory</string>
|
||||
<string name="restrictions_wedding">Wedding, Funeral and Religion</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="scheduled" formatted="false">You scheduled COVIDSafe to snooze from %@ to %@.</string>
|
||||
<string name="search">Search</string>
|
||||
|
@ -511,6 +534,8 @@
|
|||
<string name="snooze_ends">Snooze ends in</string>
|
||||
<string name="snooze_from">Snooze from</string>
|
||||
<string name="snooze_heading">Snooze COVIDSafe</string>
|
||||
<string name="snooze_interference_popup1">The next scheduled snooze starts at %@</string>
|
||||
<string name="snooze_interference_popup2">Set a snooze that ends before this time.</string>
|
||||
<string name="snooze_on">Snooze on %@</string>
|
||||
<string name="snooze_timer_description">Set a timer to snooze COVIDSafe.</string>
|
||||
<string name="snooze_to">Snooze to</string>
|
||||
|
|
|
@ -149,5 +149,4 @@
|
|||
<item name="android:fontFamily">@font/font_roboto_regular</item>
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue