diff --git a/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt b/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt index a87b01a..94a154c 100644 --- a/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt +++ b/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt @@ -62,6 +62,7 @@ import com.google.android.gms.wearable.MessageEvent import com.google.android.gms.wearable.Wearable import okhttp3.FormBody import okhttp3.Headers +import org.json.JSONObject class MainActivity : ComponentActivity(), AmbientModeSupport.AmbientCallbackProvider, @@ -72,7 +73,7 @@ class MainActivity : ComponentActivity(), private lateinit var mVibrator: Vibrator private lateinit var vibrationEffectSingle: VibrationEffect private var bpm: MutableState = mutableStateOf("0") - private var alarms: MutableState = mutableStateOf(Alarm(VibrationAlarm(), SoundAlarm(1, 0), false)) + private var alarms: MutableState = mutableStateOf(Alarm(VibrationAlarm(), SoundAlarm(1, 0), false, "", 0)) private var accessToken: MutableState = mutableStateOf(null) private var url: MutableState = mutableStateOf("") private var activityContext: Context? = null @@ -104,9 +105,7 @@ class MainActivity : ComponentActivity(), url.value = ReadEnvVar.readEnvVar(this, ReadEnvVar.EnvVar.API_URL) val alarm = LocalStorage.getData(this, EnvEnum.ALARM.value) if (!alarm.isNullOrEmpty()) { - Log.d("PADOU", "${alarm == "1"}") alarms.value.isAlarmActivate = alarm == "1"; - Log.d("PADOU", "${alarms.value.isAlarmActivate}") } val vibration = LocalStorage.getData(this, EnvEnum.VIBRATION_ALARM.value) if (!vibration.isNullOrEmpty()) { @@ -119,7 +118,7 @@ class MainActivity : ComponentActivity(), } setContent { - WearApp(this, bpm, alarms, url.value, { token -> accessToken.value = token }, mVibrator, vibrationEffectSingle) + WearApp(this, bpm, alarms, url.value, { token -> accessToken.value = token }, mVibrator, vibrationEffectSingle, accessToken) } } @@ -217,19 +216,43 @@ class MainActivity : ComponentActivity(), val headers = Headers.Builder() .add("Authorization", "Bearer ${accessToken.value}") .build() - Request.makeRequest("${url.value}/api/heart-rate", headers, formBody) {} + Request.makeRequest("${url.value}/api/heart-rate", headers, formBody, Request.Companion.REQUEST_TYPE.POST) {} } } } } @Composable -fun WearApp(context: Context, currentHeartRate: MutableState, alarms: MutableState, apiUrl: String, setAccessToken: (token: String) -> Unit, mVibrator: Vibrator, vibrationEffectSingle: VibrationEffect) { +fun WearApp(context: Context, currentHeartRate: MutableState, alarms: MutableState, apiUrl: String, setAccessToken: (token: String) -> Unit, mVibrator: Vibrator, vibrationEffectSingle: VibrationEffect, accessToken: MutableState) { val navController = rememberSwipeDismissableNavController() val email = LocalStorage.getData(context, EnvEnum.EMAIL.value); val password = LocalStorage.getData(context, EnvEnum.PASSWORD.value); if (email != null && password != null) { Authentication.login(context, apiUrl = apiUrl, email = email, password = password, navController = navController , setAccessToken = setAccessToken) + if (!accessToken.value.isNullOrEmpty()) { + val headers = Headers.Builder() + .add("Authorization", "Bearer ${accessToken.value}") + .add("Accept", "application/json") + .build() + val formBody = FormBody.Builder() + .build() + Request.makeRequest( + "$apiUrl/api/alarmPreferences", + headers, + formBody, + Request.Companion.REQUEST_TYPE.GET + ) { dto -> + run { + val jsonObject = JSONObject(dto) + val dataArray = jsonObject.getJSONArray("data").getJSONObject(0) + alarms.value.isAlarmActivate = dataArray.getString("isAlarmActivate").equals("true") + alarms.value.vibration.isActivate = dataArray.getString("isVibrationActivate").equals("true") + alarms.value.sound.isActivate = dataArray.getString("isSoundActivate").equals("true") + alarms.value.iconId = dataArray.getString("iconId").toInt() + alarms.value.music = dataArray.getString("music") + } + } + } } OwlTheme { @@ -267,7 +290,7 @@ fun WearApp(context: Context, currentHeartRate: MutableState, alarms: Mu contentAlignment = Alignment.Center ) { TimeText() - Settings(context, alarms, mVibrator) + Settings(context, alarms, mVibrator, apiUrl, accessToken.value ) } } composable(PagesEnum.ALARM.value) { diff --git a/app/src/main/java/com/eipsaferoad/owl/api/Request.kt b/app/src/main/java/com/eipsaferoad/owl/api/Request.kt index 8ce5c12..04cc709 100644 --- a/app/src/main/java/com/eipsaferoad/owl/api/Request.kt +++ b/app/src/main/java/com/eipsaferoad/owl/api/Request.kt @@ -11,18 +11,49 @@ import okhttp3.OkHttpClient import okhttp3.Request import org.json.JSONException import org.json.JSONObject +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.toRequestBody class Request { companion object { - private fun post(url: String, headers: Headers, body: FormBody): String { + public enum class REQUEST_TYPE() { + POST, + PUT, + GET, + DELETE + } + + private fun post(url: String, headers: Headers, body: FormBody, requestType: REQUEST_TYPE): String { val client = OkHttpClient() - val request = Request.Builder() - .url(url) - .post(body) - .headers(headers) - .build() + var request: Request + if (requestType == REQUEST_TYPE.POST) { + request = Request.Builder() + .url(url) + .post(body) + .headers(headers) + .build() + } else if (requestType == REQUEST_TYPE.GET) { + request = Request.Builder() + .url(url) + .headers(headers) + .build() + } else if (requestType == REQUEST_TYPE.PUT) { + request = Request.Builder() + .url(url) + .put(body) + .headers(headers) + .build() + } else { + request = Request.Builder() + .url(url) + .delete(body) + .headers(headers) + .build() + } try { val response = client.newCall(request).execute() @@ -35,17 +66,17 @@ class Request { } } - fun makeRequest(url: String, headers: Headers, body: FormBody, callback: (dto: JSONObject) -> Unit) { + fun makeRequest(url: String, headers: Headers, body: FormBody, requestType: REQUEST_TYPE, callback: (dto: String) -> Unit) { CoroutineScope(Dispatchers.Main).launch { try { val response = withContext(Dispatchers.IO) { - post(url, headers, body) + post(url, headers, body, requestType) } withContext(Dispatchers.Main) { try { - callback(JSONObject(response)) + callback(response) } catch (e: JSONException) { - Log.e("API CALL", "Error parsing JSON: $e") + Log.e("API CALL", "Error with response data: $e") } } } catch (e: Exception) { @@ -53,5 +84,63 @@ class Request { } } } + + private fun executeRequest(url: String, headers: Headers, body: String, requestType: REQUEST_TYPE): String { + val client = OkHttpClient() + val requestBody = body.toRequestBody("application/json".toMediaType()) + + val request = when (requestType) { + REQUEST_TYPE.POST -> Request.Builder() + .url(url) + .post(requestBody) + .headers(headers) + .build() + REQUEST_TYPE.PUT -> Request.Builder() + .url(url) + .put(requestBody) + .headers(headers) + .build() + REQUEST_TYPE.GET -> Request.Builder() + .url(url) + .get() + .headers(headers) + .build() + REQUEST_TYPE.DELETE -> Request.Builder() + .url(url) + .delete(requestBody) + .headers(headers) + .build() + } + + try { + val response = client.newCall(request).execute() + if (!response.isSuccessful) { + throw Exception("Error: Request failed with code ${response.code}") + } + return response.body!!.string() + } catch (e: Exception) { + throw e + } + } + + fun makeRequest(url: String, requestType: REQUEST_TYPE, callback: (dto: String) -> Unit, headers: Headers, jsonBody: String) { + + CoroutineScope(Dispatchers.Main).launch { + try { + val response = withContext(Dispatchers.IO) { + executeRequest(url, headers, jsonBody, requestType) + } + withContext(Dispatchers.Main) { + try { + callback(response) + } catch (e: JSONException) { + Log.e("API CALL", "Error with response data: $e") + } + } + } catch (e: Exception) { + Log.e("API CALL", "Error api call: $e") + } + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt b/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt index d247e1c..41611ee 100644 --- a/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt +++ b/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt @@ -8,6 +8,7 @@ import com.eipsaferoad.owl.utils.EnvEnum import com.eipsaferoad.owl.utils.LocalStorage import okhttp3.FormBody import okhttp3.Headers +import org.json.JSONObject class Authentication { companion object { @@ -29,10 +30,11 @@ class Authentication { Request.makeRequest( "$apiUrl/api/auth/login", headers, - formBody + formBody, + Request.Companion.REQUEST_TYPE.POST ) { dto -> run { - val data = dto.getJSONObject("data") + val data = JSONObject(dto).getJSONObject("data") setAccessToken(data.getString("token")) if (isNew) { diff --git a/app/src/main/java/com/eipsaferoad/owl/models/Alarm.kt b/app/src/main/java/com/eipsaferoad/owl/models/Alarm.kt index 442daac..75dfcf5 100644 --- a/app/src/main/java/com/eipsaferoad/owl/models/Alarm.kt +++ b/app/src/main/java/com/eipsaferoad/owl/models/Alarm.kt @@ -1,5 +1,3 @@ package com.eipsaferoad.owl.models -class Alarm(public var vibration: AlarmType, public var sound: AlarmType, public var isAlarmActivate: Boolean) { - -} \ No newline at end of file +class Alarm(var vibration: AlarmType, var sound: AlarmType, var isAlarmActivate: Boolean, var music: String, var iconId: Int) \ No newline at end of file diff --git a/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt b/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt index f9f42e2..88cb0b5 100644 --- a/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt +++ b/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt @@ -45,15 +45,19 @@ import androidx.wear.compose.material.Switch import androidx.wear.compose.material.SwitchDefaults import androidx.wear.compose.material.Text import com.eipsaferoad.owl.R +import com.eipsaferoad.owl.api.Request import com.eipsaferoad.owl.models.Alarm import com.eipsaferoad.owl.models.AlarmType import com.eipsaferoad.owl.presentation.theme.OwlTheme import com.eipsaferoad.owl.utils.EnvEnum import com.eipsaferoad.owl.utils.LocalStorage import com.eipsaferoad.owl.utils.soundPlayer +import okhttp3.FormBody +import okhttp3.Headers +import org.json.JSONObject @Composable -fun Settings(context: Context, alarms: MutableState, mVibrator: Vibrator) { +fun Settings(context: Context, alarms: MutableState, mVibrator: Vibrator, apiUrl: String, accessToken: String?) { LazyColumn( modifier = Modifier @@ -62,14 +66,39 @@ fun Settings(context: Context, alarms: MutableState, mVibrator: Vibrator) verticalArrangement = Arrangement.spacedBy(10.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - item { AlarmButton(context, alarms) } - item { VibrationButton(context, alarms, mVibrator) } - item { SoundButton(alarms, context) } + item { AlarmButton(context, alarms, apiUrl, accessToken) } + item { VibrationButton(context, alarms, mVibrator, apiUrl, accessToken) } + item { SoundButton(alarms, context, apiUrl, accessToken) } } } +fun saveOnServer(apiUrl: String, accessToken: String?, alarms: Alarm) { + val headers = Headers.Builder() + .add("Authorization", "Bearer $accessToken") + .add("Accept", "application/json") + .build() + + val jsonBody = JSONObject().apply { + put("isAlarmActivate", alarms.isAlarmActivate) + put("isVibrationActivate", alarms.vibration.isActivate) + put("vibrationLevel", alarms.vibration.actual.toInt()) + put("isSoundActivate", alarms.sound.isActivate) + put("soundLevel", alarms.sound.actual.toInt()) + put("music", alarms.music) + put("iconId", alarms.iconId) + }.toString() + + Request.makeRequest( + "$apiUrl/api/alarmPreferences", + Request.Companion.REQUEST_TYPE.PUT, + {}, + headers, + jsonBody, + ) +} + @Composable -fun AlarmButton(context: Context, alarms: MutableState) { +fun AlarmButton(context: Context, alarms: MutableState, apiUrl: String, accessToken: String?) { var isAlarmActivate by remember { mutableStateOf(alarms.value.isAlarmActivate) } DisposableEffect(isAlarmActivate) { @@ -104,6 +133,7 @@ fun AlarmButton(context: Context, alarms: MutableState) { checked = isAlarmActivate, onCheckedChange = { alarms.value.isAlarmActivate = it; isAlarmActivate = it + saveOnServer(apiUrl, accessToken, alarms.value) } ) } @@ -111,7 +141,7 @@ fun AlarmButton(context: Context, alarms: MutableState) { } @Composable -fun VibrationButton(context: Context, alarms: MutableState, mVibrator: Vibrator) { +fun VibrationButton(context: Context, alarms: MutableState, mVibrator: Vibrator, apiUrl: String, accessToken: String?) { var isVibrationSelected by remember { mutableStateOf(false) } var isVibrationActivate by remember { mutableStateOf(alarms.value.vibration.isActivate) } var vibrationEffectSingle by remember { @@ -158,6 +188,7 @@ fun VibrationButton(context: Context, alarms: MutableState, mVibrator: Vi checked = isVibrationActivate, onCheckedChange = { alarms.value.vibration.isActivate = it; isVibrationActivate = it + saveOnServer(apiUrl, accessToken, alarms.value) if (it) { mVibrator.vibrate(vibrationEffectSingle) } @@ -169,7 +200,7 @@ fun VibrationButton(context: Context, alarms: MutableState, mVibrator: Vi } @Composable -fun SoundButton(alarms: MutableState, context: Context) { +fun SoundButton(alarms: MutableState, context: Context, apiUrl: String, accessToken: String?) { var isSoundActivate by remember { mutableStateOf(alarms.value.sound.isActivate) } var soundVal by remember { mutableStateOf(alarms.value.sound.actual) } var isVibrationSelected by remember { mutableStateOf(false) } @@ -222,6 +253,7 @@ fun SoundButton(alarms: MutableState, context: Context) { ), checked = isSoundActivate, onCheckedChange = { + saveOnServer(apiUrl, accessToken, alarms.value) alarms.value.sound.isActivate = it; isSoundActivate = it } ) @@ -239,6 +271,7 @@ fun SoundButton(alarms: MutableState, context: Context) { text = "-", modifier = Modifier.clickable { alarms.value.sound.updateAlarm(false) + saveOnServer(apiUrl, accessToken, alarms.value) if (soundVal > alarms.value.sound.min) { soundVal -= 0.2f } @@ -263,6 +296,7 @@ fun SoundButton(alarms: MutableState, context: Context) { modifier = Modifier .clickable { alarms.value.sound.updateAlarm() + saveOnServer(apiUrl, accessToken, alarms.value) if (soundVal < alarms.value.sound.max.toFloat()) { soundVal += 0.2f } diff --git a/app/src/main/res/values-round/strings.xml b/app/src/main/res/values-round/strings.xml index 36bf50e..eb004ce 100644 --- a/app/src/main/res/values-round/strings.xml +++ b/app/src/main/res/values-round/strings.xml @@ -1,3 +1,3 @@ - http://35.181.57.245:5000 + http://20.199.106.94 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 06bfd92..aeb6063 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ owl - http://35.181.57.245:5000 + http://20.199.106.94 \ No newline at end of file