From 1c158449a425eea8d6ca2e2a5e6598f0447d58cd Mon Sep 17 00:00:00 2001 From: Raihan Ariq <202310715297@mhs.ubharajaya.ac.id> Date: Thu, 20 Nov 2025 15:46:11 +0700 Subject: [PATCH] Mengubah Tag sesuai Kiriman User dan Menambahkan Activity baru untuk Jalur Evakuasi --- .../ac/ubharajaya/panicbutton/MainActivity.kt | 173 +++++++++++++++--- 1 file changed, 148 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt index 72ee137..ec60849 100644 --- a/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt +++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/MainActivity.kt @@ -1,18 +1,33 @@ -package com.example.panicbutton +package id.ac.ubharajaya.panicbutton + + +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.material3.Button -import androidx.compose.material3.Text +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody +import java.util.concurrent.locks.Condition class MainActivity : ComponentActivity() { @@ -27,55 +42,163 @@ class MainActivity : ComponentActivity() { @Composable fun MyApp() { - // State untuk menampilkan hasil request + val focusManager = LocalFocusManager.current var message by remember { mutableStateOf("Klik tombol untuk mengirim notifikasi") } + var selectedConditions by remember { mutableStateOf(mutableSetOf()) } + var additionalNotes by remember { mutableStateOf(TextFieldValue("")) } + // Agar bisa Scroll + val scrollState = rememberScrollState() + + val context = LocalContext.current - // UI Column( modifier = Modifier .fillMaxSize() + .verticalScroll(scrollState) .padding(16.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start ) { - Text(text = message, Modifier.padding(bottom = 16.dp)) - Button(onClick = { - // Kirim HTTP request saat tombol ditekan - sendNotification { response -> - message = response + Text( + text = "Terjadi Kondisi Darurat", + fontSize = 20.sp, + color = Color.Red, + modifier = Modifier.padding(bottom = 16.dp) + ) + + listOf( + "Kebakaran", "Banjir", "Tsunami", "Gunung Meletus", + "Gempa Bumi", "Huru hara", "Binatang Buas", + "Radiasi Nuklir", "Biohazard" + ).forEach { condition -> + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + focusManager.clearFocus() + selectedConditions = selectedConditions.toMutableSet().apply { + if (contains(condition)) remove(condition) else add(condition) + } + } + .padding(vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Checkbox( + checked = selectedConditions.contains(condition), + onCheckedChange = { isChecked -> + focusManager.clearFocus() + selectedConditions = selectedConditions.toMutableSet().apply { + if (isChecked) add(condition) else remove(condition) + } + } + ) + Text( + text = condition, + modifier = Modifier.padding(start = 8.dp) + ) } - }) { - Text(text = "Kirim Alert") + } + + Spacer(modifier = Modifier.height(16.dp)) + Text(text = "Catatan tambahan:") + BasicTextField( + value = additionalNotes, + onValueChange = { additionalNotes = it }, + modifier = Modifier + .fillMaxWidth() + .height(100.dp) + .padding(8.dp) + .border(1.dp, Color.Gray), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done) + ) + + Spacer(modifier = Modifier.height(16.dp)) + Button( + onClick = { + val notes = additionalNotes.text + val conditions = selectedConditions.joinToString(", ") + val report = "Kondisi: $conditions\nCatatan: $notes" + sendNotification(conditions, report) { response -> + message = response + } + }, + colors = ButtonDefaults.buttonColors(containerColor = Color.Red) + ) { + Text(text = "Kirim Laporan", color = Color.White) + } + + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "“JANGAN PANIK! SEGERA EVAKUASI\nDIRI ANDA KE TITIK KUMPUL”", + color = Color.Red, + fontSize = 15.sp + ) + + Spacer(modifier = Modifier.height(16.dp)) + Text(text = message, Modifier.padding(top = 16.dp)) + Button( + onClick = { + val intent = Intent(context, JalurEvakuasiActivity::class.java) + context.startActivity(intent) + }, + colors = ButtonDefaults.buttonColors(containerColor = Color.Green) + ) { + Text(text = "Lihat Jalur Evakuasi", color = Color.White) } } } // Fungsi untuk mengirimkan HTTP request -fun sendNotification(onResult: (String) -> Unit) { +fun sendNotification(condition: String, report: String, onResult: (String) -> Unit) { val client = OkHttpClient() - val url = "https://ntfy.ubharajaya.ac.id/panic-button" // Ganti dengan topik Anda + val url = "https://ntfy.ubharajaya.ac.id/panic-button" - - val requestBody = RequestBody.create( - "text/plain".toMediaType(), // Mengirim plain text - "Notifikasi dari Kelompok 1 (Raihan, Dendi, Fazri)!" // Pesan yang akan tampil + // Mapping kondisi → emoji/tag + val tagMapping = mapOf( + "Kebakaran" to "fire", + "Banjir" to "ocean", + "Tsunami" to "ocean", + "Gunung Meletus" to "volcano", + "Gempa Bumi" to "earth_asia", + "Huru hara" to "imp", + "Binatang Buas" to "snake", + "Radiasi Nuklir" to "radioactive", + "Biohazard" to "biohazard" ) + // Bersihkan kondisi: trim + filter + val selectedList = condition + .split(",") + .map { it.trim() } + .filter { it.isNotEmpty() } + // Format ulang kondisi + val cleanConditionText = selectedList.joinToString(", ") + + // Ambil emoji untuk masing-masing kondisi + val emojiTags = selectedList.mapNotNull { tagMapping[it] } + + // Tambahkan default tag: alert + warning + val finalTags = listOf("Alert", "Warning") + emojiTags + val finalReport = "Kondisi: $cleanConditionText\nCatatan: ${report.substringAfter("Catatan:")}" + + val requestBody = RequestBody.create( + "text/plain".toMediaType(), + finalReport + ) val request = Request.Builder() .url(url) - .addHeader("Title", "Radioactive") + .addHeader("Title", "Alert") .addHeader("Priority", "urgent") - .addHeader("Tags", "alert warning,rotating_light") + .addHeader("Tags", "alert warning,radioactive") + .addHeader("Tags", finalTags.joinToString(",")) .post(requestBody) .build() - - // Eksekusi request di thread terpisah Thread { try { val response = client.newCall(request).execute() @@ -88,4 +211,4 @@ fun sendNotification(onResult: (String) -> Unit) { onResult("Error: ${e.message}") } }.start() -} +} \ No newline at end of file