prototype changes for demo
This commit is contained in:
@ -5,11 +5,11 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.dano.test1"
|
namespace = "com.tomhempel.rbarometer"
|
||||||
compileSdk = 35
|
compileSdk = 35
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.dano.test1"
|
applicationId = "com.tomhempel.rbarometer"
|
||||||
minSdk = 29
|
minSdk = 29
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="com.dano.test1">
|
package="com.tomhempel.rbarometer">
|
||||||
|
|
||||||
<!-- Netzwerkberechtigungen -->
|
<!-- Netzwerkberechtigungen -->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
@ -19,7 +19,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Test1"
|
android:theme="@style/Theme.Barometer"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:usesCleartextTraffic="false"
|
android:usesCleartextTraffic="false"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.tomhempel.rbarometer
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -16,27 +16,27 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.ui.AppLanguageStore
|
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||||
import com.dano.test1.ui.NotificationPermissionPrompter
|
import com.tomhempel.rbarometer.ui.NotificationPermissionPrompter
|
||||||
import com.dano.test1.ui.AuthActivity
|
import com.tomhempel.rbarometer.ui.AuthActivity
|
||||||
import com.dano.test1.ui.HandlerOpeningScreen
|
import com.tomhempel.rbarometer.ui.HandlerOpeningScreen
|
||||||
import com.dano.test1.ui.LogoutDialogs
|
import com.tomhempel.rbarometer.ui.LogoutDialogs
|
||||||
import com.dano.test1.ui.SessionLogout
|
import com.tomhempel.rbarometer.ui.SessionLogout
|
||||||
import com.dano.test1.ui.SystemBarInsets
|
import com.tomhempel.rbarometer.ui.SystemBarInsets
|
||||||
import com.dano.test1.utils.SyncProgressOverlay
|
import com.tomhempel.rbarometer.utils.SyncProgressOverlay
|
||||||
import com.dano.test1.utils.SyncProgressTexts
|
import com.tomhempel.rbarometer.utils.SyncProgressTexts
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.dano.test1.data.PendingUploadRepository
|
import com.tomhempel.rbarometer.data.PendingUploadRepository
|
||||||
import com.dano.test1.network.NetworkUtils
|
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||||
import com.dano.test1.network.QuestionnaireApiClient
|
import com.tomhempel.rbarometer.network.QuestionnaireApiClient
|
||||||
import com.dano.test1.network.SyncLog
|
import com.tomhempel.rbarometer.network.SyncLog
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.SyncCoordinator
|
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||||
import com.dano.test1.network.SyncProgress
|
import com.tomhempel.rbarometer.network.SyncProgress
|
||||||
import com.dano.test1.network.SyncResult
|
import com.tomhempel.rbarometer.network.SyncResult
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.questionnaire.QuestionnaireBase
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireBase
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.dano.test1
|
package com.tomhempel.rbarometer
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import com.dano.test1.data.AppDatabase
|
import com.tomhempel.rbarometer.data.AppDatabase
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MyApp (Application)
|
MyApp (Application)
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
|
|
||||||
object AnswerRepository {
|
object AnswerRepository {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory cache of answers for the active client to avoid repeated Room reads
|
* In-memory cache of answers for the active client to avoid repeated Room reads
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
|
|
||||||
object ClientRepository {
|
object ClientRepository {
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
|
|
||||||
object CoachScoringReviewRepository {
|
object CoachScoringReviewRepository {
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
object CompletedQuestionnaireRepository {
|
object CompletedQuestionnaireRepository {
|
||||||
|
|
||||||
private val dao get() = MyApp.database.completedQuestionnaireDao()
|
private val dao get() = MyApp.database.completedQuestionnaireDao()
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
object PendingUploadRepository {
|
object PendingUploadRepository {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.data
|
package com.tomhempel.rbarometer.data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summarises local interview data that must be uploaded (or finished) before logout.
|
* Summarises local interview data that must be uploaded (or finished) before logout.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
data class ApiError(
|
data class ApiError(
|
||||||
val code: String? = null,
|
val code: String? = null,
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
|
|
||||||
/** Persists per-client answer sync timestamps (survives process restarts). */
|
/** Persists per-client answer sync timestamps (survives process restarts). */
|
||||||
internal object ClientAnswerSyncStore {
|
internal object ClientAnswerSyncStore {
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.notification.UploadReminderScheduler
|
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -48,9 +48,9 @@ object DatabaseUploader {
|
|||||||
onResult: (UploadResult) -> Unit,
|
onResult: (UploadResult) -> Unit,
|
||||||
) {
|
) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val allPending = com.dano.test1.data.CompletedQuestionnaireRepository
|
val allPending = com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
.getAllPendingUploads()
|
.getAllPendingUploads()
|
||||||
val pendingScoring = com.dano.test1.data.CoachScoringReviewRepository
|
val pendingScoring = com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||||
.getAllPendingUploads()
|
.getAllPendingUploads()
|
||||||
if (allPending.isEmpty() && pendingScoring.isEmpty()) {
|
if (allPending.isEmpty() && pendingScoring.isEmpty()) {
|
||||||
val assigned = QuestionnaireCache.getAssignedClients(context)
|
val assigned = QuestionnaireCache.getAssignedClients(context)
|
||||||
@ -113,7 +113,7 @@ object DatabaseUploader {
|
|||||||
QuestionnaireApiClient.submitQuestionnaire(token, request)
|
QuestionnaireApiClient.submitQuestionnaire(token, request)
|
||||||
}.onSuccess { response ->
|
}.onSuccess { response ->
|
||||||
submittedQuestionnaires++
|
submittedQuestionnaires++
|
||||||
com.dano.test1.data.CompletedQuestionnaireRepository
|
com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
.markUploaded(clientCode, entry.questionnaireId, System.currentTimeMillis())
|
.markUploaded(clientCode, entry.questionnaireId, System.currentTimeMillis())
|
||||||
if (response.legacySubmit) {
|
if (response.legacySubmit) {
|
||||||
val submitRev = response.structureRevision
|
val submitRev = response.structureRevision
|
||||||
@ -162,7 +162,7 @@ object DatabaseUploader {
|
|||||||
)
|
)
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
submittedScoringReviews++
|
submittedScoringReviews++
|
||||||
com.dano.test1.data.CoachScoringReviewRepository.markUploaded(
|
com.tomhempel.rbarometer.data.CoachScoringReviewRepository.markUploaded(
|
||||||
review.clientCode,
|
review.clientCode,
|
||||||
review.profileID,
|
review.profileID,
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import okhttp3.Dispatcher
|
import okhttp3.Dispatcher
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
@ -1,14 +1,14 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.data.AnswerEntity
|
import com.tomhempel.rbarometer.data.AnswerEntity
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import com.dano.test1.data.Question
|
import com.tomhempel.rbarometer.data.Question
|
||||||
import com.dano.test1.data.Questionnaire
|
import com.tomhempel.rbarometer.data.Questionnaire
|
||||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -367,7 +367,7 @@ object QuestionnaireAnswerSync {
|
|||||||
|
|
||||||
val completedAtMs = (block.completedAt ?: 0L).let { if (it > 0) it * 1000L else System.currentTimeMillis() }
|
val completedAtMs = (block.completedAt ?: 0L).let { if (it > 0) it * 1000L else System.currentTimeMillis() }
|
||||||
val sumPoints = block.sumPoints
|
val sumPoints = block.sumPoints
|
||||||
val clientKey = com.dano.test1.security.SensitiveDataCrypto.clientCodeKey(clientCode)
|
val clientKey = com.tomhempel.rbarometer.security.SensitiveDataCrypto.clientCodeKey(clientCode)
|
||||||
|
|
||||||
return PreparedBlockImport(
|
return PreparedBlockImport(
|
||||||
questionnaireId = questionnaireId,
|
questionnaireId = questionnaireId,
|
||||||
@ -382,7 +382,7 @@ object QuestionnaireAnswerSync {
|
|||||||
AnswerEntity(
|
AnswerEntity(
|
||||||
clientCodeKey = clientKey,
|
clientCodeKey = clientKey,
|
||||||
questionId = AnswerKeyUtils.roomQuestionId(questionnaireId, key),
|
questionId = AnswerKeyUtils.roomQuestionId(questionnaireId, key),
|
||||||
answerValueEnc = com.dano.test1.security.SensitiveDataCrypto.encrypt(value),
|
answerValueEnc = com.tomhempel.rbarometer.security.SensitiveDataCrypto.encrypt(value),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
completion = CompletedQuestionnaire(
|
completion = CompletedQuestionnaire(
|
||||||
@ -461,8 +461,8 @@ object QuestionnaireAnswerSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun CompletedQuestionnaire.toEntity(clientCode: String) =
|
private fun CompletedQuestionnaire.toEntity(clientCode: String) =
|
||||||
com.dano.test1.data.CompletedQuestionnaireEntity(
|
com.tomhempel.rbarometer.data.CompletedQuestionnaireEntity(
|
||||||
clientCodeKey = com.dano.test1.security.SensitiveDataCrypto.clientCodeKey(clientCode),
|
clientCodeKey = com.tomhempel.rbarometer.security.SensitiveDataCrypto.clientCodeKey(clientCode),
|
||||||
questionnaireId = questionnaireId,
|
questionnaireId = questionnaireId,
|
||||||
timestamp = timestamp,
|
timestamp = timestamp,
|
||||||
isDone = isDone,
|
isDone = isDone,
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import com.dano.test1.security.SessionPayloadCrypto
|
import com.tomhempel.rbarometer.security.SessionPayloadCrypto
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
@ -1,11 +1,11 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.data.ClientRepository
|
import com.tomhempel.rbarometer.data.ClientRepository
|
||||||
import com.dano.test1.security.SensitiveDataCrypto
|
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -102,9 +102,9 @@ object QuestionnaireCache {
|
|||||||
*/
|
*/
|
||||||
suspend fun wipeEntireLocalStore(context: Context) {
|
suspend fun wipeEntireLocalStore(context: Context) {
|
||||||
clearAssignedClients(context)
|
clearAssignedClients(context)
|
||||||
com.dano.test1.MyApp.database.clearAllTables()
|
com.tomhempel.rbarometer.MyApp.database.clearAllTables()
|
||||||
cacheDir(context).deleteRecursively()
|
cacheDir(context).deleteRecursively()
|
||||||
com.dano.test1.notification.UploadReminderScheduler.cancel(context)
|
com.tomhempel.rbarometer.notification.UploadReminderScheduler.cancel(context)
|
||||||
LanguageManager.setApiTranslations(emptyMap())
|
LanguageManager.setApiTranslations(emptyMap())
|
||||||
LanguageManager.setQuestionnaireTranslations(emptyMap())
|
LanguageManager.setQuestionnaireTranslations(emptyMap())
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||||
import com.dano.test1.data.Questionnaire
|
import com.tomhempel.rbarometer.data.Questionnaire
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
@ -203,7 +203,7 @@ object QuestionnaireSyncService {
|
|||||||
private suspend fun seedServerCompletions(clientInfosFromApi: List<AssignedClientInfo>) {
|
private suspend fun seedServerCompletions(clientInfosFromApi: List<AssignedClientInfo>) {
|
||||||
val toInsert = mutableListOf<CompletedQuestionnaire>()
|
val toInsert = mutableListOf<CompletedQuestionnaire>()
|
||||||
for (clientInfo in clientInfosFromApi) {
|
for (clientInfo in clientInfosFromApi) {
|
||||||
val existingByQn = com.dano.test1.data.CompletedQuestionnaireRepository
|
val existingByQn = com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
.getAllForClient(clientInfo.clientCode)
|
.getAllForClient(clientInfo.clientCode)
|
||||||
.associateBy { it.questionnaireId }
|
.associateBy { it.questionnaireId }
|
||||||
for (serverCompletion in clientInfo.completedQuestionnaires) {
|
for (serverCompletion in clientInfo.completedQuestionnaires) {
|
||||||
@ -225,7 +225,7 @@ object QuestionnaireSyncService {
|
|||||||
}
|
}
|
||||||
if (toInsert.isNotEmpty()) {
|
if (toInsert.isNotEmpty()) {
|
||||||
runCatching {
|
runCatching {
|
||||||
com.dano.test1.data.CompletedQuestionnaireRepository.insertAll(toInsert)
|
com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository.insertAll(toInsert)
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
SyncLog.d(TAG, "seeded ${toInsert.size} server completion(s)")
|
SyncLog.d(TAG, "seeded ${toInsert.size} server completion(s)")
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
sealed class SyncResult {
|
sealed class SyncResult {
|
||||||
data object Success : SyncResult()
|
data object Success : SyncResult()
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.dano.test1.BuildConfig
|
import com.tomhempel.rbarometer.BuildConfig
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
/** Debug-gated logging for sync/API paths (avoids logging full JSON bodies in production). */
|
/** Debug-gated logging for sync/API paths (avoids logging full JSON bodies in production). */
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
/** User-facing sync step — no counts; shown as friendly status text only. */
|
/** User-facing sync step — no counts; shown as friendly status text only. */
|
||||||
enum class SyncPhase {
|
enum class SyncPhase {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.network
|
package com.tomhempel.rbarometer.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.notification
|
package com.tomhempel.rbarometer.notification
|
||||||
|
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
@ -8,9 +8,9 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.notification
|
package com.tomhempel.rbarometer.notification
|
||||||
|
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
@ -51,7 +51,7 @@ object UploadReminderScheduler {
|
|||||||
*/
|
*/
|
||||||
suspend fun hasPendingUploads(): Boolean {
|
suspend fun hasPendingUploads(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
com.dano.test1.data.PendingUploadRepository.hasAny()
|
com.tomhempel.rbarometer.data.PendingUploadRepository.hasAny()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "hasPendingUploads check failed: ${e.message}")
|
Log.w(TAG, "hasPendingUploads check failed: ${e.message}")
|
||||||
false
|
false
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stable keys for Room answer rows and submit mapping.
|
* Stable keys for Room answer rows and submit mapping.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves stored answers from the in-memory map using the same keys as persistence/sync.
|
* Resolves stored answers from the in-memory map using the same keys as persistence/sync.
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Single source for coach language selection across opening screen and questionnaires.
|
* Single source for coach language selection across opening screen and questionnaires.
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
|
|
||||||
object ClientAssignmentGuard {
|
object ClientAssignmentGuard {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
object QuestionFlowResolver {
|
object QuestionFlowResolver {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
||||||
interface QuestionHandler {
|
interface QuestionHandler {
|
||||||
@ -1,16 +1,16 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerClientCoachCode
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerClientCoachCode
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerDateSpinner
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerDateSpinner
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerFreeText
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerFreeText
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerGlassScaleQuestion
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerGlassScaleQuestion
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerLastPage
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerLastPage
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerMultiCheckboxQuestion
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerMultiCheckboxQuestion
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerRadioQuestion
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerRadioQuestion
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerSliderQuestion
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerSliderQuestion
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerStringSpinner
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerStringSpinner
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerValueSpinner
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerValueSpinner
|
||||||
|
|
||||||
enum class NavigationMode { Step, Embedded }
|
enum class NavigationMode { Step, Embedded }
|
||||||
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
/** Renders optional noteBeforeKey / noteAfterKey above and below the main question text. */
|
/** Renders optional noteBeforeKey / noteAfterKey above and below the main question text. */
|
||||||
object QuestionNotesHelper {
|
object QuestionNotesHelper {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
@ -9,19 +9,19 @@ import android.view.ViewGroup
|
|||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerStringSpinner
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerStringSpinner
|
||||||
import com.dano.test1.questionnaire.handlers.HandlerValueSpinner
|
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerValueSpinner
|
||||||
import com.dano.test1.ui.AppLanguageStore
|
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||||
import com.dano.test1.ui.ReviewScoresHandler
|
import com.tomhempel.rbarometer.ui.ReviewScoresHandler
|
||||||
import com.dano.test1.utils.DateAnswerFormat
|
import com.tomhempel.rbarometer.utils.DateAnswerFormat
|
||||||
import com.dano.test1.utils.DatePrecision
|
import com.tomhempel.rbarometer.utils.DatePrecision
|
||||||
import com.dano.test1.utils.ScreenLoading
|
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||||
import com.dano.test1.utils.TextInputSanitizer
|
import com.tomhempel.rbarometer.utils.TextInputSanitizer
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@ -296,7 +296,7 @@ class QuestionnaireAllInOne(private val questionnaireFileName: String) : Questio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
languageID = newLang
|
languageID = newLang
|
||||||
com.dano.test1.ui.AppLanguageStore.set(context, newLang)
|
com.tomhempel.rbarometer.ui.AppLanguageStore.set(context, newLang)
|
||||||
persistedBaselineAnswers = snapshotAnswerKeys(answers)
|
persistedBaselineAnswers = snapshotAnswerKeys(answers)
|
||||||
uiChangedSinceBaseline = false
|
uiChangedSinceBaseline = false
|
||||||
buildAllInOneUi()
|
buildAllInOneUi()
|
||||||
@ -927,7 +927,7 @@ class QuestionnaireAllInOne(private val questionnaireFileName: String) : Questio
|
|||||||
|
|
||||||
private fun selectedMonthNumber(view: View): Int? {
|
private fun selectedMonthNumber(view: View): Int? {
|
||||||
val month = view.findViewById<Spinner>(R.id.spinner_value_month)?.selectedItem
|
val month = view.findViewById<Spinner>(R.id.spinner_value_month)?.selectedItem
|
||||||
val months = com.dano.test1.ui.Months.getAllMonths(languageID)
|
val months = com.tomhempel.rbarometer.ui.Months.getAllMonths(languageID)
|
||||||
val idx = months.indexOf(month)
|
val idx = months.indexOf(month)
|
||||||
return if (idx >= 0) idx + 1 else null
|
return if (idx >= 0) idx + 1 else null
|
||||||
}
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.R
|
import android.R
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@ -77,7 +77,7 @@ abstract class QuestionnaireBase<T> {
|
|||||||
|
|
||||||
protected fun showEmptyScreen() {
|
protected fun showEmptyScreen() {
|
||||||
navigateTo(getLayoutResId("empty")) {
|
navigateTo(getLayoutResId("empty")) {
|
||||||
setupPrevButton(com.dano.test1.R.id.Qprev) { goToPreviousQuestion() }
|
setupPrevButton(com.tomhempel.rbarometer.R.id.Qprev) { goToPreviousQuestion() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -6,8 +6,8 @@ import android.widget.AdapterView
|
|||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() {
|
open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() {
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ open class QuestionnaireGeneric(private val questionnaireFileName: String) : Que
|
|||||||
val newLang = AppLanguages.ids[position]
|
val newLang = AppLanguages.ids[position]
|
||||||
if (newLang == languageID) return
|
if (newLang == languageID) return
|
||||||
languageID = newLang
|
languageID = newLang
|
||||||
com.dano.test1.ui.AppLanguageStore.set(context, newLang)
|
com.tomhempel.rbarometer.ui.AppLanguageStore.set(context, newLang)
|
||||||
spinner.post { showCurrentQuestion() }
|
spinner.post { showCurrentQuestion() }
|
||||||
}
|
}
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
data class Option(
|
data class Option(
|
||||||
val key: String, // Must always be set
|
val key: String, // Must always be set
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -1,18 +1,18 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.data.Answer
|
import com.tomhempel.rbarometer.data.Answer
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.data.ClientAnswersCache
|
import com.tomhempel.rbarometer.data.ClientAnswersCache
|
||||||
import com.dano.test1.data.ClientRepository
|
import com.tomhempel.rbarometer.data.ClientRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||||
import com.dano.test1.data.Question
|
import com.tomhempel.rbarometer.data.Question
|
||||||
import com.dano.test1.data.Questionnaire
|
import com.tomhempel.rbarometer.data.Questionnaire
|
||||||
import com.dano.test1.network.SyncLog
|
import com.tomhempel.rbarometer.network.SyncLog
|
||||||
import com.dano.test1.notification.UploadReminderScheduler
|
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||||
|
|
||||||
object QuestionnairePersistence {
|
object QuestionnairePersistence {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
object QuestionnaireProgressiveCallbacks {
|
object QuestionnaireProgressiveCallbacks {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
|
|
||||||
/** Applies per-questionnaire translation tables from synced JSON cache. */
|
/** Applies per-questionnaire translation tables from synced JSON cache. */
|
||||||
object QuestionnaireTranslationsLoader {
|
object QuestionnaireTranslationsLoader {
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates questionnaire JSON before the coach opens a flow.
|
* Validates questionnaire JSON before the coach opens a flow.
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.data.ClientAnswersCache
|
import com.tomhempel.rbarometer.data.ClientAnswersCache
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads prior answers from Room (or session cache) into the in-memory map before UI bind,
|
* Loads prior answers from Room (or session cache) into the in-memory map before UI bind,
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
object SpinnerAnswerRules {
|
object SpinnerAnswerRules {
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.questionnaire
|
package com.tomhempel.rbarometer.questionnaire
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.ui.localization.UiStrings
|
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves stored answer values to spinner indices (keys, localized labels, or free text).
|
* Resolves stored answer values to spinner indices (keys, localized labels, or free text).
|
||||||
@ -1,17 +1,17 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.ClientRepository
|
import com.tomhempel.rbarometer.data.ClientRepository
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -1,24 +1,24 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.questionnaire.MAX_VALUE_YEAR
|
import com.tomhempel.rbarometer.questionnaire.MAX_VALUE_YEAR
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||||
import com.dano.test1.ui.Month
|
import com.tomhempel.rbarometer.ui.Month
|
||||||
import com.dano.test1.ui.Months
|
import com.tomhempel.rbarometer.ui.Months
|
||||||
import com.dano.test1.utils.DateAnswerFormat
|
import com.tomhempel.rbarometer.utils.DateAnswerFormat
|
||||||
import com.dano.test1.utils.DatePrecision
|
import com.tomhempel.rbarometer.utils.DatePrecision
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.InputFilter
|
import android.text.InputFilter
|
||||||
@ -6,16 +6,16 @@ import android.view.View
|
|||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||||
import com.dano.test1.utils.TextInputSanitizer
|
import com.tomhempel.rbarometer.utils.TextInputSanitizer
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -1,17 +1,17 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -6,16 +6,16 @@ import android.widget.*
|
|||||||
import android.text.Html
|
import android.text.Html
|
||||||
import androidx.core.widget.TextViewCompat
|
import androidx.core.widget.TextViewCompat
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.ui.AppLanguageStore
|
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||||
import com.dano.test1.ui.ReviewScoresHandler
|
import com.tomhempel.rbarometer.ui.ReviewScoresHandler
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
@ -6,14 +6,14 @@ import android.view.View
|
|||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.core.widget.TextViewCompat
|
import androidx.core.widget.TextViewCompat
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -1,18 +1,18 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -1,17 +1,17 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
class HandlerSliderQuestion(
|
class HandlerSliderQuestion(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@ -1,20 +1,20 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.questionnaire.AnswerLookup
|
import com.tomhempel.rbarometer.questionnaire.AnswerLookup
|
||||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.SpinnerAnswerRules
|
import com.tomhempel.rbarometer.questionnaire.SpinnerAnswerRules
|
||||||
import com.dano.test1.questionnaire.SpinnerSelectionHelper
|
import com.tomhempel.rbarometer.questionnaire.SpinnerSelectionHelper
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
class HandlerStringSpinner(
|
class HandlerStringSpinner(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@ -1,20 +1,20 @@
|
|||||||
package com.dano.test1.questionnaire.handlers
|
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.questionnaire.AnswerLookup
|
import com.tomhempel.rbarometer.questionnaire.AnswerLookup
|
||||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||||
import com.dano.test1.questionnaire.SpinnerAnswerRules
|
import com.tomhempel.rbarometer.questionnaire.SpinnerAnswerRules
|
||||||
import com.dano.test1.questionnaire.SpinnerSelectionHelper
|
import com.tomhempel.rbarometer.questionnaire.SpinnerSelectionHelper
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.questionnaire.QuestionHandler
|
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
class HandlerValueSpinner(
|
class HandlerValueSpinner(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@ -1,13 +1,13 @@
|
|||||||
package com.dano.test1.scoring
|
package com.tomhempel.rbarometer.scoring
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import com.dano.test1.network.ClientScoringReview
|
import com.tomhempel.rbarometer.network.ClientScoringReview
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.ScoringProfileDefinition
|
import com.tomhempel.rbarometer.network.ScoringProfileDefinition
|
||||||
import com.dano.test1.network.ScoringReviewProfile
|
import com.tomhempel.rbarometer.network.ScoringReviewProfile
|
||||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
|
|
||||||
object LocalScoringReviewBuilder {
|
object LocalScoringReviewBuilder {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.scoring
|
package com.tomhempel.rbarometer.scoring
|
||||||
|
|
||||||
import com.dano.test1.network.ScoringProfileDefinition
|
import com.tomhempel.rbarometer.network.ScoringProfileDefinition
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.scoring
|
package com.tomhempel.rbarometer.scoring
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.security
|
package com.tomhempel.rbarometer.security
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.security.keystore.KeyGenParameterSpec
|
import android.security.keystore.KeyGenParameterSpec
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.security
|
package com.tomhempel.rbarometer.security
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.questionnaire.AppLanguages
|
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists the coach's chosen UI language across app restarts and screens.
|
* Persists the coach's chosen UI language across app restarts and screens.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -9,17 +9,17 @@ import android.widget.TextView
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.LoginManager
|
import com.tomhempel.rbarometer.network.LoginManager
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.SyncCoordinator
|
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.questionnaire.AppLanguages
|
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
import com.dano.test1.utils.ScreenLoading
|
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
@ -10,8 +10,8 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.security.crypto.EncryptedSharedPreferences
|
import androidx.security.crypto.EncryptedSharedPreferences
|
||||||
@ -0,0 +1,404 @@
|
|||||||
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.content.res.ColorStateList
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.PopupMenu
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.card.MaterialCardView
|
||||||
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
|
import com.tomhempel.rbarometer.R
|
||||||
|
|
||||||
|
class DashboardHandler(
|
||||||
|
private val activity: MainActivity,
|
||||||
|
private val onClose: () -> Unit,
|
||||||
|
) {
|
||||||
|
private data class DashboardClient(
|
||||||
|
val code: String,
|
||||||
|
val status: String,
|
||||||
|
val cycle: Int,
|
||||||
|
val session: Int,
|
||||||
|
val totalSessions: Int,
|
||||||
|
val lastSession: String,
|
||||||
|
val nextSession: String,
|
||||||
|
val pendingMeasures: Int,
|
||||||
|
val syncStatus: String,
|
||||||
|
val trend: String,
|
||||||
|
val participation: String,
|
||||||
|
val cadence: String,
|
||||||
|
val ownerNote: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
private val clients = listOf(
|
||||||
|
DashboardClient(
|
||||||
|
code = "A102",
|
||||||
|
status = "Due today",
|
||||||
|
cycle = 3,
|
||||||
|
session = 2,
|
||||||
|
totalSessions = 6,
|
||||||
|
lastSession = "Jun 17",
|
||||||
|
nextSession = "Today",
|
||||||
|
pendingMeasures = 2,
|
||||||
|
syncStatus = "Sync OK",
|
||||||
|
trend = "Stable",
|
||||||
|
participation = "Active",
|
||||||
|
cadence = "Weekly",
|
||||||
|
ownerNote = "Continue current cycle",
|
||||||
|
),
|
||||||
|
DashboardClient(
|
||||||
|
code = "B447",
|
||||||
|
status = "Overdue",
|
||||||
|
cycle = 1,
|
||||||
|
session = 5,
|
||||||
|
totalSessions = 6,
|
||||||
|
lastSession = "Jun 10",
|
||||||
|
nextSession = "Jun 18",
|
||||||
|
pendingMeasures = 4,
|
||||||
|
syncStatus = "3 pending sync",
|
||||||
|
trend = "Needs review",
|
||||||
|
participation = "Active",
|
||||||
|
cadence = "Weekly",
|
||||||
|
ownerNote = "Needs scheduling contact",
|
||||||
|
),
|
||||||
|
DashboardClient(
|
||||||
|
code = "C083",
|
||||||
|
status = "Upcoming",
|
||||||
|
cycle = 2,
|
||||||
|
session = 1,
|
||||||
|
totalSessions = 6,
|
||||||
|
lastSession = "Jun 21",
|
||||||
|
nextSession = "Jun 28",
|
||||||
|
pendingMeasures = 0,
|
||||||
|
syncStatus = "Sync OK",
|
||||||
|
trend = "Improving",
|
||||||
|
participation = "Active",
|
||||||
|
cadence = "Every 2 weeks",
|
||||||
|
ownerNote = "Ready for next cycle",
|
||||||
|
),
|
||||||
|
DashboardClient(
|
||||||
|
code = "D219",
|
||||||
|
status = "Paused",
|
||||||
|
cycle = 4,
|
||||||
|
session = 6,
|
||||||
|
totalSessions = 6,
|
||||||
|
lastSession = "Jun 03",
|
||||||
|
nextSession = "Not planned",
|
||||||
|
pendingMeasures = 1,
|
||||||
|
syncStatus = "1 pending sync",
|
||||||
|
trend = "Participation paused",
|
||||||
|
participation = "Inactive",
|
||||||
|
cadence = "On hold",
|
||||||
|
ownerNote = "Confirm continuation",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun show() {
|
||||||
|
activity.setContentView(R.layout.dashboard_screen)
|
||||||
|
activity.setBackPressInterceptor {
|
||||||
|
close()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
bind()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bind() {
|
||||||
|
activity.findViewById<MaterialButton>(R.id.dashboardBackButton).setOnClickListener {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
activity.findViewById<TextView>(R.id.dashboardSubtitle).text =
|
||||||
|
"Prototype view for repeated limited-session cycles"
|
||||||
|
activity.findViewById<TextView>(R.id.dashboardDueValue).text =
|
||||||
|
clients.count { it.status == "Due today" || it.status == "Overdue" }.toString()
|
||||||
|
activity.findViewById<TextView>(R.id.dashboardActiveValue).text =
|
||||||
|
clients.count { it.status != "Paused" }.toString()
|
||||||
|
activity.findViewById<TextView>(R.id.dashboardSyncValue).text =
|
||||||
|
clients.count { it.syncStatus.contains("pending") }.toString()
|
||||||
|
|
||||||
|
activity.findViewById<EditText>(R.id.dashboardSearchInput).addTextChangedListener(
|
||||||
|
object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
|
renderClients(s?.toString().orEmpty())
|
||||||
|
}
|
||||||
|
override fun afterTextChanged(s: Editable?) = Unit
|
||||||
|
},
|
||||||
|
)
|
||||||
|
renderClients("")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderClients(query: String) {
|
||||||
|
val list = activity.findViewById<LinearLayout>(R.id.dashboardClientList)
|
||||||
|
list.removeAllViews()
|
||||||
|
val normalized = query.trim()
|
||||||
|
val visibleClients = if (normalized.isBlank()) {
|
||||||
|
clients
|
||||||
|
} else {
|
||||||
|
clients.filter { client ->
|
||||||
|
client.code.contains(normalized, ignoreCase = true) ||
|
||||||
|
client.status.contains(normalized, ignoreCase = true) ||
|
||||||
|
client.participation.contains(normalized, ignoreCase = true) ||
|
||||||
|
client.trend.contains(normalized, ignoreCase = true) ||
|
||||||
|
client.nextSession.contains(normalized, ignoreCase = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visibleClients.forEach { client ->
|
||||||
|
list.addView(createClientCard(client))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createClientCard(client: DashboardClient): View {
|
||||||
|
val card = MaterialCardView(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
).also { it.setMargins(0, dp(10), 0, 0) }
|
||||||
|
radius = dp(10).toFloat()
|
||||||
|
strokeWidth = dp(1)
|
||||||
|
setStrokeColor(ContextCompat.getColor(activity, R.color.brand_header_stroke))
|
||||||
|
setCardBackgroundColor(ContextCompat.getColor(activity, R.color.brand_header_surface))
|
||||||
|
cardElevation = dp(1).toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
val content = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
setPadding(dp(16), dp(14), dp(16), dp(16))
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
}
|
||||||
|
val titleBlock = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
}
|
||||||
|
val title = TextView(activity).apply {
|
||||||
|
text = client.code
|
||||||
|
textSize = 20f
|
||||||
|
setTypeface(typeface, Typeface.BOLD)
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
|
||||||
|
}
|
||||||
|
val subtitle = TextView(activity).apply {
|
||||||
|
text = "Cycle ${client.cycle} - Session ${client.session} of ${client.totalSessions} - ${client.cadence}"
|
||||||
|
textSize = 13f
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_muted))
|
||||||
|
}
|
||||||
|
titleBlock.addView(title)
|
||||||
|
titleBlock.addView(subtitle)
|
||||||
|
header.addView(titleBlock)
|
||||||
|
header.addView(statusChip(client.status))
|
||||||
|
|
||||||
|
val scheduleRow = metricRow(
|
||||||
|
leftTitle = "Last session",
|
||||||
|
leftValue = client.lastSession,
|
||||||
|
rightTitle = "Next planned",
|
||||||
|
rightValue = client.nextSession,
|
||||||
|
rightAction = "Edit",
|
||||||
|
)
|
||||||
|
|
||||||
|
val workRow = metricRow(
|
||||||
|
leftTitle = "Open measures",
|
||||||
|
leftValue = client.pendingMeasures.toString(),
|
||||||
|
rightTitle = "Data state",
|
||||||
|
rightValue = client.syncStatus,
|
||||||
|
rightAction = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
val trend = TextView(activity).apply {
|
||||||
|
text = "Trend: ${client.trend} - Participation: ${client.participation}\n${client.ownerNote}"
|
||||||
|
textSize = 14f
|
||||||
|
setLineSpacing(dp(2).toFloat(), 1f)
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
|
||||||
|
setPadding(0, dp(12), 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
val actionRow = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
setPadding(0, dp(14), 0, 0)
|
||||||
|
}
|
||||||
|
actionRow.addView(primaryAction("Select client", weight = 1.25f))
|
||||||
|
actionRow.addView(statusDropdown(client.participation, weight = 1.15f))
|
||||||
|
actionRow.addView(destructiveAction("Remove", weight = 0.8f))
|
||||||
|
|
||||||
|
content.addView(header)
|
||||||
|
content.addView(scheduleRow)
|
||||||
|
content.addView(workRow)
|
||||||
|
content.addView(trend)
|
||||||
|
content.addView(actionRow)
|
||||||
|
card.addView(content)
|
||||||
|
return card
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun metricRow(
|
||||||
|
leftTitle: String,
|
||||||
|
leftValue: String,
|
||||||
|
rightTitle: String,
|
||||||
|
rightValue: String,
|
||||||
|
rightAction: String?,
|
||||||
|
): View {
|
||||||
|
val row = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
isBaselineAligned = false
|
||||||
|
setPadding(0, dp(12), 0, 0)
|
||||||
|
}
|
||||||
|
row.addView(metricBlock(leftTitle, leftValue, weight = 1f))
|
||||||
|
row.addView(metricBlock(rightTitle, rightValue, weight = 1f, action = rightAction))
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun metricBlock(
|
||||||
|
title: String,
|
||||||
|
value: String,
|
||||||
|
weight: Float,
|
||||||
|
action: String? = null,
|
||||||
|
): View {
|
||||||
|
val block = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, weight)
|
||||||
|
.also { it.setMargins(0, 0, dp(8), 0) }
|
||||||
|
background = ContextCompat.getDrawable(activity, R.drawable.bg_session_metric)
|
||||||
|
setPadding(dp(12), dp(10), dp(12), dp(10))
|
||||||
|
}
|
||||||
|
val titleView = TextView(activity).apply {
|
||||||
|
text = title
|
||||||
|
textSize = 11f
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_muted))
|
||||||
|
}
|
||||||
|
val valueRow = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
setPadding(0, dp(3), 0, 0)
|
||||||
|
}
|
||||||
|
val valueView = TextView(activity).apply {
|
||||||
|
text = value
|
||||||
|
textSize = 16f
|
||||||
|
setTypeface(typeface, Typeface.BOLD)
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
}
|
||||||
|
valueRow.addView(valueView)
|
||||||
|
if (action != null) {
|
||||||
|
valueRow.addView(smallAction(action))
|
||||||
|
}
|
||||||
|
block.addView(titleView)
|
||||||
|
block.addView(valueRow)
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun statusChip(status: String): TextView {
|
||||||
|
val bg = when (status) {
|
||||||
|
"Overdue" -> R.drawable.bg_chip_amber
|
||||||
|
"Paused" -> R.drawable.bg_chip_locked
|
||||||
|
else -> R.drawable.bg_chip_green
|
||||||
|
}
|
||||||
|
return TextView(activity).apply {
|
||||||
|
text = status
|
||||||
|
textSize = 12f
|
||||||
|
setTypeface(typeface, Typeface.BOLD)
|
||||||
|
setTextColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
activity,
|
||||||
|
if (status == "Paused") R.color.brand_chip_locked_text else R.color.brand_text_on_dark,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
setBackgroundResource(bg)
|
||||||
|
setPadding(dp(10), dp(6), dp(10), dp(6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun primaryAction(label: String, weight: Float): MaterialButton =
|
||||||
|
dashboardButton(label, weight).apply {
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_on_dark))
|
||||||
|
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
|
||||||
|
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lifecycleAction(label: String, weight: Float): MaterialButton =
|
||||||
|
dashboardButton(label, weight).apply {
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_text_dark))
|
||||||
|
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_surface))
|
||||||
|
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_stroke))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun statusDropdown(status: String, weight: Float): MaterialButton =
|
||||||
|
lifecycleAction("Status: $status", weight).apply {
|
||||||
|
setOnClickListener { anchor ->
|
||||||
|
PopupMenu(activity, anchor).apply {
|
||||||
|
menu.add("Active")
|
||||||
|
menu.add("Inactive")
|
||||||
|
menu.add("Archived")
|
||||||
|
setOnMenuItemClickListener { item ->
|
||||||
|
Toast.makeText(
|
||||||
|
activity,
|
||||||
|
"Set status to ${item.title} is prototype-only",
|
||||||
|
Toast.LENGTH_SHORT,
|
||||||
|
).show()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun destructiveAction(label: String, weight: Float): MaterialButton =
|
||||||
|
dashboardButton(label, weight).apply {
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_destructive_text))
|
||||||
|
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_destructive_fill))
|
||||||
|
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_destructive_fill))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dashboardButton(label: String, weight: Float): MaterialButton =
|
||||||
|
MaterialButton(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, dp(42), weight).also {
|
||||||
|
it.setMargins(0, 0, dp(6), 0)
|
||||||
|
}
|
||||||
|
text = label
|
||||||
|
textSize = 11f
|
||||||
|
isAllCaps = false
|
||||||
|
cornerRadius = dp(18)
|
||||||
|
strokeWidth = dp(1)
|
||||||
|
insetTop = 0
|
||||||
|
insetBottom = 0
|
||||||
|
setPadding(dp(6), 0, dp(6), 0)
|
||||||
|
setOnClickListener {
|
||||||
|
Toast.makeText(activity, "$label is prototype-only", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun smallAction(label: String): MaterialButton =
|
||||||
|
MaterialButton(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, dp(32))
|
||||||
|
text = label
|
||||||
|
textSize = 11f
|
||||||
|
isAllCaps = false
|
||||||
|
cornerRadius = dp(16)
|
||||||
|
strokeWidth = dp(1)
|
||||||
|
insetTop = 0
|
||||||
|
insetBottom = 0
|
||||||
|
minWidth = dp(52)
|
||||||
|
minimumWidth = dp(52)
|
||||||
|
setPadding(dp(8), 0, dp(8), 0)
|
||||||
|
setTextColor(ContextCompat.getColor(activity, R.color.brand_purple))
|
||||||
|
backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_header_surface))
|
||||||
|
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(activity, R.color.brand_purple))
|
||||||
|
setOnClickListener {
|
||||||
|
Toast.makeText(activity, "$label next session is prototype-only", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun close() {
|
||||||
|
activity.setBackPressInterceptor(null)
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dp(value: Int): Int =
|
||||||
|
(value * activity.resources.displayMetrics.density).toInt()
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
|
|
||||||
object DevSettingsAccess {
|
object DevSettingsAccess {
|
||||||
const val CLIENT_CODE = "DEVELOPER-SETTINGS"
|
const val CLIENT_CODE = "DEVELOPER-SETTINGS"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -12,16 +12,16 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.SwitchCompat
|
import androidx.appcompat.widget.SwitchCompat
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.QuestionnaireSyncService
|
import com.tomhempel.rbarometer.network.QuestionnaireSyncService
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.utils.SyncProgressOverlay
|
import com.tomhempel.rbarometer.utils.SyncProgressOverlay
|
||||||
import com.dano.test1.utils.SyncProgressTexts
|
import com.tomhempel.rbarometer.utils.SyncProgressTexts
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.dano.test1.ui.AppLanguageStore
|
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||||
import com.dano.test1.ui.LogoutDialogs
|
import com.tomhempel.rbarometer.ui.LogoutDialogs
|
||||||
import com.dano.test1.ui.SessionLogout
|
import com.tomhempel.rbarometer.ui.SessionLogout
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
@ -12,36 +12,36 @@ import androidx.appcompat.widget.AppCompatImageButton
|
|||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.data.PendingUploadRepository
|
import com.tomhempel.rbarometer.data.PendingUploadRepository
|
||||||
import com.dano.test1.data.UnuploadedWorkRepository
|
import com.tomhempel.rbarometer.data.UnuploadedWorkRepository
|
||||||
import com.dano.test1.network.NetworkUtils
|
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||||
import com.dano.test1.network.QuestionnaireAnswerSync
|
import com.tomhempel.rbarometer.network.QuestionnaireAnswerSync
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.SyncCoordinator
|
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||||
import com.dano.test1.network.SyncResult
|
import com.tomhempel.rbarometer.network.SyncResult
|
||||||
import com.dano.test1.questionnaire.AppLanguages
|
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import com.dano.test1.questionnaire.ConditionJsonParser
|
import com.tomhempel.rbarometer.questionnaire.ConditionJsonParser
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
import com.dano.test1.questionnaire.QuestionnaireBase
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireBase
|
||||||
import com.dano.test1.questionnaire.QuestionnaireAllInOne
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireAllInOne
|
||||||
import com.dano.test1.questionnaire.QuestionnaireGeneric
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireGeneric
|
||||||
import com.dano.test1.questionnaire.QuestionnaireValidation
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireValidation
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import com.dano.test1.utils.ScreenLoading
|
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
|
|
||||||
|
|
||||||
class HandlerOpeningScreen(private val activity: MainActivity) {
|
class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||||
@ -60,6 +60,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
private lateinit var spinner: Spinner
|
private lateinit var spinner: Spinner
|
||||||
private lateinit var textView: TextView
|
private lateinit var textView: TextView
|
||||||
private lateinit var noClientsAssignedText: TextView
|
private lateinit var noClientsAssignedText: TextView
|
||||||
|
private lateinit var sessionMetricClientsValue: TextView
|
||||||
|
private lateinit var sessionMetricMeasuresValue: TextView
|
||||||
|
private lateinit var sessionMetricSyncValue: TextView
|
||||||
private lateinit var nextStepBannerCard: View
|
private lateinit var nextStepBannerCard: View
|
||||||
private lateinit var nextStepEyebrow: TextView
|
private lateinit var nextStepEyebrow: TextView
|
||||||
private lateinit var nextStepTitle: TextView
|
private lateinit var nextStepTitle: TextView
|
||||||
@ -213,6 +216,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
spinner = activity.findViewById(R.id.string_spinner1)
|
spinner = activity.findViewById(R.id.string_spinner1)
|
||||||
textView = activity.findViewById(R.id.textView)
|
textView = activity.findViewById(R.id.textView)
|
||||||
noClientsAssignedText = activity.findViewById(R.id.noClientsAssignedText)
|
noClientsAssignedText = activity.findViewById(R.id.noClientsAssignedText)
|
||||||
|
sessionMetricClientsValue = activity.findViewById(R.id.sessionMetricClientsValue)
|
||||||
|
sessionMetricMeasuresValue = activity.findViewById(R.id.sessionMetricMeasuresValue)
|
||||||
|
sessionMetricSyncValue = activity.findViewById(R.id.sessionMetricSyncValue)
|
||||||
nextStepBannerCard = activity.findViewById(R.id.nextStepBannerCard)
|
nextStepBannerCard = activity.findViewById(R.id.nextStepBannerCard)
|
||||||
nextStepEyebrow = activity.findViewById(R.id.nextStepEyebrow)
|
nextStepEyebrow = activity.findViewById(R.id.nextStepEyebrow)
|
||||||
nextStepTitle = activity.findViewById(R.id.nextStepTitle)
|
nextStepTitle = activity.findViewById(R.id.nextStepTitle)
|
||||||
@ -233,23 +239,40 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
refreshProgress = activity.findViewById(R.id.refreshProgress)
|
refreshProgress = activity.findViewById(R.id.refreshProgress)
|
||||||
refreshButton.contentDescription = t("refresh")
|
refreshButton.contentDescription = t("refresh")
|
||||||
settingsButton.contentDescription = tOr("settings", hubFallback("Einstellungen", "Settings"))
|
settingsButton.contentDescription = tOr("settings", hubFallback("Einstellungen", "Settings"))
|
||||||
textView.text = t("questionnaire_title")
|
textView.text = hubFallback("Sitzungsinstrumente", "Session measures")
|
||||||
applyHubLabels()
|
applyHubLabels()
|
||||||
|
updateSessionMetrics()
|
||||||
applyCoachDisplay()
|
applyCoachDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun applyHubLabels() {
|
private fun applyHubLabels() {
|
||||||
if (!::labelLanguage.isInitialized) return
|
if (!::labelLanguage.isInitialized) return
|
||||||
headerWelcome.text = tOr("hub_welcome_back", hubFallback("Willkommen zurück", "Welcome back"))
|
headerWelcome.text = "Barometer"
|
||||||
labelLanguage.text = tOr("language", hubFallback("Sprache", "Language"))
|
labelLanguage.text = tOr("language", hubFallback("Sprache", "Language"))
|
||||||
labelClientCode.text = tOr("client_code", hubFallback("Klientencode", "Client code"))
|
labelClientCode.text = hubFallback("Aktiver Klient", "Active client")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun applyCoachDisplay() {
|
private fun applyCoachDisplay() {
|
||||||
if (!::coachNameDisplay.isInitialized) return
|
if (!::coachNameDisplay.isInitialized) return
|
||||||
val username = TokenStore.getUsername(activity)?.trim().orEmpty()
|
val username = TokenStore.getUsername(activity)?.trim().orEmpty()
|
||||||
coachNameDisplay.text = username.ifBlank {
|
coachNameDisplay.text = if (username.isBlank()) {
|
||||||
tOr("coach_code", hubFallback("Coach", "Coach"))
|
hubFallback("Sitzungskonsole", "Session console")
|
||||||
|
} else {
|
||||||
|
hubFallback("Beraterkonsole: $username", "Counselor console: $username")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateSessionMetrics() {
|
||||||
|
if (!::sessionMetricClientsValue.isInitialized) return
|
||||||
|
sessionMetricClientsValue.text = assignedClientsForUi().size.toString()
|
||||||
|
sessionMetricMeasuresValue.text = questionnaireEntries.size.toString()
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
val count = withContext(Dispatchers.IO) {
|
||||||
|
PendingUploadRepository.countAll()
|
||||||
|
}
|
||||||
|
if (::sessionMetricSyncValue.isInitialized) {
|
||||||
|
sessionMetricSyncValue.text = if (count > 0) count.toString() else "OK"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +552,38 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
setTypeface(typeface, android.graphics.Typeface.BOLD)
|
setTypeface(typeface, android.graphics.Typeface.BOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val dashboardButton = MaterialButton(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
).also {
|
||||||
|
it.bottomMargin = dp(10)
|
||||||
|
}
|
||||||
|
text = hubFallback("Dashboard", "Dashboard")
|
||||||
|
isAllCaps = false
|
||||||
|
icon = ContextCompat.getDrawable(activity, R.drawable.ic_person_24)
|
||||||
|
iconGravity = MaterialButton.ICON_GRAVITY_TEXT_START
|
||||||
|
iconPadding = dp(10)
|
||||||
|
iconTint = ColorStateList.valueOf(color(R.color.brand_purple))
|
||||||
|
setTextColor(color(R.color.brand_text_dark))
|
||||||
|
textAlignment = View.TEXT_ALIGNMENT_VIEW_START
|
||||||
|
gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
||||||
|
backgroundTintList = ColorStateList.valueOf(color(R.color.brand_header_surface))
|
||||||
|
strokeColor = ColorStateList.valueOf(color(R.color.brand_header_stroke))
|
||||||
|
strokeWidth = dp(1)
|
||||||
|
cornerRadius = dp(20)
|
||||||
|
insetTop = 0
|
||||||
|
insetBottom = 0
|
||||||
|
setPadding(dp(12), dp(14), dp(12), dp(14))
|
||||||
|
setOnClickListener {
|
||||||
|
dialog.dismiss()
|
||||||
|
DashboardHandler(activity) {
|
||||||
|
activity.setBackPressInterceptor(null)
|
||||||
|
init()
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val logoutButton = MaterialButton(activity).apply {
|
val logoutButton = MaterialButton(activity).apply {
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
@ -557,6 +612,14 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container.addView(handle)
|
container.addView(handle)
|
||||||
|
container.addView(titleView)
|
||||||
|
container.addView(View(activity).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
dp(14),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
container.addView(dashboardButton)
|
||||||
container.addView(logoutButton)
|
container.addView(logoutButton)
|
||||||
dialog.setContentView(container)
|
dialog.setContentView(container)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
@ -688,6 +751,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
refreshClientSpinner()
|
refreshClientSpinner()
|
||||||
applyUpdateButtonTexts(force = true)
|
applyUpdateButtonTexts(force = true)
|
||||||
updateStatusStrip()
|
updateStatusStrip()
|
||||||
|
updateSessionMetrics()
|
||||||
updateQuestionnaireSectionVisibility()
|
updateQuestionnaireSectionVisibility()
|
||||||
refreshLoadedClientUi()
|
refreshLoadedClientUi()
|
||||||
}
|
}
|
||||||
@ -711,6 +775,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
noClientsAssignedText.text = t("no_clients_assigned")
|
noClientsAssignedText.text = t("no_clients_assigned")
|
||||||
noClientsAssignedText.visibility = View.VISIBLE
|
noClientsAssignedText.visibility = View.VISIBLE
|
||||||
textView.visibility = View.GONE
|
textView.visibility = View.GONE
|
||||||
|
updateSessionMetrics()
|
||||||
nextStepBannerCard.visibility = View.GONE
|
nextStepBannerCard.visibility = View.GONE
|
||||||
questionnaireScroll.visibility = View.GONE
|
questionnaireScroll.visibility = View.GONE
|
||||||
bottomUploadDock.visibility = View.GONE
|
bottomUploadDock.visibility = View.GONE
|
||||||
@ -728,9 +793,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
|
|
||||||
nextStepBannerCard.visibility = View.VISIBLE
|
nextStepBannerCard.visibility = View.VISIBLE
|
||||||
val completed = dynamicButtons.count { isCompleted(it) }
|
val completed = dynamicButtons.count { isCompleted(it) }
|
||||||
nextStepEyebrow.text = t("next_step_label")
|
nextStepEyebrow.text = hubFallback("Nächster Sitzungsschritt", "Next session step")
|
||||||
nextStepTitle.text = t("next_step_loading_title")
|
nextStepTitle.text = hubFallback("Sitzungsstatus wird geprüft", "Checking session status")
|
||||||
nextStepBody.text = t("next_step_loading_body")
|
nextStepBody.text = hubFallback("Lokale Daten, Reviews und Synchronisation werden ausgewertet.", "Reviewing local measures, scoring work, and sync status.")
|
||||||
nextStepActionButton.visibility = View.GONE
|
nextStepActionButton.visibility = View.GONE
|
||||||
nextStepActionButton.setOnClickListener(null)
|
nextStepActionButton.setOnClickListener(null)
|
||||||
|
|
||||||
@ -769,9 +834,19 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun applyNextStepBanner(titleKey: String, bodyKey: String, action: NextStepAction) {
|
private fun applyNextStepBanner(titleKey: String, bodyKey: String, action: NextStepAction) {
|
||||||
nextStepEyebrow.text = t("next_step_label")
|
nextStepEyebrow.text = hubFallback("Nächster Sitzungsschritt", "Next session step")
|
||||||
nextStepTitle.text = t(titleKey)
|
nextStepTitle.text = when (action) {
|
||||||
nextStepBody.text = t(bodyKey)
|
NextStepAction.UPLOAD -> hubFallback("Synchronisation offen", "Sync required")
|
||||||
|
NextStepAction.REVIEW -> hubFallback("Score-Review offen", "Score review pending")
|
||||||
|
NextStepAction.QUESTIONNAIRE -> hubFallback("Sitzung fortsetzen", "Continue session")
|
||||||
|
NextStepAction.NONE -> hubFallback("Sitzung vollständig", "Session complete")
|
||||||
|
}
|
||||||
|
nextStepBody.text = when (action) {
|
||||||
|
NextStepAction.UPLOAD -> hubFallback("Es gibt fertige lokale Sitzungsdaten, die hochgeladen werden müssen.", "Completed local session data is waiting to be uploaded.")
|
||||||
|
NextStepAction.REVIEW -> hubFallback("Mindestens ein Score benötigt noch eine fachliche Prüfung.", "At least one score still needs counselor review.")
|
||||||
|
NextStepAction.QUESTIONNAIRE -> hubFallback("Der nächste verfügbare Messpunkt ist bereit für diese Sitzung.", "The next available measure is ready for this session.")
|
||||||
|
NextStepAction.NONE -> hubFallback("Alle verfügbaren Messpunkte für diesen Klienten sind abgeschlossen.", "All available measures for this client are complete.")
|
||||||
|
}
|
||||||
when (action) {
|
when (action) {
|
||||||
NextStepAction.UPLOAD -> {
|
NextStepAction.UPLOAD -> {
|
||||||
nextStepActionButton.visibility = View.VISIBLE
|
nextStepActionButton.visibility = View.VISIBLE
|
||||||
@ -793,7 +868,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
}
|
}
|
||||||
NextStepAction.QUESTIONNAIRE -> {
|
NextStepAction.QUESTIONNAIRE -> {
|
||||||
nextStepActionButton.visibility = View.VISIBLE
|
nextStepActionButton.visibility = View.VISIBLE
|
||||||
nextStepActionButton.text = t("next_step_show_questionnaire")
|
nextStepActionButton.text = hubFallback("Messpunkt anzeigen", "Show measure")
|
||||||
nextStepActionButton.setOnClickListener { highlightNextAvailableQuestionnaire() }
|
nextStepActionButton.setOnClickListener { highlightNextAvailableQuestionnaire() }
|
||||||
}
|
}
|
||||||
NextStepAction.NONE -> {
|
NextStepAction.NONE -> {
|
||||||
@ -952,6 +1027,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
val base = t("upload")
|
val base = t("upload")
|
||||||
uploadButton.text = if (count > 0) "$base ($count)" else base
|
uploadButton.text = if (count > 0) "$base ($count)" else base
|
||||||
uploadButton.contentDescription = uploadButton.text
|
uploadButton.contentDescription = uploadButton.text
|
||||||
|
if (::sessionMetricSyncValue.isInitialized) {
|
||||||
|
sessionMetricSyncValue.text = if (count > 0) count.toString() else "OK"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,7 +1123,8 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
uploadButton.text = t("upload")
|
uploadButton.text = t("upload")
|
||||||
applyHubLabels()
|
applyHubLabels()
|
||||||
applyCoachDisplay()
|
applyCoachDisplay()
|
||||||
textView.text = t("questionnaire_title")
|
textView.text = hubFallback("Sitzungsinstrumente", "Session measures")
|
||||||
|
updateSessionMetrics()
|
||||||
updateNextStepBanner()
|
updateNextStepBanner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,21 +1,21 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.data.ClientAnswersCache
|
import com.tomhempel.rbarometer.data.ClientAnswersCache
|
||||||
import com.dano.test1.data.ClientRepository
|
import com.tomhempel.rbarometer.data.ClientRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||||
import com.dano.test1.network.NetworkUtils
|
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||||
import com.dano.test1.network.QuestionnaireAnswerSync
|
import com.tomhempel.rbarometer.network.QuestionnaireAnswerSync
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import com.dano.test1.questionnaire.GlobalValues
|
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||||
import com.dano.test1.questionnaire.QuestionItem
|
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||||
|
|
||||||
class LoadButtonHandler(
|
class LoadButtonHandler(
|
||||||
private val activity: MainActivity,
|
private val activity: MainActivity,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
@ -13,7 +13,7 @@ import android.widget.TextView
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
data class Month(val name: String) {
|
data class Month(val name: String) {
|
||||||
override fun toString(): String = name
|
override fun toString(): String = name
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
@ -7,7 +7,7 @@ import android.os.Build
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
@ -8,8 +8,8 @@ import android.widget.Button
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
@ -15,19 +15,19 @@ import android.widget.Toast
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.data.CoachScoringReviewRepository
|
import com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||||
import com.dano.test1.network.ClientScoringReview
|
import com.tomhempel.rbarometer.network.ClientScoringReview
|
||||||
import com.dano.test1.network.QuestionnaireApiClient
|
import com.tomhempel.rbarometer.network.QuestionnaireApiClient
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.ScoringReviewProfile
|
import com.tomhempel.rbarometer.network.ScoringReviewProfile
|
||||||
import com.dano.test1.notification.UploadReminderScheduler
|
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||||
import com.dano.test1.scoring.LocalScoringReviewBuilder
|
import com.tomhempel.rbarometer.scoring.LocalScoringReviewBuilder
|
||||||
import com.dano.test1.questionnaire.AppLanguages
|
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||||
import com.dano.test1.ui.localization.UiStrings
|
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||||
import com.dano.test1.utils.ScreenLoading
|
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
import com.dano.test1.data.UnuploadedWorkRepository
|
import com.tomhempel.rbarometer.data.UnuploadedWorkRepository
|
||||||
import com.dano.test1.network.ClientAnswerSyncStore
|
import com.tomhempel.rbarometer.network.ClientAnswerSyncStore
|
||||||
import com.dano.test1.network.NetworkUtils
|
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.network.TokenStore
|
import com.tomhempel.rbarometer.network.TokenStore
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -6,7 +6,7 @@ import android.view.ViewGroup
|
|||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.ui
|
package com.tomhempel.rbarometer.ui
|
||||||
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -9,20 +9,20 @@ import android.widget.*
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.dano.test1.MainActivity
|
import com.tomhempel.rbarometer.MainActivity
|
||||||
import com.dano.test1.MyApp
|
import com.tomhempel.rbarometer.MyApp
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.data.AnswerRepository
|
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||||
import com.dano.test1.data.CoachScoringReviewRepository
|
import com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||||
import com.dano.test1.data.Question
|
import com.tomhempel.rbarometer.data.Question
|
||||||
import com.dano.test1.network.DatabaseUploader
|
import com.tomhempel.rbarometer.network.DatabaseUploader
|
||||||
import com.dano.test1.network.QuestionnaireCache
|
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||||
import com.dano.test1.questionnaire.AppLanguages
|
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||||
import com.dano.test1.questionnaire.QuestionnaireTranslationsLoader
|
import com.tomhempel.rbarometer.questionnaire.QuestionnaireTranslationsLoader
|
||||||
import com.dano.test1.ui.localization.UiStrings
|
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||||
import com.dano.test1.utils.ScreenLoading
|
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||||
import com.dano.test1.utils.ViewUtils
|
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.ui.localization
|
package com.tomhempel.rbarometer.ui.localization
|
||||||
|
|
||||||
import com.dano.test1.LanguageManager
|
import com.tomhempel.rbarometer.LanguageManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared UI string helpers for upload overview and activities.
|
* Shared UI string helpers for upload overview and activities.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.tomhempel.rbarometer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves UI strings from API translations (synced from the website).
|
* Resolves UI strings from API translations (synced from the website).
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.SyncPhase
|
import com.tomhempel.rbarometer.network.SyncPhase
|
||||||
|
|
||||||
/** Flat Material-style icons per sync phase — no emoji or decorative chrome. */
|
/** Flat Material-style icons per sync phase — no emoji or decorative chrome. */
|
||||||
object SyncPhaseIcons {
|
object SyncPhaseIcons {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
@ -12,9 +12,9 @@ import android.widget.TextView
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.ImageViewCompat
|
import androidx.core.widget.ImageViewCompat
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import com.dano.test1.network.SyncPhase
|
import com.tomhempel.rbarometer.network.SyncPhase
|
||||||
import com.dano.test1.network.SyncProgress
|
import com.tomhempel.rbarometer.network.SyncProgress
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import com.dano.test1.network.SyncPhase
|
import com.tomhempel.rbarometer.network.SyncPhase
|
||||||
|
|
||||||
/** Professional DE/EN copy for the sync overlay — phase messages only, no counts. */
|
/** Professional DE/EN copy for the sync overlay — phase messages only, no counts. */
|
||||||
object SyncProgressTexts {
|
object SyncProgressTexts {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strips patterns commonly used in SQL injection attempts from free-text answers.
|
* Strips patterns commonly used in SQL injection attempts from free-text answers.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1.utils
|
package com.tomhempel.rbarometer.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -14,7 +14,7 @@ import android.widget.Spinner
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.widget.TextViewCompat
|
import androidx.core.widget.TextViewCompat
|
||||||
import com.dano.test1.R
|
import com.tomhempel.rbarometer.R
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
object ViewUtils {
|
object ViewUtils {
|
||||||
8
app/src/main/res/drawable/bg_session_metric.xml
Normal file
8
app/src/main/res/drawable/bg_session_metric.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/brand_header_surface" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/brand_header_stroke" />
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
</shape>
|
||||||
@ -5,166 +5,12 @@
|
|||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#3DDC84"
|
android:fillColor="#0F766E"
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#0E7490"
|
||||||
android:pathData="M9,0L9,108"
|
android:pathData="M0,78 C26,62 48,65 73,49 C88,39 99,27 108,15 L108,108 L0,108 Z" />
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#14B8A6"
|
||||||
android:pathData="M19,0L19,108"
|
android:pathData="M0,0h108v26 C86,36 64,39 44,32 C27,26 14,17 0,14 Z" />
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@ -1,30 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="#FFFFFFFF"
|
||||||
android:fillType="nonZero"
|
android:pathData="M54,23C36.88,23 23,36.88 23,54C23,71.12 36.88,85 54,85C71.12,85 85,71.12 85,54C85,36.88 71.12,23 54,23ZM54,31C66.7,31 77,41.3 77,54C77,66.7 66.7,77 54,77C41.3,77 31,66.7 31,54C31,41.3 41.3,31 54,31Z" />
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
<path
|
||||||
android:strokeWidth="1"
|
android:fillColor="#FFFFFFFF"
|
||||||
android:strokeColor="#00000000" />
|
android:pathData="M54,37C51.79,37 50,38.79 50,41C50,43.21 51.79,45 54,45C56.21,45 58,43.21 58,41C58,38.79 56.21,37 54,37ZM54,41C61.38,41 67.67,45.6 70,52H63.5C61.76,48.45 58.16,46 54,46C49.84,46 46.24,48.45 44.5,52H38C40.33,45.6 46.62,41 54,41Z" />
|
||||||
</vector>
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M52,57 L76,43 L58,64 Z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M31,70h46v7h-46z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M32,54h6v5h-6zM70,54h6v5h-6zM51,30h6v8h-6z" />
|
||||||
|
</vector>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user