prototype changes for demo
This commit is contained in:
@ -5,11 +5,11 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.dano.test1"
|
||||
namespace = "com.tomhempel.rbarometer"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.dano.test1"
|
||||
applicationId = "com.tomhempel.rbarometer"
|
||||
minSdk = 29
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.dano.test1">
|
||||
package="com.tomhempel.rbarometer">
|
||||
|
||||
<!-- Netzwerkberechtigungen -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
@ -19,7 +19,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Test1"
|
||||
android:theme="@style/Theme.Barometer"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:usesCleartextTraffic="false"
|
||||
tools:targetApi="31">
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1
|
||||
package com.tomhempel.rbarometer
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
@ -16,27 +16,27 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.ui.AppLanguageStore
|
||||
import com.dano.test1.ui.NotificationPermissionPrompter
|
||||
import com.dano.test1.ui.AuthActivity
|
||||
import com.dano.test1.ui.HandlerOpeningScreen
|
||||
import com.dano.test1.ui.LogoutDialogs
|
||||
import com.dano.test1.ui.SessionLogout
|
||||
import com.dano.test1.ui.SystemBarInsets
|
||||
import com.dano.test1.utils.SyncProgressOverlay
|
||||
import com.dano.test1.utils.SyncProgressTexts
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.dano.test1.data.PendingUploadRepository
|
||||
import com.dano.test1.network.NetworkUtils
|
||||
import com.dano.test1.network.QuestionnaireApiClient
|
||||
import com.dano.test1.network.SyncLog
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.SyncCoordinator
|
||||
import com.dano.test1.network.SyncProgress
|
||||
import com.dano.test1.network.SyncResult
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.questionnaire.QuestionnaireBase
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||
import com.tomhempel.rbarometer.ui.NotificationPermissionPrompter
|
||||
import com.tomhempel.rbarometer.ui.AuthActivity
|
||||
import com.tomhempel.rbarometer.ui.HandlerOpeningScreen
|
||||
import com.tomhempel.rbarometer.ui.LogoutDialogs
|
||||
import com.tomhempel.rbarometer.ui.SessionLogout
|
||||
import com.tomhempel.rbarometer.ui.SystemBarInsets
|
||||
import com.tomhempel.rbarometer.utils.SyncProgressOverlay
|
||||
import com.tomhempel.rbarometer.utils.SyncProgressTexts
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.data.PendingUploadRepository
|
||||
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireApiClient
|
||||
import com.tomhempel.rbarometer.network.SyncLog
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||
import com.tomhempel.rbarometer.network.SyncProgress
|
||||
import com.tomhempel.rbarometer.network.SyncResult
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireBase
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -1,12 +1,12 @@
|
||||
package com.dano.test1
|
||||
package com.tomhempel.rbarometer
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.dano.test1.data.AppDatabase
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.data.AppDatabase
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
|
||||
/*
|
||||
MyApp (Application)
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
|
||||
object AnswerRepository {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import androidx.room.Database
|
||||
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
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
|
||||
object ClientRepository {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
|
||||
object CoachScoringReviewRepository {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
object CompletedQuestionnaireRepository {
|
||||
|
||||
private val dao get() = MyApp.database.completedQuestionnaireDao()
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import androidx.room.*
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
import androidx.room.*
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.data
|
||||
package com.tomhempel.rbarometer.data
|
||||
|
||||
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.
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
data class ApiError(
|
||||
val code: String? = null,
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
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). */
|
||||
internal object ClientAnswerSyncStore {
|
||||
@ -1,8 +1,8 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.notification.UploadReminderScheduler
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@ -48,9 +48,9 @@ object DatabaseUploader {
|
||||
onResult: (UploadResult) -> Unit,
|
||||
) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val allPending = com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
val allPending = com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
.getAllPendingUploads()
|
||||
val pendingScoring = com.dano.test1.data.CoachScoringReviewRepository
|
||||
val pendingScoring = com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||
.getAllPendingUploads()
|
||||
if (allPending.isEmpty() && pendingScoring.isEmpty()) {
|
||||
val assigned = QuestionnaireCache.getAssignedClients(context)
|
||||
@ -113,7 +113,7 @@ object DatabaseUploader {
|
||||
QuestionnaireApiClient.submitQuestionnaire(token, request)
|
||||
}.onSuccess { response ->
|
||||
submittedQuestionnaires++
|
||||
com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
.markUploaded(clientCode, entry.questionnaireId, System.currentTimeMillis())
|
||||
if (response.legacySubmit) {
|
||||
val submitRev = response.structureRevision
|
||||
@ -162,7 +162,7 @@ object DatabaseUploader {
|
||||
)
|
||||
}.onSuccess {
|
||||
submittedScoringReviews++
|
||||
com.dano.test1.data.CoachScoringReviewRepository.markUploaded(
|
||||
com.tomhempel.rbarometer.data.CoachScoringReviewRepository.markUploaded(
|
||||
review.clientCode,
|
||||
review.profileID,
|
||||
System.currentTimeMillis(),
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import okhttp3.Dispatcher
|
||||
import okhttp3.OkHttpClient
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
@ -1,14 +1,14 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.data.AnswerEntity
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaire
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.dano.test1.data.Question
|
||||
import com.dano.test1.data.Questionnaire
|
||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.data.AnswerEntity
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.data.Question
|
||||
import com.tomhempel.rbarometer.data.Questionnaire
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
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 sumPoints = block.sumPoints
|
||||
val clientKey = com.dano.test1.security.SensitiveDataCrypto.clientCodeKey(clientCode)
|
||||
val clientKey = com.tomhempel.rbarometer.security.SensitiveDataCrypto.clientCodeKey(clientCode)
|
||||
|
||||
return PreparedBlockImport(
|
||||
questionnaireId = questionnaireId,
|
||||
@ -382,7 +382,7 @@ object QuestionnaireAnswerSync {
|
||||
AnswerEntity(
|
||||
clientCodeKey = clientKey,
|
||||
questionId = AnswerKeyUtils.roomQuestionId(questionnaireId, key),
|
||||
answerValueEnc = com.dano.test1.security.SensitiveDataCrypto.encrypt(value),
|
||||
answerValueEnc = com.tomhempel.rbarometer.security.SensitiveDataCrypto.encrypt(value),
|
||||
)
|
||||
},
|
||||
completion = CompletedQuestionnaire(
|
||||
@ -461,8 +461,8 @@ object QuestionnaireAnswerSync {
|
||||
}
|
||||
|
||||
private fun CompletedQuestionnaire.toEntity(clientCode: String) =
|
||||
com.dano.test1.data.CompletedQuestionnaireEntity(
|
||||
clientCodeKey = com.dano.test1.security.SensitiveDataCrypto.clientCodeKey(clientCode),
|
||||
com.tomhempel.rbarometer.data.CompletedQuestionnaireEntity(
|
||||
clientCodeKey = com.tomhempel.rbarometer.security.SensitiveDataCrypto.clientCodeKey(clientCode),
|
||||
questionnaireId = questionnaireId,
|
||||
timestamp = timestamp,
|
||||
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.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
@ -1,11 +1,11 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.data.ClientRepository
|
||||
import com.dano.test1.security.SensitiveDataCrypto
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.data.ClientRepository
|
||||
import com.tomhempel.rbarometer.security.SensitiveDataCrypto
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
@ -102,9 +102,9 @@ object QuestionnaireCache {
|
||||
*/
|
||||
suspend fun wipeEntireLocalStore(context: Context) {
|
||||
clearAssignedClients(context)
|
||||
com.dano.test1.MyApp.database.clearAllTables()
|
||||
com.tomhempel.rbarometer.MyApp.database.clearAllTables()
|
||||
cacheDir(context).deleteRecursively()
|
||||
com.dano.test1.notification.UploadReminderScheduler.cancel(context)
|
||||
com.tomhempel.rbarometer.notification.UploadReminderScheduler.cancel(context)
|
||||
LanguageManager.setApiTranslations(emptyMap())
|
||||
LanguageManager.setQuestionnaireTranslations(emptyMap())
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
@ -1,9 +1,9 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.data.CompletedQuestionnaire
|
||||
import com.dano.test1.data.Questionnaire
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||
import com.tomhempel.rbarometer.data.Questionnaire
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
@ -203,7 +203,7 @@ object QuestionnaireSyncService {
|
||||
private suspend fun seedServerCompletions(clientInfosFromApi: List<AssignedClientInfo>) {
|
||||
val toInsert = mutableListOf<CompletedQuestionnaire>()
|
||||
for (clientInfo in clientInfosFromApi) {
|
||||
val existingByQn = com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
val existingByQn = com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
.getAllForClient(clientInfo.clientCode)
|
||||
.associateBy { it.questionnaireId }
|
||||
for (serverCompletion in clientInfo.completedQuestionnaires) {
|
||||
@ -225,7 +225,7 @@ object QuestionnaireSyncService {
|
||||
}
|
||||
if (toInsert.isNotEmpty()) {
|
||||
runCatching {
|
||||
com.dano.test1.data.CompletedQuestionnaireRepository.insertAll(toInsert)
|
||||
com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository.insertAll(toInsert)
|
||||
}.onSuccess {
|
||||
SyncLog.d(TAG, "seeded ${toInsert.size} server completion(s)")
|
||||
}.onFailure { e ->
|
||||
@ -1,8 +1,8 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
|
||||
sealed class SyncResult {
|
||||
data object Success : SyncResult()
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.util.Log
|
||||
import com.dano.test1.BuildConfig
|
||||
import com.tomhempel.rbarometer.BuildConfig
|
||||
import java.security.MessageDigest
|
||||
|
||||
/** 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. */
|
||||
enum class SyncPhase {
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.network
|
||||
package com.tomhempel.rbarometer.network
|
||||
|
||||
import android.content.Context
|
||||
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.NotificationManager
|
||||
@ -8,9 +8,9 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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.PendingIntent
|
||||
@ -51,7 +51,7 @@ object UploadReminderScheduler {
|
||||
*/
|
||||
suspend fun hasPendingUploads(): Boolean {
|
||||
return try {
|
||||
com.dano.test1.data.PendingUploadRepository.hasAny()
|
||||
com.tomhempel.rbarometer.data.PendingUploadRepository.hasAny()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "hasPendingUploads check failed: ${e.message}")
|
||||
false
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -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.Dispatchers
|
||||
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.
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
|
||||
object ClientAssignmentGuard {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.util.Log
|
||||
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 {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
import android.view.View
|
||||
|
||||
interface QuestionHandler {
|
||||
@ -1,16 +1,16 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.questionnaire.handlers.HandlerClientCoachCode
|
||||
import com.dano.test1.questionnaire.handlers.HandlerDateSpinner
|
||||
import com.dano.test1.questionnaire.handlers.HandlerFreeText
|
||||
import com.dano.test1.questionnaire.handlers.HandlerGlassScaleQuestion
|
||||
import com.dano.test1.questionnaire.handlers.HandlerLastPage
|
||||
import com.dano.test1.questionnaire.handlers.HandlerMultiCheckboxQuestion
|
||||
import com.dano.test1.questionnaire.handlers.HandlerRadioQuestion
|
||||
import com.dano.test1.questionnaire.handlers.HandlerSliderQuestion
|
||||
import com.dano.test1.questionnaire.handlers.HandlerStringSpinner
|
||||
import com.dano.test1.questionnaire.handlers.HandlerValueSpinner
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerClientCoachCode
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerDateSpinner
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerFreeText
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerGlassScaleQuestion
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerLastPage
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerMultiCheckboxQuestion
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerRadioQuestion
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerSliderQuestion
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerStringSpinner
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerValueSpinner
|
||||
|
||||
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.widget.TextView
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
/** Renders optional noteBeforeKey / noteAfterKey above and below the main question text. */
|
||||
object QuestionNotesHelper {
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.graphics.Color
|
||||
import android.text.Editable
|
||||
@ -9,19 +9,19 @@ import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.questionnaire.handlers.HandlerStringSpinner
|
||||
import com.dano.test1.questionnaire.handlers.HandlerValueSpinner
|
||||
import com.dano.test1.ui.AppLanguageStore
|
||||
import com.dano.test1.ui.ReviewScoresHandler
|
||||
import com.dano.test1.utils.DateAnswerFormat
|
||||
import com.dano.test1.utils.DatePrecision
|
||||
import com.dano.test1.utils.ScreenLoading
|
||||
import com.dano.test1.utils.TextInputSanitizer
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerStringSpinner
|
||||
import com.tomhempel.rbarometer.questionnaire.handlers.HandlerValueSpinner
|
||||
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||
import com.tomhempel.rbarometer.ui.ReviewScoresHandler
|
||||
import com.tomhempel.rbarometer.utils.DateAnswerFormat
|
||||
import com.tomhempel.rbarometer.utils.DatePrecision
|
||||
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||
import com.tomhempel.rbarometer.utils.TextInputSanitizer
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import kotlinx.coroutines.*
|
||||
@ -296,7 +296,7 @@ class QuestionnaireAllInOne(private val questionnaireFileName: String) : Questio
|
||||
}
|
||||
}
|
||||
languageID = newLang
|
||||
com.dano.test1.ui.AppLanguageStore.set(context, newLang)
|
||||
com.tomhempel.rbarometer.ui.AppLanguageStore.set(context, newLang)
|
||||
persistedBaselineAnswers = snapshotAnswerKeys(answers)
|
||||
uiChangedSinceBaseline = false
|
||||
buildAllInOneUi()
|
||||
@ -927,7 +927,7 @@ class QuestionnaireAllInOne(private val questionnaireFileName: String) : Questio
|
||||
|
||||
private fun selectedMonthNumber(view: View): Int? {
|
||||
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)
|
||||
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.app.Activity
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.util.Calendar
|
||||
@ -77,7 +77,7 @@ abstract class QuestionnaireBase<T> {
|
||||
|
||||
protected fun showEmptyScreen() {
|
||||
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 com.dano.test1.MainActivity
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
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.View
|
||||
@ -6,8 +6,8 @@ import android.widget.AdapterView
|
||||
import android.widget.Button
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.Spinner
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
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]
|
||||
if (newLang == languageID) return
|
||||
languageID = newLang
|
||||
com.dano.test1.ui.AppLanguageStore.set(context, newLang)
|
||||
com.tomhempel.rbarometer.ui.AppLanguageStore.set(context, newLang)
|
||||
spinner.post { showCurrentQuestion() }
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
data class Option(
|
||||
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 com.dano.test1.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
@ -1,18 +1,18 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.data.Answer
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.data.ClientAnswersCache
|
||||
import com.dano.test1.data.ClientRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaire
|
||||
import com.dano.test1.data.Question
|
||||
import com.dano.test1.data.Questionnaire
|
||||
import com.dano.test1.network.SyncLog
|
||||
import com.dano.test1.notification.UploadReminderScheduler
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.data.Answer
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.data.ClientAnswersCache
|
||||
import com.tomhempel.rbarometer.data.ClientRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||
import com.tomhempel.rbarometer.data.Question
|
||||
import com.tomhempel.rbarometer.data.Questionnaire
|
||||
import com.tomhempel.rbarometer.network.SyncLog
|
||||
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||
|
||||
object QuestionnairePersistence {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
object QuestionnaireProgressiveCallbacks {
|
||||
@JvmStatic
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
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. */
|
||||
object QuestionnaireTranslationsLoader {
|
||||
@ -1,10 +1,10 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import android.app.Activity
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -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 {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.questionnaire
|
||||
package com.tomhempel.rbarometer.questionnaire
|
||||
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.ui.localization.UiStrings
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||
|
||||
/**
|
||||
* 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.widget.*
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.ClientRepository
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.ClientRepository
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.questionnaire.MAX_VALUE_YEAR
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
||||
import com.dano.test1.ui.Month
|
||||
import com.dano.test1.ui.Months
|
||||
import com.dano.test1.utils.DateAnswerFormat
|
||||
import com.dano.test1.utils.DatePrecision
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.questionnaire.MAX_VALUE_YEAR
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||
import com.tomhempel.rbarometer.ui.Month
|
||||
import com.tomhempel.rbarometer.ui.Months
|
||||
import com.tomhempel.rbarometer.utils.DateAnswerFormat
|
||||
import com.tomhempel.rbarometer.utils.DatePrecision
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import java.util.Calendar
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
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.text.InputFilter
|
||||
@ -6,16 +6,16 @@ import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
||||
import com.dano.test1.utils.TextInputSanitizer
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||
import com.tomhempel.rbarometer.utils.TextInputSanitizer
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
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.view.View
|
||||
@ -6,16 +6,16 @@ import android.widget.*
|
||||
import android.text.Html
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.ui.AppLanguageStore
|
||||
import com.dano.test1.ui.ReviewScoresHandler
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||
import com.tomhempel.rbarometer.ui.ReviewScoresHandler
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
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.util.TypedValue
|
||||
@ -6,14 +6,14 @@ import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
/*
|
||||
Zweck:
|
||||
@ -1,18 +1,18 @@
|
||||
package com.dano.test1.questionnaire.handlers
|
||||
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.text.Html
|
||||
import android.widget.*
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
/*
|
||||
Zweck:
|
||||
@ -1,17 +1,17 @@
|
||||
package com.dano.test1.questionnaire.handlers
|
||||
package com.tomhempel.rbarometer.questionnaire.handlers
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
class HandlerSliderQuestion(
|
||||
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.view.View
|
||||
import android.widget.*
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.questionnaire.AnswerLookup
|
||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.SpinnerAnswerRules
|
||||
import com.dano.test1.questionnaire.SpinnerSelectionHelper
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerLookup
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.SpinnerAnswerRules
|
||||
import com.tomhempel.rbarometer.questionnaire.SpinnerSelectionHelper
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
class HandlerStringSpinner(
|
||||
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.view.View
|
||||
import android.widget.*
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.questionnaire.AnswerLookup
|
||||
import com.dano.test1.questionnaire.AnswerRestoreHelper
|
||||
import com.dano.test1.questionnaire.QuestionFlowResolver
|
||||
import com.dano.test1.questionnaire.SpinnerAnswerRules
|
||||
import com.dano.test1.questionnaire.SpinnerSelectionHelper
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.questionnaire.QuestionHandler
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.QuestionNotesHelper
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerLookup
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerRestoreHelper
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
|
||||
import com.tomhempel.rbarometer.questionnaire.SpinnerAnswerRules
|
||||
import com.tomhempel.rbarometer.questionnaire.SpinnerSelectionHelper
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
class HandlerValueSpinner(
|
||||
private val context: Context,
|
||||
@ -1,13 +1,13 @@
|
||||
package com.dano.test1.scoring
|
||||
package com.tomhempel.rbarometer.scoring
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.dano.test1.network.ClientScoringReview
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.ScoringProfileDefinition
|
||||
import com.dano.test1.network.ScoringReviewProfile
|
||||
import com.dano.test1.questionnaire.AnswerKeyUtils
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.network.ClientScoringReview
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.ScoringProfileDefinition
|
||||
import com.tomhempel.rbarometer.network.ScoringReviewProfile
|
||||
import com.tomhempel.rbarometer.questionnaire.AnswerKeyUtils
|
||||
import com.google.gson.JsonParser
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.scoring
|
||||
package com.tomhempel.rbarometer.scoring
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
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.security.keystore.KeyGenParameterSpec
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.security
|
||||
package com.tomhempel.rbarometer.security
|
||||
|
||||
import android.util.Base64
|
||||
import com.google.gson.JsonObject
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.content.Context
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
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.
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
@ -9,17 +9,17 @@ import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.network.LoginManager
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.SyncCoordinator
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.questionnaire.AppLanguages
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.LoginManager
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.dano.test1.utils.ScreenLoading
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
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.TextWatcher
|
||||
@ -10,8 +10,8 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
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 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 com.dano.test1.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
|
||||
object DevSettingsAccess {
|
||||
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.os.Bundle
|
||||
@ -12,16 +12,16 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.network.QuestionnaireSyncService
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.utils.SyncProgressOverlay
|
||||
import com.dano.test1.utils.SyncProgressTexts
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireSyncService
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.utils.SyncProgressOverlay
|
||||
import com.tomhempel.rbarometer.utils.SyncProgressTexts
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.dano.test1.ui.AppLanguageStore
|
||||
import com.dano.test1.ui.LogoutDialogs
|
||||
import com.dano.test1.ui.SessionLogout
|
||||
import com.tomhempel.rbarometer.ui.AppLanguageStore
|
||||
import com.tomhempel.rbarometer.ui.LogoutDialogs
|
||||
import com.tomhempel.rbarometer.ui.SessionLogout
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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.res.ColorStateList
|
||||
@ -12,36 +12,36 @@ import androidx.appcompat.widget.AppCompatImageButton
|
||||
import android.widget.*
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.data.PendingUploadRepository
|
||||
import com.dano.test1.data.UnuploadedWorkRepository
|
||||
import com.dano.test1.network.NetworkUtils
|
||||
import com.dano.test1.network.QuestionnaireAnswerSync
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.SyncCoordinator
|
||||
import com.dano.test1.network.SyncResult
|
||||
import com.dano.test1.questionnaire.AppLanguages
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.data.PendingUploadRepository
|
||||
import com.tomhempel.rbarometer.data.UnuploadedWorkRepository
|
||||
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireAnswerSync
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.SyncCoordinator
|
||||
import com.tomhempel.rbarometer.network.SyncResult
|
||||
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.dano.test1.questionnaire.ConditionJsonParser
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.dano.test1.questionnaire.QuestionnaireBase
|
||||
import com.dano.test1.questionnaire.QuestionnaireAllInOne
|
||||
import com.dano.test1.questionnaire.QuestionnaireGeneric
|
||||
import com.dano.test1.questionnaire.QuestionnaireValidation
|
||||
import com.tomhempel.rbarometer.questionnaire.ConditionJsonParser
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireBase
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireAllInOne
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireGeneric
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireValidation
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import org.json.JSONObject
|
||||
import com.dano.test1.utils.ScreenLoading
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
|
||||
|
||||
class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
@ -60,6 +60,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
private lateinit var spinner: Spinner
|
||||
private lateinit var textView: 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 nextStepEyebrow: TextView
|
||||
private lateinit var nextStepTitle: TextView
|
||||
@ -213,6 +216,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
spinner = activity.findViewById(R.id.string_spinner1)
|
||||
textView = activity.findViewById(R.id.textView)
|
||||
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)
|
||||
nextStepEyebrow = activity.findViewById(R.id.nextStepEyebrow)
|
||||
nextStepTitle = activity.findViewById(R.id.nextStepTitle)
|
||||
@ -233,23 +239,40 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
refreshProgress = activity.findViewById(R.id.refreshProgress)
|
||||
refreshButton.contentDescription = t("refresh")
|
||||
settingsButton.contentDescription = tOr("settings", hubFallback("Einstellungen", "Settings"))
|
||||
textView.text = t("questionnaire_title")
|
||||
textView.text = hubFallback("Sitzungsinstrumente", "Session measures")
|
||||
applyHubLabels()
|
||||
updateSessionMetrics()
|
||||
applyCoachDisplay()
|
||||
}
|
||||
|
||||
private fun applyHubLabels() {
|
||||
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"))
|
||||
labelClientCode.text = tOr("client_code", hubFallback("Klientencode", "Client code"))
|
||||
labelClientCode.text = hubFallback("Aktiver Klient", "Active client")
|
||||
}
|
||||
|
||||
private fun applyCoachDisplay() {
|
||||
if (!::coachNameDisplay.isInitialized) return
|
||||
val username = TokenStore.getUsername(activity)?.trim().orEmpty()
|
||||
coachNameDisplay.text = username.ifBlank {
|
||||
tOr("coach_code", hubFallback("Coach", "Coach"))
|
||||
coachNameDisplay.text = if (username.isBlank()) {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
@ -557,6 +612,14 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
}
|
||||
|
||||
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)
|
||||
dialog.setContentView(container)
|
||||
dialog.show()
|
||||
@ -688,6 +751,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
refreshClientSpinner()
|
||||
applyUpdateButtonTexts(force = true)
|
||||
updateStatusStrip()
|
||||
updateSessionMetrics()
|
||||
updateQuestionnaireSectionVisibility()
|
||||
refreshLoadedClientUi()
|
||||
}
|
||||
@ -711,6 +775,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
noClientsAssignedText.text = t("no_clients_assigned")
|
||||
noClientsAssignedText.visibility = View.VISIBLE
|
||||
textView.visibility = View.GONE
|
||||
updateSessionMetrics()
|
||||
nextStepBannerCard.visibility = View.GONE
|
||||
questionnaireScroll.visibility = View.GONE
|
||||
bottomUploadDock.visibility = View.GONE
|
||||
@ -728,9 +793,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
|
||||
nextStepBannerCard.visibility = View.VISIBLE
|
||||
val completed = dynamicButtons.count { isCompleted(it) }
|
||||
nextStepEyebrow.text = t("next_step_label")
|
||||
nextStepTitle.text = t("next_step_loading_title")
|
||||
nextStepBody.text = t("next_step_loading_body")
|
||||
nextStepEyebrow.text = hubFallback("Nächster Sitzungsschritt", "Next session step")
|
||||
nextStepTitle.text = hubFallback("Sitzungsstatus wird geprüft", "Checking session status")
|
||||
nextStepBody.text = hubFallback("Lokale Daten, Reviews und Synchronisation werden ausgewertet.", "Reviewing local measures, scoring work, and sync status.")
|
||||
nextStepActionButton.visibility = View.GONE
|
||||
nextStepActionButton.setOnClickListener(null)
|
||||
|
||||
@ -769,9 +834,19 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
}
|
||||
|
||||
private fun applyNextStepBanner(titleKey: String, bodyKey: String, action: NextStepAction) {
|
||||
nextStepEyebrow.text = t("next_step_label")
|
||||
nextStepTitle.text = t(titleKey)
|
||||
nextStepBody.text = t(bodyKey)
|
||||
nextStepEyebrow.text = hubFallback("Nächster Sitzungsschritt", "Next session step")
|
||||
nextStepTitle.text = when (action) {
|
||||
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) {
|
||||
NextStepAction.UPLOAD -> {
|
||||
nextStepActionButton.visibility = View.VISIBLE
|
||||
@ -793,7 +868,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
}
|
||||
NextStepAction.QUESTIONNAIRE -> {
|
||||
nextStepActionButton.visibility = View.VISIBLE
|
||||
nextStepActionButton.text = t("next_step_show_questionnaire")
|
||||
nextStepActionButton.text = hubFallback("Messpunkt anzeigen", "Show measure")
|
||||
nextStepActionButton.setOnClickListener { highlightNextAvailableQuestionnaire() }
|
||||
}
|
||||
NextStepAction.NONE -> {
|
||||
@ -952,6 +1027,9 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
||||
val base = t("upload")
|
||||
uploadButton.text = if (count > 0) "$base ($count)" else base
|
||||
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")
|
||||
applyHubLabels()
|
||||
applyCoachDisplay()
|
||||
textView.text = t("questionnaire_title")
|
||||
textView.text = hubFallback("Sitzungsinstrumente", "Session measures")
|
||||
updateSessionMetrics()
|
||||
updateNextStepBanner()
|
||||
}
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.data.ClientAnswersCache
|
||||
import com.dano.test1.data.ClientRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.data.ClientAnswersCache
|
||||
import com.tomhempel.rbarometer.data.ClientRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import kotlinx.coroutines.*
|
||||
import com.dano.test1.data.CompletedQuestionnaire
|
||||
import com.dano.test1.network.NetworkUtils
|
||||
import com.dano.test1.network.QuestionnaireAnswerSync
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.dano.test1.questionnaire.GlobalValues
|
||||
import com.dano.test1.questionnaire.QuestionItem
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaire
|
||||
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireAnswerSync
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import com.tomhempel.rbarometer.questionnaire.GlobalValues
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionItem
|
||||
|
||||
class LoadButtonHandler(
|
||||
private val activity: MainActivity,
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.res.ColorStateList
|
||||
@ -13,7 +13,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.R
|
||||
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) {
|
||||
override fun toString(): String = name
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
@ -7,7 +7,7 @@ import android.os.Build
|
||||
import android.view.LayoutInflater
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.R
|
||||
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.graphics.Typeface
|
||||
@ -8,8 +8,8 @@ import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.button.MaterialButton
|
||||
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.graphics.Typeface
|
||||
@ -15,19 +15,19 @@ import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.data.CoachScoringReviewRepository
|
||||
import com.dano.test1.network.ClientScoringReview
|
||||
import com.dano.test1.network.QuestionnaireApiClient
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.ScoringReviewProfile
|
||||
import com.dano.test1.notification.UploadReminderScheduler
|
||||
import com.dano.test1.scoring.LocalScoringReviewBuilder
|
||||
import com.dano.test1.questionnaire.AppLanguages
|
||||
import com.dano.test1.ui.localization.UiStrings
|
||||
import com.dano.test1.utils.ScreenLoading
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||
import com.tomhempel.rbarometer.network.ClientScoringReview
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireApiClient
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.ScoringReviewProfile
|
||||
import com.tomhempel.rbarometer.notification.UploadReminderScheduler
|
||||
import com.tomhempel.rbarometer.scoring.LocalScoringReviewBuilder
|
||||
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -1,12 +1,12 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.content.Context
|
||||
import com.dano.test1.LanguageManager
|
||||
import com.dano.test1.data.UnuploadedWorkRepository
|
||||
import com.dano.test1.network.ClientAnswerSyncStore
|
||||
import com.dano.test1.network.NetworkUtils
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.network.TokenStore
|
||||
import com.tomhempel.rbarometer.LanguageManager
|
||||
import com.tomhempel.rbarometer.data.UnuploadedWorkRepository
|
||||
import com.tomhempel.rbarometer.network.ClientAnswerSyncStore
|
||||
import com.tomhempel.rbarometer.network.NetworkUtils
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.network.TokenStore
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
@ -6,7 +6,7 @@ import android.view.ViewGroup
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.R
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.ui
|
||||
package com.tomhempel.rbarometer.ui
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.util.Log
|
||||
@ -9,20 +9,20 @@ import android.widget.*
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.dano.test1.MainActivity
|
||||
import com.dano.test1.MyApp
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.data.AnswerRepository
|
||||
import com.dano.test1.data.CoachScoringReviewRepository
|
||||
import com.dano.test1.data.CompletedQuestionnaireRepository
|
||||
import com.dano.test1.data.Question
|
||||
import com.dano.test1.network.DatabaseUploader
|
||||
import com.dano.test1.network.QuestionnaireCache
|
||||
import com.dano.test1.questionnaire.AppLanguages
|
||||
import com.dano.test1.questionnaire.QuestionnaireTranslationsLoader
|
||||
import com.dano.test1.ui.localization.UiStrings
|
||||
import com.dano.test1.utils.ScreenLoading
|
||||
import com.dano.test1.utils.ViewUtils
|
||||
import com.tomhempel.rbarometer.MainActivity
|
||||
import com.tomhempel.rbarometer.MyApp
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.data.AnswerRepository
|
||||
import com.tomhempel.rbarometer.data.CoachScoringReviewRepository
|
||||
import com.tomhempel.rbarometer.data.CompletedQuestionnaireRepository
|
||||
import com.tomhempel.rbarometer.data.Question
|
||||
import com.tomhempel.rbarometer.network.DatabaseUploader
|
||||
import com.tomhempel.rbarometer.network.QuestionnaireCache
|
||||
import com.tomhempel.rbarometer.questionnaire.AppLanguages
|
||||
import com.tomhempel.rbarometer.questionnaire.QuestionnaireTranslationsLoader
|
||||
import com.tomhempel.rbarometer.ui.localization.UiStrings
|
||||
import com.tomhempel.rbarometer.utils.ScreenLoading
|
||||
import com.tomhempel.rbarometer.utils.ViewUtils
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
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.
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.utils
|
||||
package com.tomhempel.rbarometer.utils
|
||||
|
||||
import java.util.Calendar
|
||||
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).
|
||||
@ -1,10 +1,10 @@
|
||||
package com.dano.test1.utils
|
||||
package com.tomhempel.rbarometer.utils
|
||||
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.R
|
||||
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 com.dano.test1.R
|
||||
import com.dano.test1.network.SyncPhase
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.SyncPhase
|
||||
|
||||
/** Flat Material-style icons per sync phase — no emoji or decorative chrome. */
|
||||
object SyncPhaseIcons {
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.utils
|
||||
package com.tomhempel.rbarometer.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
@ -12,9 +12,9 @@ import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.ImageViewCompat
|
||||
import com.dano.test1.R
|
||||
import com.dano.test1.network.SyncPhase
|
||||
import com.dano.test1.network.SyncProgress
|
||||
import com.tomhempel.rbarometer.R
|
||||
import com.tomhempel.rbarometer.network.SyncPhase
|
||||
import com.tomhempel.rbarometer.network.SyncProgress
|
||||
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. */
|
||||
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.
|
||||
@ -1,4 +1,4 @@
|
||||
package com.dano.test1.utils
|
||||
package com.tomhempel.rbarometer.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
@ -14,7 +14,7 @@ import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import com.dano.test1.R
|
||||
import com.tomhempel.rbarometer.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
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:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:fillColor="#0F766E"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
android:fillColor="#0E7490"
|
||||
android:pathData="M0,78 C26,62 48,65 73,49 C88,39 99,27 108,15 L108,108 L0,108 Z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
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" />
|
||||
android:fillColor="#14B8A6"
|
||||
android:pathData="M0,0h108v26 C86,36 64,39 44,32 C27,26 14,17 0,14 Z" />
|
||||
</vector>
|
||||
|
||||
@ -1,30 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="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
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
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"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
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" />
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
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" />
|
||||
<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