Skip to content

Commit

Permalink
17 alarm api call (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRealPad committed May 2, 2024
2 parents 12aab1d + 5b75cf5 commit 247f6c1
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 31 deletions.
37 changes: 30 additions & 7 deletions app/src/main/java/com/eipsaferoad/owl/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -72,7 +73,7 @@ class MainActivity : ComponentActivity(),
private lateinit var mVibrator: Vibrator
private lateinit var vibrationEffectSingle: VibrationEffect
private var bpm: MutableState<String> = mutableStateOf("0")
private var alarms: MutableState<Alarm> = mutableStateOf(Alarm(VibrationAlarm(), SoundAlarm(1, 0), false))
private var alarms: MutableState<Alarm> = mutableStateOf(Alarm(VibrationAlarm(), SoundAlarm(1, 0), false, "", 0))
private var accessToken: MutableState<String?> = mutableStateOf(null)
private var url: MutableState<String> = mutableStateOf("")
private var activityContext: Context? = null
Expand Down Expand Up @@ -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()) {
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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<String>, alarms: MutableState<Alarm>, apiUrl: String, setAccessToken: (token: String) -> Unit, mVibrator: Vibrator, vibrationEffectSingle: VibrationEffect) {
fun WearApp(context: Context, currentHeartRate: MutableState<String>, alarms: MutableState<Alarm>, apiUrl: String, setAccessToken: (token: String) -> Unit, mVibrator: Vibrator, vibrationEffectSingle: VibrationEffect, accessToken: MutableState<String?>) {
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 {
Expand Down Expand Up @@ -267,7 +290,7 @@ fun WearApp(context: Context, currentHeartRate: MutableState<String>, alarms: Mu
contentAlignment = Alignment.Center
) {
TimeText()
Settings(context, alarms, mVibrator)
Settings(context, alarms, mVibrator, apiUrl, accessToken.value )
}
}
composable(PagesEnum.ALARM.value) {
Expand Down
109 changes: 99 additions & 10 deletions app/src/main/java/com/eipsaferoad/owl/api/Request.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -35,23 +66,81 @@ 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) {
Log.e("API CALL", "Error api call in: $e")
}
}
}

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")
}
}
}
}
}
6 changes: 4 additions & 2 deletions app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/java/com/eipsaferoad/owl/models/Alarm.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package com.eipsaferoad.owl.models

class Alarm(public var vibration: AlarmType, public var sound: AlarmType, public var isAlarmActivate: Boolean) {

}
class Alarm(var vibration: AlarmType, var sound: AlarmType, var isAlarmActivate: Boolean, var music: String, var iconId: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -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<Alarm>, mVibrator: Vibrator) {
fun Settings(context: Context, alarms: MutableState<Alarm>, mVibrator: Vibrator, apiUrl: String, accessToken: String?) {

LazyColumn(
modifier = Modifier
Expand All @@ -62,14 +66,39 @@ fun Settings(context: Context, alarms: MutableState<Alarm>, 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<Alarm>) {
fun AlarmButton(context: Context, alarms: MutableState<Alarm>, apiUrl: String, accessToken: String?) {
var isAlarmActivate by remember { mutableStateOf(alarms.value.isAlarmActivate) }

DisposableEffect(isAlarmActivate) {
Expand Down Expand Up @@ -104,14 +133,15 @@ fun AlarmButton(context: Context, alarms: MutableState<Alarm>) {
checked = isAlarmActivate,
onCheckedChange = {
alarms.value.isAlarmActivate = it; isAlarmActivate = it
saveOnServer(apiUrl, accessToken, alarms.value)
}
)
}
}
}

@Composable
fun VibrationButton(context: Context, alarms: MutableState<Alarm>, mVibrator: Vibrator) {
fun VibrationButton(context: Context, alarms: MutableState<Alarm>, 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 {
Expand Down Expand Up @@ -158,6 +188,7 @@ fun VibrationButton(context: Context, alarms: MutableState<Alarm>, mVibrator: Vi
checked = isVibrationActivate,
onCheckedChange = {
alarms.value.vibration.isActivate = it; isVibrationActivate = it
saveOnServer(apiUrl, accessToken, alarms.value)
if (it) {
mVibrator.vibrate(vibrationEffectSingle)
}
Expand All @@ -169,7 +200,7 @@ fun VibrationButton(context: Context, alarms: MutableState<Alarm>, mVibrator: Vi
}

@Composable
fun SoundButton(alarms: MutableState<Alarm>, context: Context) {
fun SoundButton(alarms: MutableState<Alarm>, 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) }
Expand Down Expand Up @@ -222,6 +253,7 @@ fun SoundButton(alarms: MutableState<Alarm>, context: Context) {
),
checked = isSoundActivate,
onCheckedChange = {
saveOnServer(apiUrl, accessToken, alarms.value)
alarms.value.sound.isActivate = it; isSoundActivate = it
}
)
Expand All @@ -239,6 +271,7 @@ fun SoundButton(alarms: MutableState<Alarm>, 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
}
Expand All @@ -263,6 +296,7 @@ fun SoundButton(alarms: MutableState<Alarm>, context: Context) {
modifier = Modifier
.clickable {
alarms.value.sound.updateAlarm()
saveOnServer(apiUrl, accessToken, alarms.value)
if (soundVal < alarms.value.sound.max.toFloat()) {
soundVal += 0.2f
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-round/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<resources>
<string name="api_url">http://35.181.57.245:5000</string>
<string name="api_url">http://20.199.106.94</string>
</resources>
Loading

0 comments on commit 247f6c1

Please sign in to comment.