diff --git a/android/build.gradle.kts b/android/build.gradle.kts
index 43414fb..7bb08ca 100644
--- a/android/build.gradle.kts
+++ b/android/build.gradle.kts
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.compose)
+ // necessary for using T.serializer() on a data class
+ alias(libs.plugins.kotlin.serialization)
}
android {
@@ -96,6 +98,7 @@ dependencies {
implementation(libs.androidx.glance.material3)
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.android)
+ implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.activity.compose)
@@ -115,6 +118,10 @@ dependencies {
implementation(libs.androidx.compose.ui.viewbinding)
implementation(libs.androidx.compose.ui.googlefonts)
+ implementation(libs.ktor.client.auth)
+ implementation(libs.ktor.client.core)
+ implementation(libs.ktor.client.cio)
+
debugImplementation(libs.androidx.compose.ui.test.manifest)
androidTestImplementation(libs.junit)
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 676ce5b..6f87e86 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -9,6 +9,8 @@
+
+
insets }
+ var deviceDtoList: List = listOf()
+ viewModel.viewModelScope.launch {
+ val networkClient = NetworkClient()
+ deviceDtoList = networkClient.getDevices()
+ }
+
setContentView(
ComposeView(this).apply {
consumeWindowInsets = false
@@ -79,15 +90,18 @@ class NavActivity : AppCompatActivity() {
JetchatDrawer(
drawerState = drawerState,
selectedMenu = selectedMenu,
+ deviceDtoList = deviceDtoList,
onChatClicked = {
findNavController().popBackStack(R.id.nav_device, false)
val args = Bundle(1)
- args.putString("deviceName", it)
+ args.putString("deviceId", it.access_key)
+ args.putString("name", it.name)
+ args.putString("type", it.type)
findNavController().navigate(R.id.nav_device, args)
scope.launch {
drawerState.close()
}
- selectedMenu = it
+ selectedMenu = it.access_key
},
) {
AndroidViewBinding(ContentMainBinding::inflate)
diff --git a/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatDrawer.kt b/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatDrawer.kt
index d46e26a..490bfd9 100644
--- a/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatDrawer.kt
+++ b/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatDrawer.kt
@@ -56,11 +56,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import xyz.magicalbits.smsremote.R
+import xyz.magicalbits.smsremote.network.NetworkClient
import xyz.magicalbits.smsremote.theme.JetchatTheme
import xyz.magicalbits.smsremote.widget.WidgetReceiver
@Composable
-fun JetchatDrawerContent(onChatClicked: (String) -> Unit, selectedMenu: String = "iPhone XYZ") {
+fun JetchatDrawerContent(onChatClicked: (NetworkClient.DeviceDto) -> Unit, selectedMenu: String = "", deviceDtoList: List = listOf()) {
// Use windowInsetsTopHeight() to add a spacer which pushes the drawer content
// below the status bar (y-axis)
Column {
@@ -68,12 +69,13 @@ fun JetchatDrawerContent(onChatClicked: (String) -> Unit, selectedMenu: String =
DrawerHeader()
DividerItem()
DrawerItemHeader("Devices")
- DeviceItem("Samsung A14", selectedMenu == "Samsung A14") {
- onChatClicked("Samsung A14")
- }
- DeviceItem("iPhone XYZ", selectedMenu == "iPhone XYZ") {
- onChatClicked("iPhone XYZ")
+
+ for (deviceDto in deviceDtoList) {
+ DeviceItem(deviceDto.name, selectedMenu == deviceDto.access_key) {
+ onChatClicked(deviceDto)
+ }
}
+
// DividerItem(modifier = Modifier.padding(horizontal = 28.dp))
if (widgetAddingIsSupported(LocalContext.current)) {
DividerItem(modifier = Modifier.padding(horizontal = 28.dp))
diff --git a/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatScaffold.kt b/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatScaffold.kt
index 257ab78..7cf827f 100644
--- a/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatScaffold.kt
+++ b/android/src/main/kotlin/xyz/magicalbits/smsremote/components/JetchatScaffold.kt
@@ -23,13 +23,15 @@ import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
+import xyz.magicalbits.smsremote.network.NetworkClient
import xyz.magicalbits.smsremote.theme.JetchatTheme
@Composable
fun JetchatDrawer(
drawerState: DrawerState = rememberDrawerState(initialValue = Closed),
selectedMenu: String,
- onChatClicked: (String) -> Unit,
+ deviceDtoList: List,
+ onChatClicked: (NetworkClient.DeviceDto) -> Unit,
content: @Composable () -> Unit,
) {
JetchatTheme {
@@ -44,6 +46,7 @@ fun JetchatDrawer(
JetchatDrawerContent(
onChatClicked = onChatClicked,
selectedMenu = selectedMenu,
+ deviceDtoList = deviceDtoList,
)
}
},
diff --git a/android/src/main/kotlin/xyz/magicalbits/smsremote/data/FakeData.kt b/android/src/main/kotlin/xyz/magicalbits/smsremote/data/FakeData.kt
index defc460..d8a7d86 100644
--- a/android/src/main/kotlin/xyz/magicalbits/smsremote/data/FakeData.kt
+++ b/android/src/main/kotlin/xyz/magicalbits/smsremote/data/FakeData.kt
@@ -87,17 +87,3 @@ val meProfile =
timeZone = "In your timezone",
commonChannels = null,
)
-
-val a14Device =
- DeviceScreenState(
- deviceId = "012345",
- name = "Samsung A14",
- phoneNumbers = listOf("+420123456789", "+420777444111")
- )
-
-val iPhoneDevice =
- DeviceScreenState(
- deviceId = "012345",
- name = "iPhone XYZ",
- phoneNumbers = listOf("+15558881111")
- )
diff --git a/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceFragment.kt b/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceFragment.kt
index d1a6c5c..297d523 100644
--- a/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceFragment.kt
+++ b/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceFragment.kt
@@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
@@ -24,7 +23,6 @@ import xyz.magicalbits.smsremote.components.JetchatAppBar
import xyz.magicalbits.smsremote.theme.JetchatTheme
import kotlin.getValue
import androidx.navigation.findNavController
-import kotlinx.coroutines.launch
class DeviceFragment : Fragment() {
private val viewModel: DeviceViewModel by viewModels()
@@ -33,8 +31,10 @@ class DeviceFragment : Fragment() {
override fun onAttach(context: Context) {
super.onAttach(context)
// Consider using safe args plugin
- val deviceName = arguments?.getString("deviceName")
- viewModel.setDeviceId(deviceName)
+ val deviceId = arguments?.getString("deviceId")
+ val name = arguments?.getString("name")
+ val type = arguments?.getString("type")
+ viewModel.setDeviceData(deviceId, name, type)
}
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
@@ -65,6 +65,7 @@ class DeviceFragment : Fragment() {
JetchatTheme {
if (deviceData == null) {
+ println("calling device error")
DeviceError()
} else {
val navController: NavController = rootView.findNavController()
diff --git a/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceViewModel.kt b/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceViewModel.kt
index 179cada..0eb277e 100644
--- a/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceViewModel.kt
+++ b/android/src/main/kotlin/xyz/magicalbits/smsremote/device/DeviceViewModel.kt
@@ -4,26 +4,39 @@ import androidx.compose.runtime.Immutable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import xyz.magicalbits.smsremote.data.a14Device
-import xyz.magicalbits.smsremote.data.iPhoneDevice
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.launch
+import xyz.magicalbits.smsremote.network.NetworkClient
class DeviceViewModel : ViewModel() {
private var deviceId: String = ""
private val _deviceData = MutableLiveData()
val deviceData: LiveData = _deviceData
- fun setDeviceId(newDeviceId: String?) {
- if (newDeviceId != null) {
+ fun setDeviceData(newDeviceId: String?, name: String?, type: String?) {
+ if (newDeviceId != null && name != null) {
deviceId = newDeviceId
- }
- // placeholder since there's no API reading logic yet
- _deviceData.value =
- if (deviceId == "Samsung A14") {
- a14Device
- } else {
- iPhoneDevice
+ var simCardDtoList: List = listOf()
+ viewModelScope.launch {
+ val networkClient = NetworkClient()
+ simCardDtoList = networkClient.getSimCardsByAccessKey(deviceId)
+ println("sims: $simCardDtoList")
+ }.invokeOnCompletion {
+ // FIXME waiting for the response causes brief moment of DeviceError() before _deviceData is updated ...
+ // a solution: caching SIM phone numbers of all discovered devices locally on startup and updating them
+ // only on startup (implicit behavior) or with a pull-down refresh action (not done yet)
+
+ // placeholder since there's no API reading logic yet
+ _deviceData.value =
+ DeviceScreenState(
+ deviceId = deviceId,
+ name = name,
+ phoneNumbers = simCardDtoList.map { it.phone_number },
+ )
+ println("sims live: ${_deviceData.value!!.phoneNumbers}")
}
+ }
}
}
diff --git a/android/src/main/res/navigation/mobile_navigation.xml b/android/src/main/res/navigation/mobile_navigation.xml
index 84b650c..eac44a3 100644
--- a/android/src/main/res/navigation/mobile_navigation.xml
+++ b/android/src/main/res/navigation/mobile_navigation.xml
@@ -43,6 +43,12 @@
+
+