diff --git a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt index b2de087fd..7ee2c4d7f 100644 --- a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt @@ -326,19 +326,15 @@ class RadioConfigViewModel @Inject constructor( fun removeFixedPosition() = setFixedPosition(Position(0.0, 0.0, 0)) - private val _deviceProfile = MutableStateFlow(null) - val deviceProfile: StateFlow get() = _deviceProfile - - fun setDeviceProfile(deviceProfile: DeviceProfile?) { - _deviceProfile.value = deviceProfile - } - - fun importProfile(uri: Uri) = viewModelScope.launch(Dispatchers.IO) { + fun importProfile( + uri: Uri, + onResult: (DeviceProfile) -> Unit, + ) = viewModelScope.launch(Dispatchers.IO) { try { app.contentResolver.openInputStream(uri).use { inputStream -> val bytes = inputStream?.readBytes() val protobuf = DeviceProfile.parseFrom(bytes) - _deviceProfile.value = protobuf + onResult(protobuf) } } catch (ex: Exception) { errormsg("Import DeviceProfile error: ${ex.message}") @@ -346,10 +342,8 @@ class RadioConfigViewModel @Inject constructor( } } - fun exportProfile(uri: Uri) = viewModelScope.launch { - val profile = deviceProfile.value ?: return@launch + fun exportProfile(uri: Uri, profile: DeviceProfile) = viewModelScope.launch { writeToUri(uri, profile) - _deviceProfile.value = null } private suspend fun writeToUri(uri: Uri, message: MessageLite) = withContext(Dispatchers.IO) { @@ -367,15 +361,17 @@ class RadioConfigViewModel @Inject constructor( } fun installProfile(protobuf: DeviceProfile) = with(protobuf) { - _deviceProfile.value = null meshService?.beginEditSettings() - if (hasLongName() || hasShortName()) destNode.value?.user?.let { - val user = MeshProtos.User.newBuilder() - .setLongName(if (hasLongName()) longName else it.longName) - .setShortName(if (hasShortName()) shortName else it.shortName) - .setIsLicensed(it.isLicensed) - .build() - setOwner(user) + if (hasLongName() || hasShortName()) { + destNode.value?.user?.let { + val user = MeshProtos.User.newBuilder() + .setId(it.id) + .setLongName(if (hasLongName()) longName else it.longName) + .setShortName(if (hasShortName()) shortName else it.shortName) + .setIsLicensed(it.isLicensed) + .build() + setOwner(user) + } } if (hasChannelUrl()) try { setChannels(channelUrl) diff --git a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt index 9977d96f8..e7d478c89 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt @@ -59,6 +59,7 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile import com.geeksville.mesh.Position import com.geeksville.mesh.R import com.geeksville.mesh.android.Logging @@ -544,7 +545,7 @@ fun RadioConfigScreen( val isLocal = node?.num == viewModel.myNodeNum val isWaiting = radioConfigState.responseState.isWaiting() - val deviceProfile by viewModel.deviceProfile.collectAsStateWithLifecycle() + var deviceProfile by remember { mutableStateOf(null) } var showEditDeviceProfileDialog by remember { mutableStateOf(false) } val importConfigLauncher = rememberLauncherForActivityResult( @@ -552,7 +553,9 @@ fun RadioConfigScreen( ) { if (it.resultCode == Activity.RESULT_OK) { showEditDeviceProfileDialog = true - it.data?.data?.let { uri -> viewModel.importProfile(uri) } + it.data?.data?.let { uri -> + viewModel.importProfile(uri) { profile -> deviceProfile = profile } + } } } @@ -560,7 +563,7 @@ fun RadioConfigScreen( ActivityResultContracts.StartActivityForResult() ) { if (it.resultCode == Activity.RESULT_OK) { - it.data?.data?.let { uri -> viewModel.exportProfile(uri) } + it.data?.data?.let { uri -> viewModel.exportProfile(uri, deviceProfile!!) } } } @@ -573,7 +576,7 @@ fun RadioConfigScreen( if (deviceProfile != null) { viewModel.installProfile(it) } else { - viewModel.setDeviceProfile(it) + deviceProfile = it val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/*" @@ -584,7 +587,7 @@ fun RadioConfigScreen( }, onDismiss = { showEditDeviceProfileDialog = false - viewModel.setDeviceProfile(null) + deviceProfile = null } ) } @@ -616,7 +619,7 @@ fun RadioConfigScreen( }, onImport = { viewModel.clearPacketResponse() - viewModel.setDeviceProfile(null) + deviceProfile = null val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/*" @@ -625,7 +628,7 @@ fun RadioConfigScreen( }, onExport = { viewModel.clearPacketResponse() - viewModel.setDeviceProfile(null) + deviceProfile = null showEditDeviceProfileDialog = true }, )