From 4a89fcea14739a5a34dd405127b64163db24e09c Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Thu, 8 Sep 2022 10:30:33 +0200 Subject: [PATCH] Adding basic structure for the new screen --- .../src/main/res/values/strings.xml | 1 + vector/src/main/AndroidManifest.xml | 1 + .../app/core/di/MavericksViewModelModule.kt | 6 ++ .../v2/details/SessionDetailsAction.kt | 21 ++++++ .../v2/details/SessionDetailsActivity.kt | 52 +++++++++++++++ .../devices/v2/details/SessionDetailsArgs.kt | 25 ++++++++ .../v2/details/SessionDetailsFragment.kt | 64 +++++++++++++++++++ .../v2/details/SessionDetailsViewModel.kt | 60 +++++++++++++++++ .../v2/details/SessionDetailsViewState.kt | 31 +++++++++ .../res/layout/fragment_session_details.xml | 6 ++ 10 files changed, 267 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt create mode 100644 vector/src/main/res/layout/fragment_session_details.xml diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 6a87ce82f4..8ccfd2bf38 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3265,6 +3265,7 @@ Session Last activity %1$s + Session details %s\nis looking a little empty. diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index c55852d7d8..94f2abe78b 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -340,6 +340,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 8bcfd4e422..9d2b6c8196 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -88,6 +88,7 @@ import im.vector.app.features.settings.account.deactivation.DeactivateAccountVie import im.vector.app.features.settings.crosssigning.CrossSigningSettingsViewModel import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheetViewModel import im.vector.app.features.settings.devices.DevicesViewModel +import im.vector.app.features.settings.devices.v2.details.SessionDetailsViewModel import im.vector.app.features.settings.devices.v2.overview.SessionOverviewViewModel import im.vector.app.features.settings.devtools.AccountDataViewModel import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel @@ -641,4 +642,9 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(SessionOverviewViewModel::class) fun sessionOverviewViewModelFactory(factory: SessionOverviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(SessionDetailsViewModel::class) + fun sessionDetailsViewModelFactory(factory: SessionDetailsViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt new file mode 100644 index 0000000000..5c3743add4 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class SessionDetailsAction : VectorViewModelAction diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt new file mode 100644 index 0000000000..101bf1da2e --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.airbnb.mvrx.Mavericks +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.SimpleFragmentActivity + +/** + * Display the details info about a Session. + */ +@AndroidEntryPoint +class SessionDetailsActivity : SimpleFragmentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (isFirstCreation()) { + addFragment( + container = views.container, + fragmentClass = SessionDetailsFragment::class.java, + params = intent.getParcelableExtra(Mavericks.KEY_ARG) + ) + } + } + + companion object { + fun newIntent(context: Context, deviceId: String): Intent { + return Intent(context, SessionDetailsActivity::class.java).apply { + putExtra(Mavericks.KEY_ARG, SessionDetailsArgs(deviceId)) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt new file mode 100644 index 0000000000..97716d7c47 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class SessionDetailsArgs( + val deviceId: String +) : Parcelable diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt new file mode 100644 index 0000000000..278f9eec7a --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import com.airbnb.mvrx.fragmentViewModel +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentSessionDetailsBinding + +/** + * Display the details info about a Session. + */ +@AndroidEntryPoint +class SessionDetailsFragment : + VectorBaseFragment() { + + private val viewModel: SessionDetailsViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSessionDetailsBinding { + return FragmentSessionDetailsBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initToolbar() + } + + private fun initToolbar() { + (activity as? AppCompatActivity) + ?.supportActionBar + ?.setTitle(R.string.device_manager_session_details_title) + } + + /*override fun invalidate() = withState(viewModel) { state -> + if (state.deviceInfo is Success) { + renderSessionDetails(state.deviceInfo.invoke()) + } else { + hideSessionInfo() + } + } + + private fun renderSessionDetails(deviceInfo: DeviceInfo) { + }*/ +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt new file mode 100644 index 0000000000..c2beec2c89 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import com.airbnb.mvrx.MavericksViewModelFactory +import com.airbnb.mvrx.Success +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory +import im.vector.app.core.platform.EmptyViewEvents +import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.settings.devices.v2.overview.GetDeviceFullInfoUseCase +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach + +// TODO add unit tests +class SessionDetailsViewModel @AssistedInject constructor( + @Assisted val initialState: SessionDetailsViewState, + private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase, +) : VectorViewModel(initialState) { + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: SessionDetailsViewState): SessionDetailsViewModel + } + + init { + observeSessionInfo(initialState.deviceId) + } + + private fun observeSessionInfo(deviceId: String) { + getDeviceFullInfoUseCase.execute(deviceId) + .mapNotNull { it.getOrNull() } + .onEach { setState { copy(deviceInfo = Success(it.deviceInfo)) } } + .launchIn(viewModelScope) + } + + override fun handle(action: SessionDetailsAction) { + TODO("Implement when adding the first action") + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt new file mode 100644 index 0000000000..15868d3110 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MavericksState +import com.airbnb.mvrx.Uninitialized +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo + +data class SessionDetailsViewState( + val deviceId: String, + val deviceInfo: Async = Uninitialized, +) : MavericksState { + constructor(args: SessionDetailsArgs) : this( + deviceId = args.deviceId + ) +} diff --git a/vector/src/main/res/layout/fragment_session_details.xml b/vector/src/main/res/layout/fragment_session_details.xml new file mode 100644 index 0000000000..1354408486 --- /dev/null +++ b/vector/src/main/res/layout/fragment_session_details.xml @@ -0,0 +1,6 @@ + + + +