From 48d1205ba8a6a2103422522c11772113adc1a33a Mon Sep 17 00:00:00 2001
From: Raihan Ariq <202310715297@mhs.ubharajaya.ac.id>
Date: Thu, 20 Nov 2025 15:38:38 +0700
Subject: [PATCH] Mengubah Tag sesuai Kiriman User dan Menambahkan Activity
baru untuk Jalur Evakuasi
---
app/build.gradle.kts | 1 +
app/src/main/AndroidManifest.xml | 5 +-
.../panicbutton/JalurEvakuasiActivity.kt | 62 +++++++
.../ac/ubharajaya/panicbutton/MainActivity.kt | 170 +++++++++++++++---
gradle/libs.versions.toml | 2 +
5 files changed, 215 insertions(+), 25 deletions(-)
create mode 100644 app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d34120c..2c0511f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -50,6 +50,7 @@ dependencies {
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
+ implementation(libs.androidx.compose.foundation)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96d3b3c..8bac809 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,16 +17,19 @@
android:theme="@style/Theme.PanicButton">
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt b/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt
new file mode 100644
index 0000000..b6e793b
--- /dev/null
+++ b/app/src/main/java/id/ac/ubharajaya/panicbutton/JalurEvakuasiActivity.kt
@@ -0,0 +1,62 @@
+package id.ac.ubharajaya.panicbutton
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+class JalurEvakuasiActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ JalurEvakuasiScreen(onClose = { finish() })
+ }
+ }
+}
+
+@Composable
+fun JalurEvakuasiScreen(onClose: () -> Unit) {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(
+ text = "Jalur Evakuasi",
+ fontSize = 20.sp,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ // Menampilkan gambar denah
+ Image(
+ painter = painterResource(id = R.drawable.jalur_evakuasi),
+ contentDescription = "Denah Jalur Evakuasi",
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(450.dp)
+ )
+
+ Spacer(modifier = Modifier.height(20.dp))
+
+ // Tombol Close
+ Button(
+ onClick = { onClose() },
+ colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
+ ) {
+ Text(text = "Close", color = Color.White)
+ }
+ }
+}
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..c2ac500 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,162 @@ 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", finalTags.joinToString(","))
.post(requestBody)
.build()
-
- // Eksekusi request di thread terpisah
Thread {
try {
val response = client.newCall(request).execute()
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index f649454..eedd36e 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -8,6 +8,7 @@ espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.9.4"
activityCompose = "1.11.0"
composeBom = "2024.09.00"
+foundation = "1.9.4"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -24,6 +25,7 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
+androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundation" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }