Skip to content

Commit cd645cc

Browse files
committed
[FEAT] Functionality to change port and logout
1 parent ca221a9 commit cd645cc

5 files changed

Lines changed: 87 additions & 33 deletions

File tree

app/src/main/java/com/example/blockchainaccess/CreatePofileActivity.kt renamed to app/src/main/java/com/example/blockchainaccess/CreateProfileActivity.kt

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import androidx.compose.material3.MaterialTheme
1616
import androidx.compose.material3.Scaffold
1717
import androidx.compose.material3.Text
1818
import androidx.compose.material3.Button
19+
import androidx.compose.material3.DropdownMenu
20+
import androidx.compose.material3.DropdownMenuItem
1921
import androidx.compose.material3.TextField
2022
import androidx.compose.runtime.Composable
2123
import androidx.compose.ui.graphics.Color
@@ -61,6 +63,8 @@ fun CreateProfileScreen(name: String, modifier: Modifier = Modifier) {
6163
var username by remember { mutableStateOf("") }
6264
var password by remember { mutableStateOf("") }
6365
var repeatPassword by remember { mutableStateOf("") }
66+
var selectedPort by remember { mutableStateOf("8081") }
67+
var showPortDropdown by remember { mutableStateOf(false) }
6468
Scaffold {
6569
Box(
6670
modifier = modifier
@@ -135,7 +139,7 @@ fun CreateProfileScreen(name: String, modifier: Modifier = Modifier) {
135139
)
136140
Spacer(modifier = Modifier.height(34.dp))
137141
Button(
138-
onClick = { register(context, username,password,repeatPassword,coroutineScope) },
142+
onClick = { register(context, username,password,repeatPassword,selectedPort, coroutineScope) },
139143
shape = RoundedCornerShape(50),
140144
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
141145
elevation = ButtonDefaults.buttonElevation(defaultElevation = 6.dp),
@@ -146,6 +150,35 @@ fun CreateProfileScreen(name: String, modifier: Modifier = Modifier) {
146150
Text("Create Profile", color = Color.White)
147151
}
148152
}
153+
Box(
154+
modifier = Modifier
155+
.align(Alignment.BottomStart)
156+
.padding(16.dp)
157+
) {
158+
Button(onClick = { showPortDropdown = true }) {
159+
Text(text = "Port: $selectedPort")
160+
}
161+
DropdownMenu(
162+
expanded = showPortDropdown,
163+
onDismissRequest = { showPortDropdown = false }
164+
) {
165+
val ports = listOf("8081", "8082", "8083", "8084")
166+
ports.forEach { port ->
167+
DropdownMenuItem(
168+
text = { Text(port) },
169+
onClick = {
170+
selectedPort = port
171+
showPortDropdown = false
172+
// Reset session when port changes
173+
coroutineScope.launch {
174+
SessionManager.clearSession(context)
175+
}
176+
Toast.makeText(context, "Session reset. Please log in again.", Toast.LENGTH_SHORT).show()
177+
}
178+
)
179+
}
180+
}
181+
}
149182
}
150183
}
151184
}
@@ -163,6 +196,7 @@ fun register(
163196
username: String,
164197
password: String,
165198
repeatPassword: String,
199+
port: String,
166200
coroutineScope: CoroutineScope
167201
) {
168202
if (username.isBlank() || password.isBlank() || repeatPassword.isBlank()) {
@@ -178,15 +212,15 @@ fun register(
178212
// Launch a coroutine to handle the asynchronous network request
179213
coroutineScope.launch(Dispatchers.IO) {
180214
// The network request is made here, on a background thread.
181-
val result = NetworkClient.createAndRegisterProfile(username, password)
215+
val result = NetworkClient.createAndRegisterProfile(username, password, port)
182216

183217
// Switch back to the main thread to update UI or navigate
184218
withContext(Dispatchers.Main) {
185219
result.fold(
186220
onSuccess = { (id, whitelist) ->
187221
Toast.makeText(context, "Profile created successfully!", Toast.LENGTH_SHORT).show()
188222

189-
SessionManager.saveSession(context, id, username)
223+
SessionManager.saveSession(context, id, username, port)
190224

191225
SessionManager.saveWhitelist(context, whitelist)
192226

app/src/main/java/com/example/blockchainaccess/NetworkClient.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ object NetworkClient {
4444
val userId: String,
4545
)
4646

47-
suspend fun addWhitelistEntry(userId: String): Result<Unit> {
47+
suspend fun addWhitelistEntry(userId: String, port: String): Result<Unit> {
4848
return try {
49-
val url = "http://192.168.0.198:8081/new_whitelist_entry"
49+
val url = "http://192.168.0.198:$port/new_whitelist_entry"
5050
val response = client.post(url) {
5151
contentType(ContentType.Application.Json)
5252
setBody(WhitelistEntryRequest(userId))
@@ -62,9 +62,9 @@ object NetworkClient {
6262
}
6363
}
6464

65-
suspend fun removeWhitelistEntry(userId: String): Result<Unit> {
65+
suspend fun removeWhitelistEntry(userId: String, port: String): Result<Unit> {
6666
return try {
67-
val url = "http://192.168.0.198:8081/remove_whitelist_entry"
67+
val url = "http://192.168.0.198:$port/remove_whitelist_entry"
6868
val response = client.post(url) {
6969
contentType(ContentType.Application.Json)
7070
setBody(WhitelistEntryRequest(userId))
@@ -80,9 +80,9 @@ object NetworkClient {
8080
}
8181
}
8282

83-
suspend fun createAndRegisterProfile(username: String, password: String): Result<Pair<String, Set<String>>> {
83+
suspend fun createAndRegisterProfile(username: String, password: String, port: String): Result<Pair<String, Set<String>>> {
8484
try {
85-
val createProfileUrl = "http://192.168.0.198:8081/login"
85+
val createProfileUrl = "http://10.0.2.2:$port/login"
8686
val response: HttpResponse = client.post(createProfileUrl) {
8787
contentType(ContentType.Application.Json)
8888
setBody(CreateProfileRequest(username, password))
@@ -100,10 +100,9 @@ object NetworkClient {
100100

101101
val generatedId = creationResponse.id
102102
val whitelist = creationResponse.whitelist
103-
104103
println("Profile created. ID: $generatedId")
105104
// --- Step 2: Register user ID with 127.0.0.1:8081 ---
106-
val registerUrl = "http://192.168.0.198:8081/app_save_id"
105+
val registerUrl = "http://10.0.2.2:$port/app_save_id"
107106
val registerResponse: HttpResponse = client.post(registerUrl) {
108107
contentType(ContentType.Application.Json)
109108
setBody(UpdateUserRequest(generatedId))

app/src/main/java/com/example/blockchainaccess/SessionManager.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ object SessionManager {
1818
private val USER_ID = stringPreferencesKey("user_id")
1919
private val USERNAME = stringPreferencesKey("username")
2020

21+
private val PORT = stringPreferencesKey("port")
2122
private val WHITELIST = stringSetPreferencesKey("whitelist")
2223

23-
suspend fun saveSession(context: Context, userId: String, username: String) {
24+
suspend fun saveSession(context: Context, userId: String, username: String, port: String) {
2425
context.dataStore.edit { prefs ->
2526
prefs[IS_LOGGED_IN] = true
2627
prefs[USER_ID] = userId
28+
prefs[PORT] = port
2729
prefs[USERNAME] = username
2830
}
2931
}
@@ -42,13 +44,14 @@ object SessionManager {
4244
return context.dataStore.data.map { it[USER_ID] }.first()
4345
}
4446

47+
4548
suspend fun getUsername(context: Context): String? {
4649
return context.dataStore.data.map { it[USERNAME] }.first()
4750
}
4851

49-
suspend fun addToWhitelist(context: Context, userId: String) {
52+
suspend fun addToWhitelist(context: Context, userId: String, port: String) {
5053

51-
val result = NetworkClient.addWhitelistEntry(userId)
54+
val result = NetworkClient.addWhitelistEntry(userId, port)
5255

5356
result.fold(
5457
onSuccess = {
@@ -63,9 +66,9 @@ object SessionManager {
6366
)
6467
}
6568

66-
suspend fun removeFromWhitelist(context: Context, userId: String) {
69+
suspend fun removeFromWhitelist(context: Context, userId: String, port: String) {
6770

68-
val result = NetworkClient.removeWhitelistEntry(userId)
71+
val result = NetworkClient.removeWhitelistEntry(userId, port)
6972

7073
result.fold(
7174
onSuccess = {
@@ -86,7 +89,11 @@ object SessionManager {
8689
}
8790
}
8891

89-
92+
fun getPort(context: Context): Flow<String> {
93+
return context.dataStore.data.map { prefs ->
94+
prefs[PORT] ?: ""
95+
}
96+
}
9097
fun getWhitelist(context: Context): Flow<Set<String>> {
9198
return context.dataStore.data.map { prefs ->
9299
prefs[WHITELIST] ?: emptySet()

app/src/main/java/com/example/blockchainaccess/UserActivity.kt

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.blockchainaccess
22

3+
import android.annotation.SuppressLint
34
import android.os.Bundle
45
import android.content.Intent
56
import androidx.activity.ComponentActivity
@@ -39,11 +40,6 @@ import androidx.compose.ui.graphics.BlendMode
3940
import androidx.compose.foundation.clickable
4041

4142

42-
43-
object NfcDataHolder {
44-
var userId: String = "unknown-user"
45-
}
46-
4743
class UserActivity : ComponentActivity() {
4844
override fun onCreate(savedInstanceState: Bundle?) {
4945
super.onCreate(savedInstanceState)
@@ -71,9 +67,11 @@ class UserActivity : ComponentActivity() {
7167
}
7268
}
7369

70+
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
7471
@Composable
7572
fun UserScreen(name: String, modifier: Modifier = Modifier) {
7673
val context = LocalContext.current
74+
val coroutineScope = rememberCoroutineScope()
7775
var userId by remember { mutableStateOf("Loading...") }
7876
var username by remember { mutableStateOf("Loading...") }
7977
var clicked by remember { mutableStateOf(false) }
@@ -171,13 +169,14 @@ fun UserScreen(name: String, modifier: Modifier = Modifier) {
171169
.height(160.dp)
172170
.clip(RoundedCornerShape(12.dp)) // clip the shape so background doesn't overflow
173171
.background(gradient)
174-
.clickable { clicked = !clicked
175-
saveUserIdForNfc(context, userId)
176-
val intent = Intent(context, MyHostApduService::class.java).apply {
177-
putExtra("NFC_USER_ID", userId)
178-
}
179-
context.startService(intent)
180-
},
172+
.clickable {
173+
clicked = !clicked
174+
saveUserIdForNfc(context, userId)
175+
val intent = Intent(context, MyHostApduService::class.java).apply {
176+
putExtra("NFC_USER_ID", userId)
177+
}
178+
context.startService(intent)
179+
},
181180
contentAlignment = Alignment.Center
182181
) {
183182
Image(
@@ -211,7 +210,7 @@ fun UserScreen(name: String, modifier: Modifier = Modifier) {
211210
shape = RoundedCornerShape(12.dp)
212211
),
213212
contentAlignment = Alignment.Center
214-
){
213+
) {
215214
Text(
216215
text = "Logs",
217216
fontSize = 18.sp,
@@ -247,8 +246,22 @@ fun UserScreen(name: String, modifier: Modifier = Modifier) {
247246
}
248247
}
249248
}
249+
Box(
250+
modifier = Modifier
251+
.align(Alignment.BottomStart)
252+
.padding(16.dp)
253+
) {
254+
Button(onClick = { coroutineScope.launch {
255+
SessionManager.clearSession(context)
256+
val intent = Intent(context, CreateProfileActivity::class.java).apply {
257+
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
258+
}
259+
context.startActivity(intent)
260+
} }) {
261+
Text(text = "Logout")
262+
}
263+
}
250264
}
251-
252265
}
253266

254267
fun saveUserIdForNfc(context: Context, userId: String) {

app/src/main/java/com/example/blockchainaccess/WhitelistActivity.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ fun WhitelistScreen(modifier: Modifier = Modifier) {
5858
// Collect the whitelist Flow as state. The UI will automatically
5959
// recompose whenever the whitelist changes.
6060
val whitelist by SessionManager.getWhitelist(context).collectAsState(initial = emptySet())
61+
val port by SessionManager.getPort(context).collectAsState(initial = "")
6162

6263
// State for the text field
6364
var newId by remember { mutableStateOf("") }
@@ -84,7 +85,7 @@ fun WhitelistScreen(modifier: Modifier = Modifier) {
8485
Button(onClick = {
8586
if (newId.isNotBlank()) {
8687
scope.launch {
87-
SessionManager.addToWhitelist(context, newId)
88+
SessionManager.addToWhitelist(context, newId, port)
8889
newId = "" // Clear the text field
8990
}
9091
}
@@ -105,7 +106,7 @@ fun WhitelistScreen(modifier: Modifier = Modifier) {
105106
id = id,
106107
onRemove = {
107108
scope.launch {
108-
SessionManager.removeFromWhitelist(context, id)
109+
SessionManager.removeFromWhitelist(context, id, port)
109110
}
110111
}
111112
)

0 commit comments

Comments
 (0)