switching the player tracker to a singleton to avoid losing state on rotation

- this means we need to be extra careful about releasing any listeners
This commit is contained in:
Adam Brown 2021-11-24 12:00:36 +00:00
parent 32441eb81b
commit 755e3fe932
4 changed files with 16 additions and 22 deletions

View File

@ -42,6 +42,7 @@ import im.vector.app.features.home.UnknownDeviceDetectorSharedViewModel
import im.vector.app.features.home.UnreadMessagesSharedViewModel import im.vector.app.features.home.UnreadMessagesSharedViewModel
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel
import im.vector.app.features.home.room.detail.RoomDetailViewModel import im.vector.app.features.home.room.detail.RoomDetailViewModel
import im.vector.app.features.home.room.detail.composer.MessageComposerViewModel
import im.vector.app.features.home.room.detail.search.SearchViewModel import im.vector.app.features.home.room.detail.search.SearchViewModel
import im.vector.app.features.home.room.detail.timeline.action.MessageActionsViewModel import im.vector.app.features.home.room.detail.timeline.action.MessageActionsViewModel
import im.vector.app.features.home.room.detail.timeline.edithistory.ViewEditHistoryViewModel import im.vector.app.features.home.room.detail.timeline.edithistory.ViewEditHistoryViewModel
@ -508,6 +509,11 @@ interface MavericksViewModelModule {
@MavericksViewModelKey(RoomDetailViewModel::class) @MavericksViewModelKey(RoomDetailViewModel::class)
fun roomDetailViewModelFactory(factory: RoomDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *> fun roomDetailViewModelFactory(factory: RoomDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(MessageComposerViewModel::class)
fun messageComposerViewModelFactory(factory: MessageComposerViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds @Binds
@IntoMap @IntoMap
@MavericksViewModelKey(SetIdentityServerViewModel::class) @MavericksViewModelKey(SetIdentityServerViewModel::class)

View File

@ -240,7 +240,6 @@ class RoomDetailFragment @Inject constructor(
autoCompleterFactory: AutoCompleter.Factory, autoCompleterFactory: AutoCompleter.Factory,
private val permalinkHandler: PermalinkHandler, private val permalinkHandler: PermalinkHandler,
private val notificationDrawerManager: NotificationDrawerManager, private val notificationDrawerManager: NotificationDrawerManager,
val messageComposerViewModelFactory: MessageComposerViewModel.Factory,
private val eventHtmlRenderer: EventHtmlRenderer, private val eventHtmlRenderer: EventHtmlRenderer,
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val colorProvider: ColorProvider, private val colorProvider: ColorProvider,
@ -393,8 +392,8 @@ class RoomDetailFragment @Inject constructor(
when (mode) { when (mode) {
is SendMode.Regular -> renderRegularMode(mode.text) is SendMode.Regular -> renderRegularMode(mode.text)
is SendMode.Edit -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_edit, R.string.edit, mode.text) is SendMode.Edit -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_edit, R.string.edit, mode.text)
is SendMode.Quote -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_quote, R.string.quote, mode.text) is SendMode.Quote -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_quote, R.string.quote, mode.text)
is SendMode.Reply -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_reply, R.string.reply, mode.text) is SendMode.Reply -> renderSpecialMode(mode.timelineEvent, R.drawable.ic_reply, R.string.reply, mode.text)
} }
} }
@ -1130,9 +1129,8 @@ class RoomDetailFragment @Inject constructor(
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
notificationDrawerManager.setCurrentRoom(null) notificationDrawerManager.setCurrentRoom(null)
voiceMessagePlaybackTracker.unTrack(VoiceMessagePlaybackTracker.RECORDING_ID)
messageComposerViewModel.handle(MessageComposerAction.SaveDraft(views.composerLayout.text.toString())) messageComposerViewModel.handle(MessageComposerAction.SaveDraft(views.composerLayout.text.toString()))
// We should improve the UX to support going into playback mode when paused and delete the media when the view is destroyed. // We should improve the UX to support going into playback mode when paused and delete the media when the view is destroyed.

View File

@ -23,6 +23,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
@ -764,23 +766,10 @@ class MessageComposerViewModel @AssistedInject constructor(
} }
@AssistedFactory @AssistedFactory
interface Factory { interface Factory : MavericksAssistedViewModelFactory<MessageComposerViewModel, MessageComposerViewState> {
fun create(initialState: MessageComposerViewState): MessageComposerViewModel override fun create(initialState: MessageComposerViewState): MessageComposerViewModel
} }
/** companion object : MavericksViewModelFactory<MessageComposerViewModel, MessageComposerViewState> by hiltMavericksViewModelFactory()
* We're unable to create this ViewModel with `by hiltMavericksViewModelFactory()` due to the
* VoiceMessagePlaybackTracker being ActivityScoped
*
* This factory allows us to provide the ViewModel instance from the Fragment directly
* bypassing the Singleton scope requirement
*/
companion object : MavericksViewModelFactory<MessageComposerViewModel, MessageComposerViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: MessageComposerViewState): MessageComposerViewModel {
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.messageComposerViewModelFactory.create(state)
}
}
} }

View File

@ -20,8 +20,9 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import dagger.hilt.android.scopes.ActivityScoped import dagger.hilt.android.scopes.ActivityScoped
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton
@ActivityScoped @Singleton
class VoiceMessagePlaybackTracker @Inject constructor() { class VoiceMessagePlaybackTracker @Inject constructor() {
private val mainHandler = Handler(Looper.getMainLooper()) private val mainHandler = Handler(Looper.getMainLooper())