added username and password for up- and download
This commit is contained in:
@ -26,10 +26,14 @@ object DatabaseUploader {
|
|||||||
|
|
||||||
private val client = OkHttpClient()
|
private val client = OkHttpClient()
|
||||||
|
|
||||||
fun uploadDatabaseWithLogin(context: Context, password: String) {
|
/** NEU: Login mit Username+Password, danach Upload wie gehabt */
|
||||||
LoginManager.loginUser(context, password,
|
fun uploadDatabaseWithLogin(context: Context, username: String, password: String) {
|
||||||
|
LoginManager.loginUserWithCredentials(
|
||||||
|
context = context,
|
||||||
|
username = username,
|
||||||
|
password = password,
|
||||||
onSuccess = { token ->
|
onSuccess = { token ->
|
||||||
Log.d("UPLOAD", "Login OK")
|
Log.d("UPLOAD", "Login OK (user=$username)")
|
||||||
uploadDatabase(context, token)
|
uploadDatabase(context, token)
|
||||||
},
|
},
|
||||||
onError = { msg -> Log.e("UPLOAD", "Login fehlgeschlagen: $msg") }
|
onError = { msg -> Log.e("UPLOAD", "Login fehlgeschlagen: $msg") }
|
||||||
@ -47,13 +51,12 @@ object DatabaseUploader {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val db = SQLiteDatabase.openDatabase(dbFile.absolutePath, null, SQLiteDatabase.OPEN_READWRITE)
|
val db = SQLiteDatabase.openDatabase(dbFile.absolutePath, null, SQLiteDatabase.OPEN_READWRITE)
|
||||||
db.rawQuery("PRAGMA wal_checkpoint(FULL);", null).use { /* ignore */ }
|
db.rawQuery("PRAGMA wal_checkpoint(FULL);", null).use { /* noop */ }
|
||||||
db.close()
|
db.close()
|
||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
|
|
||||||
checkDatabaseExists() // nur Logging
|
checkDatabaseExists()
|
||||||
uploadPseudoDelta(context, dbFile, token)
|
uploadPseudoDelta(context, dbFile, token)
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("UPLOAD", "Fehler", e)
|
Log.e("UPLOAD", "Fehler", e)
|
||||||
}
|
}
|
||||||
@ -99,7 +102,7 @@ object DatabaseUploader {
|
|||||||
.addFormDataPart("file", "payload.enc", tmpEnc.asRequestBody("application/octet-stream".toMediaType()))
|
.addFormDataPart("file", "payload.enc", tmpEnc.asRequestBody("application/octet-stream".toMediaType()))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val request = Request.Builder().url(SERVER_DELTA_URL).post(body).build()
|
val request = Request.Builder().url("http://49.13.157.44/uploadDeltaTest5.php").post(body).build()
|
||||||
client.newCall(request).enqueue(object : Callback {
|
client.newCall(request).enqueue(object : Callback {
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
Log.e("UPLOAD", "Fehlgeschlagen: ${e.message}")
|
Log.e("UPLOAD", "Fehlgeschlagen: ${e.message}")
|
||||||
@ -109,8 +112,17 @@ object DatabaseUploader {
|
|||||||
val respBody = try { response.body?.string() ?: "" } catch (_: Exception) { "" }
|
val respBody = try { response.body?.string() ?: "" } catch (_: Exception) { "" }
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
Log.d("UPLOAD", "OK: $respBody")
|
Log.d("UPLOAD", "OK: $respBody")
|
||||||
if (!file.delete()) Log.w("UPLOAD", "Lokale DB nicht gelöscht.")
|
|
||||||
File(file.parent, file.name + "-journal").delete()
|
// <<< alte Logik wieder aktivieren: lokale DB + Nebendateien löschen
|
||||||
|
try {
|
||||||
|
if (!file.delete()) Log.w("UPLOAD", "Lokale DB nicht gelöscht.")
|
||||||
|
File(file.parent, "${file.name}-journal").delete()
|
||||||
|
File(file.parent, "${file.name}-wal").delete()
|
||||||
|
File(file.parent, "${file.name}-shm").delete()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w("UPLOAD", "Fehler beim Löschen lokaler DB-Dateien", e)
|
||||||
|
}
|
||||||
|
// >>>
|
||||||
} else {
|
} else {
|
||||||
Log.e("UPLOAD", "HTTP ${response.code}: $respBody")
|
Log.e("UPLOAD", "HTTP ${response.code}: $respBody")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,16 +60,13 @@ class HandlerGlassScaleQuestion(
|
|||||||
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
|
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTv, 0.03f)
|
setTextSizePercentOfScreenHeight(questionTv, 0.03f)
|
||||||
|
|
||||||
// --- FIXE ICON-LEISTE AUFBAUEN (bleibt stehen) ---
|
// ----- feste Icon-Leiste -----
|
||||||
val header = layout.findViewById<LinearLayout>(R.id.glass_header)
|
val header = layout.findViewById<LinearLayout>(R.id.glass_header)
|
||||||
header.removeAllViews()
|
header.removeAllViews()
|
||||||
|
|
||||||
// linker Platzhalter (entspricht der Symptom-Spalte mit weight=4)
|
|
||||||
header.addView(Space(context).apply {
|
header.addView(Space(context).apply {
|
||||||
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 4f)
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 4f)
|
||||||
})
|
})
|
||||||
|
val iconSizePx = (context.resources.displayMetrics.density * 36).toInt()
|
||||||
val iconSizePx = (context.resources.displayMetrics.density * 36).toInt() // ~36dp
|
|
||||||
scaleLabels.forEach { labelKey ->
|
scaleLabels.forEach { labelKey ->
|
||||||
val cell = FrameLayout(context).apply {
|
val cell = FrameLayout(context).apply {
|
||||||
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
@ -83,51 +80,44 @@ class HandlerGlassScaleQuestion(
|
|||||||
cell.addView(img)
|
cell.addView(img)
|
||||||
header.addView(cell)
|
header.addView(cell)
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------
|
// -----------------------------
|
||||||
|
|
||||||
val tableLayout = layout.findViewById<TableLayout>(R.id.glass_table)
|
val tableLayout = layout.findViewById<TableLayout>(R.id.glass_table)
|
||||||
tableLayout.removeAllViews()
|
tableLayout.removeAllViews()
|
||||||
|
|
||||||
addSymptomRows(tableLayout)
|
addSymptomRows(tableLayout)
|
||||||
|
|
||||||
|
// ggf. Antworten aus DB wiederherstellen
|
||||||
val anySymptomNeedsRestore = question.symptoms.any { !answers.containsKey(it) }
|
val anySymptomNeedsRestore = question.symptoms.any { !answers.containsKey(it) }
|
||||||
if (anySymptomNeedsRestore) {
|
if (anySymptomNeedsRestore) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val clientCode = GlobalValues.LAST_CLIENT_CODE
|
val clientCode = GlobalValues.LAST_CLIENT_CODE ?: return@launch
|
||||||
if (clientCode.isNullOrBlank()) return@launch
|
|
||||||
|
|
||||||
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode)
|
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode)
|
||||||
val answerMap = allAnswersForClient.associateBy({ it.questionId }, { it.answerValue })
|
val answerMap = allAnswersForClient.associateBy({ it.questionId }, { it.answerValue })
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val table = tableLayout
|
val table = tableLayout
|
||||||
for ((index, symptomKey) in question.symptoms.withIndex()) {
|
for ((index, symptomKey) in question.symptoms.withIndex()) {
|
||||||
val answerMapKey = questionnaireMeta + "-" + symptomKey
|
val answerMapKey = "$questionnaireMeta-$symptomKey"
|
||||||
val dbAnswer = answerMap[answerMapKey]?.takeIf { it.isNotBlank() }?.trim()
|
val dbAnswer = answerMap[answerMapKey]?.takeIf { it.isNotBlank() }?.trim()
|
||||||
if (!answers.containsKey(symptomKey) && !dbAnswer.isNullOrBlank()) {
|
if (!answers.containsKey(symptomKey) && !dbAnswer.isNullOrBlank()) {
|
||||||
val rowIndex = index // erste Datenzeile ist Index 1 im TableLayout-Aufbau unten
|
if (index < table.childCount) {
|
||||||
if (rowIndex < table.childCount) {
|
val row = table.getChildAt(index) as? TableRow ?: continue
|
||||||
val row = table.getChildAt(rowIndex) as? TableRow ?: continue
|
|
||||||
val radioGroup = row.getChildAt(1) as? RadioGroup ?: continue
|
val radioGroup = row.getChildAt(1) as? RadioGroup ?: continue
|
||||||
for (i in 0 until radioGroup.childCount) {
|
for (i in 0 until radioGroup.childCount) {
|
||||||
val cell = radioGroup.getChildAt(i) as? FrameLayout ?: continue
|
val rb = getRadioFromChild(radioGroup.getChildAt(i)) ?: continue
|
||||||
val rb = cell.getChildAt(0) as? RadioButton ?: continue
|
|
||||||
if ((rb.tag as? String)?.trim() == dbAnswer) {
|
if ((rb.tag as? String)?.trim() == dbAnswer) {
|
||||||
rb.isChecked = true
|
rb.isChecked = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
answers[symptomKey] = dbAnswer
|
answers[symptomKey] = dbAnswer
|
||||||
val point = pointsMap[dbAnswer] ?: 0
|
points.add(pointsMap[dbAnswer] ?: 0)
|
||||||
points.add(point)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) { /* ignore */ }
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,25 +156,21 @@ class HandlerGlassScaleQuestion(
|
|||||||
layoutParams = TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 5f)
|
layoutParams = TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WICHTIG: RadioButtons sind direkte Kinder des RadioGroup!
|
||||||
scaleLabels.forEach { labelKey ->
|
scaleLabels.forEach { labelKey ->
|
||||||
val cell = FrameLayout(context).apply {
|
val rb = RadioButton(context).apply {
|
||||||
layoutParams = RadioGroup.LayoutParams(0, RadioGroup.LayoutParams.WRAP_CONTENT, 1f)
|
|
||||||
}
|
|
||||||
val radioButton = RadioButton(context).apply {
|
|
||||||
tag = labelKey
|
tag = labelKey
|
||||||
id = View.generateViewId()
|
id = View.generateViewId()
|
||||||
isChecked = savedLabel == labelKey
|
isChecked = savedLabel == labelKey
|
||||||
layoutParams = FrameLayout.LayoutParams(
|
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
||||||
Gravity.CENTER
|
|
||||||
)
|
|
||||||
gravity = Gravity.CENTER
|
|
||||||
setPadding(0, 0, 0, 0)
|
setPadding(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
cell.addView(radioButton)
|
val lp = RadioGroup.LayoutParams(
|
||||||
radioGroup.addView(cell)
|
0, RadioGroup.LayoutParams.WRAP_CONTENT, 1f
|
||||||
|
).apply { gravity = Gravity.CENTER }
|
||||||
|
rb.layoutParams = lp
|
||||||
|
radioGroup.addView(rb)
|
||||||
}
|
}
|
||||||
|
|
||||||
row.addView(radioGroup)
|
row.addView(radioGroup)
|
||||||
table.addView(row)
|
table.addView(row)
|
||||||
}
|
}
|
||||||
@ -197,8 +183,7 @@ class HandlerGlassScaleQuestion(
|
|||||||
val radioGroup = row.getChildAt(1) as RadioGroup
|
val radioGroup = row.getChildAt(1) as RadioGroup
|
||||||
var anyChecked = false
|
var anyChecked = false
|
||||||
for (j in 0 until radioGroup.childCount) {
|
for (j in 0 until radioGroup.childCount) {
|
||||||
val cell = radioGroup.getChildAt(j) as FrameLayout
|
val rb = getRadioFromChild(radioGroup.getChildAt(j)) ?: continue
|
||||||
val rb = cell.getChildAt(0) as RadioButton
|
|
||||||
if (rb.isChecked) { anyChecked = true; break }
|
if (rb.isChecked) { anyChecked = true; break }
|
||||||
}
|
}
|
||||||
if (!anyChecked) return false
|
if (!anyChecked) return false
|
||||||
@ -207,9 +192,10 @@ class HandlerGlassScaleQuestion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun saveAnswer() {
|
override fun saveAnswer() {
|
||||||
|
// alte Punkte entfernen
|
||||||
question.symptoms.forEach { key ->
|
question.symptoms.forEach { key ->
|
||||||
val previousLabel = answers[key] as? String
|
val prev = answers[key] as? String
|
||||||
previousLabel?.let { lbl -> pointsMap[lbl] }?.let { points.remove(it) }
|
prev?.let { pointsMap[it] }?.let { points.remove(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val table = layout.findViewById<TableLayout>(R.id.glass_table)
|
val table = layout.findViewById<TableLayout>(R.id.glass_table)
|
||||||
@ -218,18 +204,25 @@ class HandlerGlassScaleQuestion(
|
|||||||
val symptomKey = question.symptoms[i]
|
val symptomKey = question.symptoms[i]
|
||||||
val radioGroup = row.getChildAt(1) as RadioGroup
|
val radioGroup = row.getChildAt(1) as RadioGroup
|
||||||
for (j in 0 until radioGroup.childCount) {
|
for (j in 0 until radioGroup.childCount) {
|
||||||
val cell = radioGroup.getChildAt(j) as FrameLayout
|
val rb = getRadioFromChild(radioGroup.getChildAt(j)) ?: continue
|
||||||
val rb = cell.getChildAt(0) as RadioButton
|
|
||||||
if (rb.isChecked) {
|
if (rb.isChecked) {
|
||||||
val selectedLabel = rb.tag as String
|
val selected = rb.tag as String
|
||||||
answers[symptomKey] = selectedLabel
|
answers[symptomKey] = selected
|
||||||
points.add(pointsMap[selectedLabel] ?: 0)
|
points.add(pointsMap[selected] ?: 0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Helpers ---
|
||||||
|
private fun getRadioFromChild(child: View): RadioButton? =
|
||||||
|
when (child) {
|
||||||
|
is RadioButton -> child
|
||||||
|
is FrameLayout -> child.getChildAt(0) as? RadioButton
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
||||||
val dm = (view.context ?: layout.context).resources.displayMetrics
|
val dm = (view.context ?: layout.context).resources.displayMetrics
|
||||||
val sp = (dm.heightPixels * percentOfHeight) / dm.scaledDensity
|
val sp = (dm.heightPixels * percentOfHeight) / dm.scaledDensity
|
||||||
|
|||||||
@ -434,59 +434,80 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
private fun setupUploadButton() {
|
private fun setupUploadButton() {
|
||||||
uploadButton.text = t("upload")
|
uploadButton.text = t("upload")
|
||||||
uploadButton.setOnClickListener {
|
uploadButton.setOnClickListener {
|
||||||
val clientCode = editText.text.toString().trim()
|
GlobalValues.LAST_CLIENT_CODE = editText.text.toString().trim()
|
||||||
GlobalValues.LAST_CLIENT_CODE = clientCode
|
promptCredentials(
|
||||||
val input = EditText(activity).apply { hint = "Server-Passwort" }
|
title = t("login_required") ?: "Login erforderlich",
|
||||||
android.app.AlertDialog.Builder(activity)
|
onOk = { user, pass ->
|
||||||
.setTitle(t("login_required"))
|
// Login -> Upload
|
||||||
.setView(input)
|
DatabaseUploader.uploadDatabaseWithLogin(activity, user, pass)
|
||||||
.setPositiveButton("OK") { _, _ ->
|
|
||||||
val password = input.text.toString()
|
|
||||||
if (password.isNotBlank()) {
|
|
||||||
Toast.makeText(activity, t("checking_login"), Toast.LENGTH_SHORT).show()
|
|
||||||
DatabaseUploader.uploadDatabaseWithLogin(activity, password)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(activity, t("enter_password"), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(t("cancel"), null)
|
)
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupDownloadButton() {
|
private fun setupDownloadButton() {
|
||||||
downloadButton.text = t("download")
|
downloadButton.text = t("download")
|
||||||
downloadButton.setOnClickListener {
|
downloadButton.setOnClickListener {
|
||||||
val clientCode = editText.text.toString().trim()
|
GlobalValues.LAST_CLIENT_CODE = editText.text.toString().trim()
|
||||||
GlobalValues.LAST_CLIENT_CODE = clientCode
|
promptCredentials(
|
||||||
val input = EditText(activity).apply { hint = "Server-Passwort" }
|
title = t("login_required") ?: "Login erforderlich",
|
||||||
android.app.AlertDialog.Builder(activity)
|
onOk = { user, pass ->
|
||||||
.setTitle(t("login_required"))
|
// Login -> Token -> Download
|
||||||
.setView(input)
|
LoginManager.loginUserWithCredentials(
|
||||||
.setPositiveButton("OK") { _, _ ->
|
context = activity,
|
||||||
val password = input.text.toString()
|
username = user,
|
||||||
if (password.isNotBlank()) {
|
password = pass,
|
||||||
LoginManager.loginUser(
|
onSuccess = { token ->
|
||||||
context = activity,
|
Toast.makeText(activity, t("login_ok") ?: "Login OK", Toast.LENGTH_SHORT).show()
|
||||||
password = password,
|
DatabaseDownloader.downloadAndReplaceDatabase(activity, token)
|
||||||
onSuccess = { token ->
|
updateMainButtonsState(true)
|
||||||
Toast.makeText(activity, t("login_ok"), Toast.LENGTH_SHORT).show()
|
},
|
||||||
DatabaseDownloader.downloadAndReplaceDatabase(activity, token)
|
onError = { error ->
|
||||||
updateMainButtonsState(true)
|
Toast.makeText(activity, error, Toast.LENGTH_LONG).show()
|
||||||
},
|
}
|
||||||
onError = { error ->
|
)
|
||||||
Toast.makeText(activity, error, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(activity, t("enter_password"), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(t("cancel"), null)
|
)
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun promptCredentials(
|
||||||
|
title: String,
|
||||||
|
onOk: (username: String, password: String) -> Unit
|
||||||
|
) {
|
||||||
|
val wrapper = LinearLayout(activity).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
setPadding(dp(20), dp(8), dp(20), 0)
|
||||||
|
}
|
||||||
|
val etUser = EditText(activity).apply {
|
||||||
|
hint = "Username"
|
||||||
|
setSingleLine()
|
||||||
|
}
|
||||||
|
val etPass = EditText(activity).apply {
|
||||||
|
hint = "Passwort"
|
||||||
|
setSingleLine()
|
||||||
|
inputType = android.text.InputType.TYPE_CLASS_TEXT or
|
||||||
|
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
}
|
||||||
|
wrapper.addView(etUser)
|
||||||
|
wrapper.addView(etPass)
|
||||||
|
|
||||||
|
android.app.AlertDialog.Builder(activity)
|
||||||
|
.setTitle(title)
|
||||||
|
.setView(wrapper)
|
||||||
|
.setPositiveButton("OK") { _, _ ->
|
||||||
|
val u = etUser.text.toString().trim()
|
||||||
|
val p = etPass.text.toString()
|
||||||
|
if (u.isNotEmpty() && p.isNotEmpty()) {
|
||||||
|
onOk(u, p)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(activity, t("enter_password") ?: "Bitte Username & Passwort eingeben", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.setNegativeButton(t("cancel") ?: "Abbrechen", null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupDatabaseButtonHandler() {
|
private fun setupDatabaseButtonHandler() {
|
||||||
DatabaseButtonHandler(
|
DatabaseButtonHandler(
|
||||||
activity = activity,
|
activity = activity,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ object LanguageManager {
|
|||||||
private fun injectDynamicValues(text: String): String {
|
private fun injectDynamicValues(text: String): String {
|
||||||
val points = RHS_POINTS ?: 0
|
val points = RHS_POINTS ?: 0
|
||||||
val color = when (points) {
|
val color = when (points) {
|
||||||
in 1..12 -> "#4CAF50" // Grün
|
in 0..12 -> "#4CAF50" // Grün
|
||||||
in 13..36 -> "#FFEB3B" // Gelb
|
in 13..36 -> "#FFEB3B" // Gelb
|
||||||
in 37..100 -> "#F44336" // Rot
|
in 37..100 -> "#F44336" // Rot
|
||||||
else -> "#9E9E9E" // Grau (Standard)
|
else -> "#9E9E9E" // Grau (Standard)
|
||||||
|
|||||||
@ -17,35 +17,45 @@ object LoginManager {
|
|||||||
private const val SERVER_LOGIN_URL = "http://49.13.157.44/login.php"
|
private const val SERVER_LOGIN_URL = "http://49.13.157.44/login.php"
|
||||||
private val client = OkHttpClient()
|
private val client = OkHttpClient()
|
||||||
|
|
||||||
fun loginUser(
|
/**
|
||||||
|
* Neuer Login: Benutzername + Passwort -> Token
|
||||||
|
*/
|
||||||
|
fun loginUserWithCredentials(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
onSuccess: (String) -> Unit,
|
onSuccess: (String) -> Unit,
|
||||||
onError: (String) -> Unit
|
onError: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val requestBody = """{"password":"$password"}"""
|
val bodyJson = JSONObject().apply {
|
||||||
.toRequestBody("application/json".toMediaType())
|
put("username", username.trim())
|
||||||
|
put("password", password)
|
||||||
|
}.toString()
|
||||||
|
|
||||||
|
val requestBody = bodyJson.toRequestBody("application/json".toMediaType())
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(SERVER_LOGIN_URL)
|
.url(SERVER_LOGIN_URL)
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val response = client.newCall(request).execute()
|
client.newCall(request).execute().use { resp ->
|
||||||
val responseText = response.body?.string()
|
val text = resp.body?.string()
|
||||||
|
if (!resp.isSuccessful || text == null) {
|
||||||
if (response.isSuccessful && responseText != null) {
|
withContext(Dispatchers.Main) {
|
||||||
val json = JSONObject(responseText)
|
onError("Fehler beim Login (${resp.code})")
|
||||||
if (json.optBoolean("success")) {
|
}
|
||||||
val token = json.getString("token")
|
return@use
|
||||||
withContext(Dispatchers.Main) { onSuccess(token) }
|
}
|
||||||
} else {
|
val json = runCatching { JSONObject(text) }.getOrNull()
|
||||||
withContext(Dispatchers.Main) { onError("Login fehlgeschlagen") }
|
val ok = json?.optBoolean("success") == true
|
||||||
|
val token = json?.optString("token").orEmpty()
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (ok && token.isNotBlank()) onSuccess(token)
|
||||||
|
else onError(json?.optString("message") ?: "Login fehlgeschlagen")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
withContext(Dispatchers.Main) { onError("Fehler beim Login (${response.code})") }
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("LOGIN", "Exception", e)
|
Log.e("LOGIN", "Exception", e)
|
||||||
|
|||||||
Reference in New Issue
Block a user