Dagger: continue working on app side. Now compile but some DI are not branched yet.

This commit is contained in:
ganfra 2019-06-19 19:40:59 +02:00
parent 9c1f870694
commit ee87c253fe
46 changed files with 406 additions and 240 deletions

View File

@ -17,6 +17,7 @@
package im.vector.matrix.rx

import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary
import io.reactivex.Observable

@ -30,6 +31,10 @@ class RxRoom(private val room: Room) {
return room.getRoomMemberIdsLive().asObservable()
}

fun liveAnnotationSummary(eventId: String): Observable<List<EventAnnotationsSummary>> {
return room.getEventSummaryLive(eventId).asObservable()
}

}

fun Room.rx(): RxRoom {

View File

@ -31,6 +31,7 @@ import com.github.piasy.biv.BigImageViewer
import com.github.piasy.biv.loader.glide.GlideImageLoader
import com.jakewharton.threetenabp.AndroidThreeTen
import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.core.di.DaggerVectorComponent
import im.vector.riotredesign.core.di.HasInjector
import im.vector.riotredesign.core.di.VectorComponent
import im.vector.riotredesign.features.configuration.VectorConfiguration
@ -53,6 +54,8 @@ class VectorApplication : Application(), HasInjector<VectorComponent> {
override fun onCreate() {
super.onCreate()
appContext = this
vectorComponent = DaggerVectorComponent.factory().create(this)
vectorComponent.inject(this)
VectorUncaughtExceptionHandler.activate(this)
// Log
VectorFileLogger.init(this)

View File

@ -20,13 +20,32 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import dagger.BindsInstance
import dagger.Component
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyFragment
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreSuccessFragment
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupStep1Fragment
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupStep2Fragment
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupStep3Fragment
import im.vector.riotredesign.features.crypto.verification.SASVerificationIncomingFragment
import im.vector.riotredesign.features.home.HomeActivity
import im.vector.riotredesign.features.home.HomeDetailFragment
import im.vector.riotredesign.features.home.HomeDrawerFragment
import im.vector.riotredesign.features.home.HomeModule
import im.vector.riotredesign.features.home.group.GroupListFragment
import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageActionsBottomSheet
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageMenuFragment
import im.vector.riotredesign.features.home.room.detail.timeline.action.QuickReactionFragment
import im.vector.riotredesign.features.home.room.detail.timeline.action.ViewReactionBottomSheet
import im.vector.riotredesign.features.home.room.list.RoomListFragment
import im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity
import im.vector.riotredesign.features.roomdirectory.PublicRoomsFragment
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomFragment
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerFragment
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment
import im.vector.riotredesign.features.settings.VectorSettingsActivity

@Component(dependencies = [VectorComponent::class], modules = [ViewModelModule::class, HomeModule::class])
@ScreenScope
@ -40,12 +59,51 @@ interface ScreenComponent {

fun inject(roomDetailFragment: RoomDetailFragment)

fun inject(roomListFragment: RoomListFragment)

fun inject(groupListFragment: GroupListFragment)

fun inject(roomDirectoryPickerFragment: RoomDirectoryPickerFragment)

fun inject(roomPreviewNoPreviewFragment: RoomPreviewNoPreviewFragment)
fun inject(keysBackupSettingsFragment: KeysBackupSettingsFragment)

fun inject(homeDrawerFragment: HomeDrawerFragment)

fun inject(homeDetailFragment: HomeDetailFragment)

fun inject(messageActionsBottomSheet: MessageActionsBottomSheet)

fun inject(viewReactionBottomSheet: ViewReactionBottomSheet)

fun inject(messageMenuFragment: MessageMenuFragment)

fun inject(vectorSettingsActivity: VectorSettingsActivity)

fun inject(createRoomFragment: CreateRoomFragment)

fun inject(keysBackupRestoreFromKeyFragment: KeysBackupRestoreFromKeyFragment)

fun inject(keysBackupRestoreFromPassphraseFragment: KeysBackupRestoreFromPassphraseFragment)

fun inject(keysBackupRestoreSuccessFragment: KeysBackupRestoreSuccessFragment)

fun inject(keysBackupSetupStep1Fragment: KeysBackupSetupStep1Fragment)

fun inject(keysBackupSetupStep2Fragment: KeysBackupSetupStep2Fragment)

fun inject(keysBackupSetupStep3Fragment: KeysBackupSetupStep3Fragment)

fun inject(publicRoomsFragment: PublicRoomsFragment)

fun inject(sasVerificationIncomingFragment: SASVerificationIncomingFragment)

fun inject(quickReactionFragment: QuickReactionFragment)

fun inject(emojiReactionPickerActivity: EmojiReactionPickerActivity)


@Component.Factory
interface Factory {
fun create(vectorComponent: VectorComponent,

View File

@ -22,9 +22,11 @@ import dagger.BindsInstance
import dagger.Component
import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.VectorApplication
import im.vector.riotredesign.features.configuration.VectorConfiguration
import im.vector.riotredesign.features.crypto.keysrequest.KeyRequestHandler
import im.vector.riotredesign.features.crypto.verification.IncomingVerificationRequestHandler
import im.vector.riotredesign.features.home.HomeNavigator
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
import im.vector.riotredesign.features.home.group.SelectedGroupStore
import im.vector.riotredesign.features.navigation.Navigator
@ -49,6 +51,8 @@ interface VectorComponent {

fun navigator(): Navigator

fun homeNavigator(): HomeNavigator

fun homeRoomListObservableStore(): HomeRoomListObservableStore

fun selectedGroupStore(): SelectedGroupStore
@ -57,6 +61,8 @@ interface VectorComponent {

fun incomingKeyRequestHandler(): KeyRequestHandler

fun inject(vectorApplication: VectorApplication)

@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context): VectorComponent

View File

@ -21,6 +21,7 @@ import androidx.lifecycle.ViewModelProvider
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
import im.vector.riotredesign.core.platform.ConfigurationViewModel
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel
@ -39,18 +40,15 @@ import im.vector.riotredesign.features.home.room.detail.RoomDetailViewModel
import im.vector.riotredesign.features.home.room.detail.RoomDetailViewModel_AssistedFactory
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerViewModel
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerViewModel_AssistedFactory
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageActionsViewModel
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageActionsViewModel_AssistedFactory
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageMenuViewModel
import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageMenuViewModel_AssistedFactory
import im.vector.riotredesign.features.home.room.detail.timeline.action.QuickReactionViewModel
import im.vector.riotredesign.features.home.room.detail.timeline.action.QuickReactionViewModel_AssistedFactory
import im.vector.riotredesign.features.home.room.detail.timeline.action.*
import im.vector.riotredesign.features.home.room.list.RoomListViewModel
import im.vector.riotredesign.features.home.room.list.RoomListViewModel_AssistedFactory
import im.vector.riotredesign.features.reactions.EmojiChooserViewModel
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryNavigationViewModel
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryViewModel
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryViewModel_AssistedFactory
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomViewModel
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomViewModel_AssistedFactory
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerViewModel
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerViewModel_AssistedFactory
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewViewModel
@ -109,42 +107,53 @@ interface ViewModelModule {
fun bindKeysBackupSetupSharedViewModel(viewModel: KeysBackupSetupSharedViewModel): ViewModel

@Binds
fun bind_im_vector_riotredesign_features_home_HomeActivityViewModel(factory: HomeActivityViewModel_AssistedFactory): HomeActivityViewModel.Factory
@IntoMap
@ViewModelKey(ConfigurationViewModel::class)
fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel

@Binds
fun bind_im_vector_riotredesign_features_home_room_detail_composer_TextComposerViewModel(factory: TextComposerViewModel_AssistedFactory): TextComposerViewModel.Factory
fun bindHomeActivityViewModelFactory(factory: HomeActivityViewModel_AssistedFactory): HomeActivityViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_room_detail_RoomDetailViewModel(factory: RoomDetailViewModel_AssistedFactory): RoomDetailViewModel.Factory
fun bindTextComposerViewModelFactory(factory: TextComposerViewModel_AssistedFactory): TextComposerViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_QuickReactionViewModel(factory: QuickReactionViewModel_AssistedFactory): QuickReactionViewModel.Factory
fun bindRoomDetailViewModelFactory(factory: RoomDetailViewModel_AssistedFactory): RoomDetailViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_MessageActionsViewModel(factory: MessageActionsViewModel_AssistedFactory): MessageActionsViewModel.Factory
fun bindQuickReactionViewModelFactory(factory: QuickReactionViewModel_AssistedFactory): QuickReactionViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_MessageMenuViewModel(factory: MessageMenuViewModel_AssistedFactory): MessageMenuViewModel.Factory
fun bindMessageActionsViewModelFactory(factory: MessageActionsViewModel_AssistedFactory): MessageActionsViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_room_list_RoomListViewModel(factory: RoomListViewModel_AssistedFactory): RoomListViewModel.Factory
fun bindMessageMenuViewModelFactory(factory: MessageMenuViewModel_AssistedFactory): MessageMenuViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_group_GroupListViewModel(factory: GroupListViewModel_AssistedFactory): GroupListViewModel.Factory
fun bindRoomListViewModelFactory(factory: RoomListViewModel_AssistedFactory): RoomListViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_home_HomeDetailViewModel(factory: HomeDetailViewModel_AssistedFactory): HomeDetailViewModel.Factory
fun bindGroupListViewModelFactory(factory: GroupListViewModel_AssistedFactory): GroupListViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_crypto_keysbackup_settings_KeysBackupSettingsViewModel(factory: KeysBackupSettingsViewModel_AssistedFactory): KeysBackupSettingsViewModel.Factory
fun bindHomeDetailViewModelFactory(factory: HomeDetailViewModel_AssistedFactory): HomeDetailViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_roomdirectory_picker_RoomDirectoryPickerViewModel(factory: RoomDirectoryPickerViewModel_AssistedFactory): RoomDirectoryPickerViewModel.Factory
fun bindKeysBackupSettingsViewModelFactory(factory: KeysBackupSettingsViewModel_AssistedFactory): KeysBackupSettingsViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_roomdirectory_RoomDirectoryViewModel(factory: RoomDirectoryViewModel_AssistedFactory): RoomDirectoryViewModel.Factory
fun bindRoomDirectoryPickerViewModelFactory(factory: RoomDirectoryPickerViewModel_AssistedFactory): RoomDirectoryPickerViewModel.Factory

@Binds
fun bind_im_vector_riotredesign_features_roomdirectory_roompreview_RoomPreviewViewModel(factory: RoomPreviewViewModel_AssistedFactory): RoomPreviewViewModel.Factory
fun bindRoomDirectoryViewModelFactory(factory: RoomDirectoryViewModel_AssistedFactory): RoomDirectoryViewModel.Factory

@Binds
fun bindRoomPreviewViewModelFactory(factory: RoomPreviewViewModel_AssistedFactory): RoomPreviewViewModel.Factory

@Binds
fun bindViewReactionViewModelFactory(factory: ViewReactionViewModel_AssistedFactory): ViewReactionViewModel.Factory

@Binds
fun bindCreateRoomViewModelFactory(factory: CreateRoomViewModel_AssistedFactory): CreateRoomViewModel.Factory

}

View File

@ -24,6 +24,7 @@ import androidx.core.view.isVisible
import butterknife.BindView
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.hideKeyboard
import kotlinx.android.synthetic.main.activity.*
import javax.inject.Inject
@ -44,12 +45,10 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
@BindView(R.id.waiting_view_status_horizontal_progress)
lateinit var waitingHorizontalProgress: ProgressBar

@Inject
lateinit var session: Session
@Inject lateinit var session: Session

override fun onCreate(savedInstanceState: Bundle?) {
injector().inject(this)
super.onCreate(savedInstanceState)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun initUiAndData() {

View File

@ -44,8 +44,10 @@ import com.bumptech.glide.util.Util
import com.google.android.material.snackbar.Snackbar
import im.vector.riotredesign.BuildConfig
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.DaggerScreenComponent
import im.vector.riotredesign.core.di.HasInjector
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.di.VectorComponent
import im.vector.riotredesign.core.utils.toast
import im.vector.riotredesign.features.configuration.VectorConfiguration
import im.vector.riotredesign.features.rageshake.BugReportActivity
@ -78,7 +80,6 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
* ========================================================================================== */

protected lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var vectorConfiguration: VectorConfiguration
private lateinit var configurationViewModel: ConfigurationViewModel

private var unBinder: Unbinder? = null
@ -95,6 +96,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
private lateinit var screenComponent: ScreenComponent

override fun attachBaseContext(base: Context) {
val vectorConfiguration = VectorConfiguration(this)
super.attachBaseContext(vectorConfiguration.getLocalisedContext(base))
}

@ -121,8 +123,10 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
}

override fun onCreate(savedInstanceState: Bundle?) {

screenComponent = DaggerScreenComponent.factory().create(getVectorComponent(), this)
super.onCreate(savedInstanceState)
injectWith(screenComponent)
viewModelFactory = screenComponent.viewModelFactory()
configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java)
configurationViewModel.activityRestarter.observe(this, Observer {
if (!it.hasBeenHandled) {
@ -219,10 +223,16 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
return screenComponent
}

protected open fun injectWith(injector: ScreenComponent) = Unit

/* ==========================================================================================
* PRIVATE METHODS
* ========================================================================================== */

internal fun getVectorComponent(): VectorComponent {
return (application as HasInjector<VectorComponent>).injector()
}

/**
* Force to render the activity in fullscreen
*/

View File

@ -16,6 +16,7 @@

package im.vector.riotredesign.core.platform

import android.content.Context
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
@ -33,6 +34,7 @@ import butterknife.Unbinder
import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.MvRx
import com.bumptech.glide.util.Util.assertMainThread
import im.vector.riotredesign.core.di.DaggerScreenComponent
import im.vector.riotredesign.core.di.HasInjector
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.features.navigation.Navigator
@ -55,11 +57,22 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasInject

protected lateinit var viewModelFactory: ViewModelProvider.Factory
protected lateinit var navigator: Navigator
private lateinit var screenComponent: ScreenComponent

/* ==========================================================================================
* Life cycle
* ========================================================================================== */

override fun onAttach(context: Context) {
screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity)
super.onAttach(context)
navigator = vectorBaseActivity.getVectorComponent().navigator()
viewModelFactory = screenComponent.viewModelFactory()
injectWith(injector())
}

protected open fun injectWith(injector: ScreenComponent) = Unit

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -78,7 +91,6 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasInject
@CallSuper
override fun onResume() {
super.onResume()

Timber.v("onResume Fragment ${this.javaClass.simpleName}")
}

@ -101,7 +113,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasInject
}

override fun injector(): ScreenComponent {
return vectorBaseActivity.injector()
return screenComponent
}

/* ==========================================================================================

View File

@ -30,6 +30,7 @@ import im.vector.riotredesign.features.notifications.NotifiableEventResolver
import im.vector.riotredesign.features.notifications.NotificationUtils
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject

/**
* A service in charge of controlling whether the event stream is running or not.
@ -41,7 +42,7 @@ class EventStreamServiceX : VectorService() {
/**
* Managed session (no multi session for Riot)
*/
private val mSession by inject<Session>()
@Inject lateinit var session: Session

/**
* Set to true to simulate a push immediately when service is destroyed
@ -135,6 +136,11 @@ class EventStreamServiceX : VectorService() {
STARTED
}

override fun onCreate() {
//setup injector
super.onCreate()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Cancel any previous worker
cancelAnySimulatedPushSchedule()
@ -168,7 +174,7 @@ class EventStreamServiceX : VectorService() {
}
}

if (null == mSession) {
if (null == session) {
Timber.e("onStartCommand : no sessions")
myStopSelf()
return START_NOT_STICKY
@ -334,7 +340,7 @@ class EventStreamServiceX : VectorService() {
// TODO mPushManager = Matrix.getInstance(applicationContext)!!.pushManager
mNotifiableEventResolver = NotifiableEventResolver(applicationContext)

monitorSession(mSession!!)
monitorSession(session!!)

serviceState = if (forPush) {
ServiceState.CATCHUP
@ -387,7 +393,7 @@ class EventStreamServiceX : VectorService() {
}

if (canCatchup) {
if (mSession != null) {
if (session != null) {
// TODO session!!.catchupEventStream()
} else {
Timber.i("catchup no session")

View File

@ -28,6 +28,7 @@ import butterknife.OnClick
import butterknife.OnTextChanged
import com.google.android.material.textfield.TextInputLayout
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.utils.startImportTextFromFileIntent
import timber.log.Timber
@ -50,6 +51,10 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() {
@BindView(R.id.keys_restore_key_enter_edittext)
lateinit var mKeyTextEdit: EditText

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java)

View File

@ -33,6 +33,7 @@ import butterknife.OnClick
import butterknife.OnTextChanged
import com.google.android.material.textfield.TextInputLayout
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.showPassword
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
@ -66,6 +67,10 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
fun newInstance() = KeysBackupRestoreFromPassphraseFragment()
}

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)


View File

@ -21,6 +21,7 @@ import androidx.lifecycle.ViewModelProviders
import butterknife.BindView
import butterknife.OnClick
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.utils.LiveEvent

@ -36,6 +37,10 @@ class KeysBackupRestoreSuccessFragment : VectorBaseFragment() {

private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
sharedViewModel = activity?.run {

View File

@ -23,7 +23,7 @@ import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.viewModel
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.injector
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
import im.vector.riotredesign.core.platform.WaitingViewData
import javax.inject.Inject
@ -43,9 +43,8 @@ class KeysBackupManageActivity : SimpleFragmentActivity() {
private val viewModel: KeysBackupSettingsViewModel by viewModel()
@Inject lateinit var keysBackupSettingsViewModelFactory: KeysBackupSettingsViewModel.Factory

override fun onCreate(savedInstanceState: Bundle?) {
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
super.onCreate(savedInstanceState)
}

override fun initUiAndData() {

View File

@ -21,7 +21,7 @@ import androidx.appcompat.app.AlertDialog
import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.injector
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupActivity
@ -40,9 +40,8 @@ class KeysBackupSettingsFragment : VectorBaseFragment(),
@Inject lateinit var keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController
private val viewModel: KeysBackupSettingsViewModel by activityViewModel()

override fun onCreate(savedInstanceState: Bundle?) {
injector().inject(this)
super.onCreate(savedInstanceState)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModelProviders
import butterknife.BindView
import butterknife.OnClick
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.utils.LiveEvent

@ -45,6 +46,10 @@ class KeysBackupSetupStep1Fragment : VectorBaseFragment() {
@BindView(R.id.keys_backup_setup_step1_manualExport)
lateinit var manualExportButton: Button

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)

View File

@ -31,6 +31,7 @@ import butterknife.OnTextChanged
import com.google.android.material.textfield.TextInputLayout
import com.nulabinc.zxcvbn.Zxcvbn
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.showPassword
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.ui.views.PasswordStrengthBar
@ -77,6 +78,10 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {

private lateinit var viewModel: KeysBackupSetupSharedViewModel

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)


View File

@ -29,6 +29,7 @@ import butterknife.BindView
import butterknife.OnClick
import com.google.android.material.bottomsheet.BottomSheetDialog
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.files.addEntryToDownloadManager
import im.vector.riotredesign.core.files.saveStringToFile
import im.vector.riotredesign.core.platform.VectorBaseFragment
@ -54,6 +55,10 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() {

private lateinit var viewModel: KeysBackupSetupSharedViewModel

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = activity?.run {

View File

@ -24,6 +24,7 @@ import butterknife.BindView
import butterknife.OnClick
import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.AvatarRenderer

@ -49,6 +50,10 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {

private lateinit var viewModel: SasVerificationViewModel

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)


View File

@ -31,6 +31,7 @@ import androidx.lifecycle.ViewModelProviders
import com.airbnb.mvrx.viewModel
import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.hideKeyboard
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.extensions.replaceFragment
@ -73,6 +74,10 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {

override fun getLayoutRes() = R.layout.activity_home

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeNavigator.activity = this
@ -103,9 +108,6 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START)
}
}

incomingVerificationRequestHandler.ensureStarted()
keyRequestHandler.ensureStarted()
}

override fun onDestroy() {

View File

@ -32,6 +32,7 @@ import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.ui.views.KeysBackupBanner
@ -74,6 +75,10 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
return R.layout.fragment_home_detail
}

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
currentDisplayMode = savedInstanceState?.getSerializable(CURRENT_DISPLAY_MODE) as? RoomListFragment.DisplayMode

View File

@ -19,6 +19,7 @@ package im.vector.riotredesign.features.home
import android.os.Bundle
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.observeK
import im.vector.riotredesign.core.extensions.replaceChildFragment
import im.vector.riotredesign.core.platform.VectorBaseFragment
@ -39,6 +40,10 @@ class HomeDrawerFragment : VectorBaseFragment() {

override fun getLayoutResId() = R.layout.fragment_home_drawer

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState == null) {
@ -62,4 +67,4 @@ class HomeDrawerFragment : VectorBaseFragment() {
navigator.openDebug(requireActivity())
}
}
}
}

View File

@ -20,12 +20,15 @@ import androidx.core.view.GravityCompat
import androidx.fragment.app.FragmentManager
import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenScope
import im.vector.riotredesign.core.extensions.replaceFragment
import im.vector.riotredesign.features.navigation.Navigator
import kotlinx.android.synthetic.main.activity_home.*
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class HomeNavigator @Inject constructor() {

var activity: HomeActivity? = null

View File

@ -16,12 +16,14 @@

package im.vector.riotredesign.features.home.group

import android.content.Context
import android.os.Bundle
import com.airbnb.mvrx.Incomplete
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel
import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.StateView
import im.vector.riotredesign.core.platform.VectorBaseFragment
@ -45,6 +47,10 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback

override fun getLayoutResId() = R.layout.fragment_group_list

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
groupController.callback = this

View File

@ -67,6 +67,7 @@ import im.vector.matrix.android.api.session.room.model.message.MessageVideoConte
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.user.model.User
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.dialogs.DialogListItem
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
import im.vector.riotredesign.core.extensions.hideKeyboard
@ -189,8 +190,11 @@ class RoomDetailFragment :
@BindView(R.id.composerLayout)
lateinit var composerLayout: TextComposerView

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
injector().inject(this)
super.onActivityCreated(savedInstanceState)
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
setupToolbar(roomToolbar)

View File

@ -33,6 +33,7 @@ import com.airbnb.mvrx.withState
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import kotlinx.android.synthetic.main.bottom_sheet_message_actions.*
@ -42,7 +43,7 @@ import javax.inject.Inject
* Bottom sheet fragment that shows a message preview with list of contextual actions
* (Includes fragments for quick reactions and list of actions)
*/
class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment() {

@Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory
private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
@ -61,6 +62,9 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
@BindView(R.id.bottom_sheet_message_preview_body)
lateinit var messageBodyTextView: TextView

override fun injectWith(screenComponent: ScreenComponent) {
screenComponent.inject(this)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.bottom_sheet_message_actions, container, false)

View File

@ -23,24 +23,31 @@ import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.themes.ThemeUtils
import javax.inject.Inject

/**
* Fragment showing the list of available contextual action for a given message.
*/
class MessageMenuFragment : BaseMvRxFragment() {
class MessageMenuFragment : VectorBaseFragment() {

@Inject lateinit var messageMenuViewModelFactory: MessageMenuViewModel.Factory
private val viewModel: MessageMenuViewModel by fragmentViewModel(MessageMenuViewModel::class)
private var addSeparators = false
var interactionListener: InteractionListener? = null

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun getLayoutResId() = R.layout.fragment_message_menu

override fun invalidate() = withState(viewModel) { state ->

val linearLayout = view as? LinearLayout
@ -68,14 +75,6 @@ class MessageMenuFragment : BaseMvRxFragment() {
}


override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//we just create programmatically
val contentView = LinearLayout(context)
contentView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
contentView.orientation = LinearLayout.VERTICAL
return contentView
}

private fun inflateActionView(action: SimpleAction, inflater: LayoutInflater, container: ViewGroup?): View? {
return inflater.inflate(R.layout.adapter_item_action, container, false)?.apply {
if (action.iconResId != null) {

View File

@ -17,26 +17,24 @@ package im.vector.riotredesign.features.home.room.detail.timeline.action

import android.graphics.Typeface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.transition.TransitionManager
import butterknife.BindView
import butterknife.ButterKnife
import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.EmojiCompatFontProvider
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import javax.inject.Inject

/**
* Quick Reaction Fragment (agree / like reactions)
*/
class QuickReactionFragment : BaseMvRxFragment() {
class QuickReactionFragment : VectorBaseFragment() {

private val viewModel: QuickReactionViewModel by fragmentViewModel(QuickReactionViewModel::class)

@ -60,10 +58,10 @@ class QuickReactionFragment : BaseMvRxFragment() {
@Inject lateinit var fontProvider: EmojiCompatFontProvider
@Inject lateinit var quickReactionViewModelFactory: QuickReactionViewModel.Factory

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.adapter_item_action_quick_reaction, container, false)
ButterKnife.bind(this, view)
return view
override fun getLayoutResId() = R.layout.adapter_item_action_quick_reaction

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@ -15,24 +15,40 @@
*/
package im.vector.riotredesign.features.home.room.detail.timeline.action

import android.content.Context
import android.os.Bundle
import android.os.Parcelable
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.MvRxView
import com.airbnb.mvrx.MvRxViewModelStore
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import im.vector.riotredesign.core.di.DaggerScreenComponent
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseActivity
import java.util.*

/**
* Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment)
*/
abstract class BaseMvRxBottomSheetDialog : BottomSheetDialogFragment(), MvRxView {
abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MvRxView {

override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) }
private lateinit var mvrxPersistedViewId: String

private lateinit var screenComponent: ScreenComponent
final override val mvrxViewId: String by lazy { mvrxPersistedViewId }

val vectorBaseActivity: VectorBaseActivity by lazy {
activity as VectorBaseActivity
}

override fun onAttach(context: Context) {
screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity)
super.onAttach(context)
injectWith(screenComponent)
}

protected open fun injectWith(screenComponent: ScreenComponent) = Unit

override fun onCreate(savedInstanceState: Bundle?) {
mvrxViewModelStore.restoreViewModels(this, savedInstanceState)
mvrxPersistedViewId = savedInstanceState?.getString(PERSISTED_VIEW_ID_KEY)

View File

@ -15,24 +15,30 @@ import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.EmojiCompatFontProvider
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import kotlinx.android.synthetic.main.bottom_sheet_display_reactions.*
import org.koin.android.ext.android.inject
import javax.inject.Inject

/**
* Bottom sheet displaying list of reactions for a given event ordered by timestamp
*/
class ViewReactionBottomSheet : BaseMvRxBottomSheetDialog() {
class ViewReactionBottomSheet : VectorBaseBottomSheetDialogFragment() {

private val viewModel: ViewReactionViewModel by fragmentViewModel(ViewReactionViewModel::class)

private val emojiCompatFontProvider by inject<EmojiCompatFontProvider>()
@Inject lateinit var viewReactionViewModelFactory: ViewReactionViewModel.Factory
@Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider

@BindView(R.id.bottom_sheet_display_reactions_list)
lateinit var epoxyRecyclerView: EpoxyRecyclerView

private val epoxyController by lazy { ViewReactionsEpoxyController(emojiCompatFontProvider.typeface) }

override fun injectWith(screenComponent: ScreenComponent) {
screenComponent.inject(this)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.bottom_sheet_display_reactions, container, false)
ButterKnife.bind(this, view)

View File

@ -1,20 +1,25 @@
package im.vector.riotredesign.features.home.room.detail.timeline.action

import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.airbnb.mvrx.*
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.rx.RxRoom
import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.core.platform.VectorViewModel
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
import org.koin.android.ext.android.get
import io.reactivex.Observable


data class DisplayReactionsViewState(
val eventId: String = "",
val roomId: String = "",
val eventId: String,
val roomId: String,
val mapReactionKeyToMemberList: Async<List<ReactionInfo>> = Uninitialized)
: MvRxState
: MvRxState {

constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId)

}

data class ReactionInfo(
val eventId: String,
@ -27,75 +32,59 @@ data class ReactionInfo(
/**
* Used to display the list of members that reacted to a given event
*/
class ViewReactionViewModel(private val session: Session,
private val timelineDateFormatter: TimelineDateFormatter,
initialState: DisplayReactionsViewState) : VectorViewModel<DisplayReactionsViewState>(initialState) {
class ViewReactionViewModel @AssistedInject constructor(@Assisted
initialState: DisplayReactionsViewState,
private val session: Session,
private val timelineDateFormatter: TimelineDateFormatter
) : VectorViewModel<DisplayReactionsViewState>(initialState) {

init {
loadReaction()
private val roomId = initialState.roomId
private val eventId = initialState.eventId
private val room = session.getRoom(roomId)
?: throw IllegalStateException("Shouldn't use this ViewModel without a room")

@AssistedInject.Factory
interface Factory {
fun create(initialState: DisplayReactionsViewState): ViewReactionViewModel
}

fun loadReaction() = withState { state ->

try {
val room = session.getRoom(state.roomId)
val event = room?.getTimeLineEvent(state.eventId)
if (event == null) {
setState { copy(mapReactionKeyToMemberList = Fail(Throwable())) }
return@withState
}
var results = ArrayList<ReactionInfo>()
event.annotations?.reactionsSummary?.forEach { sum ->

sum.sourceEvents.mapNotNull { room.getTimeLineEvent(it) }.forEach {
val localDate = it.root.localDateTime()
results.add(ReactionInfo(it.root.eventId!!, sum.key, it.root.sender
?: "", it.senderName, timelineDateFormatter.formatMessageHour(localDate)))
}
}
setState {
copy(
mapReactionKeyToMemberList = Success(results.sortedBy { it.timestamp })
)
}
} catch (t: Throwable) {
setState {
copy(
mapReactionKeyToMemberList = Fail(t)
)
}
}
}


companion object : MvRxViewModelFactory<ViewReactionViewModel, DisplayReactionsViewState> {

override fun initialState(viewModelContext: ViewModelContext): DisplayReactionsViewState? {

val roomId = (viewModelContext.args as? TimelineEventFragmentArgs)?.roomId
?: return null
val info = (viewModelContext.args as? TimelineEventFragmentArgs)?.informationData
?: return null
return DisplayReactionsViewState(info.eventId, roomId)
}

override fun create(viewModelContext: ViewModelContext, state: DisplayReactionsViewState): ViewReactionViewModel? {
val session = viewModelContext.activity.get<Session>()
val eventId = (viewModelContext.args as TimelineEventFragmentArgs).eventId
val lifecycleOwner = (viewModelContext as FragmentViewModelContext).fragment<Fragment>()
val liveSummary = session.getRoom(state.roomId)?.getEventSummaryLive(eventId)
val viewReactionViewModel = ViewReactionViewModel(session, viewModelContext.activity.get(), state)
// This states observes the live summary
// When fragment context will be destroyed the observer will automatically removed
liveSummary?.observe(lifecycleOwner, Observer {
it?.firstOrNull()?.let {
viewReactionViewModel.loadReaction()
}
})

return viewReactionViewModel
val fragment: ViewReactionBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.viewReactionViewModelFactory.create(state)
}


}


init {
observeEventAnnotationSummaries()
}

private fun observeEventAnnotationSummaries() {
RxRoom(room)
.liveAnnotationSummary(eventId)
.flatMapSingle { summaries ->
Observable
.fromIterable(summaries)
.flatMapIterable { it.reactionsSummary }
.map {
val event = room.getTimeLineEvent(eventId)
?: throw RuntimeException("Your eventId is not valid")
val localDate = event.root.localDateTime()
ReactionInfo(
event.root.eventId!!,
it.key,
event.root.sender ?: "",
event.senderName,
timelineDateFormatter.formatMessageHour(localDate)
)
}
.toList()
}
.execute {
copy(mapReactionKeyToMemberList = it)
}
}
}

View File

@ -32,6 +32,7 @@ import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.OnBackPressed
@ -71,6 +72,10 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback, O

override fun getLayoutResId() = R.layout.fragment_room_list

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setupCreateRoomButton()

View File

@ -28,7 +28,9 @@ import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity
import im.vector.riotredesign.features.settings.VectorSettingsActivity
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class DefaultNavigator @Inject constructor() : Navigator {

override fun openRoom(roomId: String, context: Context) {

View File

@ -30,9 +30,11 @@ import androidx.lifecycle.ViewModelProviders
import com.google.android.material.tabs.TabLayout
import im.vector.riotredesign.EmojiCompatFontProvider
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.VectorBaseActivity
import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.*
import javax.inject.Inject

/**
*
@ -54,7 +56,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide

override fun getTitleRes(): Int = R.string.title_activity_emoji_reaction_picker

lateinit var emojiCompatFontProvider: EmojiCompatFontProvider
@Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider

private var tabLayoutSelectionListener = object : TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> {
override fun onTabReselected(p0: TabLayout.Tab) {
@ -69,6 +71,10 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide

}

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun initUiAndData() {
configureToolbar(emojiPickerToolbar)
emojiCompatFontProvider.let {

View File

@ -28,8 +28,9 @@ import im.vector.riotredesign.core.epoxy.loadingItem
import im.vector.riotredesign.core.epoxy.noResultItem
import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.resources.StringProvider
import javax.inject.Inject

class PublicRoomsController(private val stringProvider: StringProvider,
class PublicRoomsController @Inject constructor(private val stringProvider: StringProvider,
private val errorFormatter: ErrorFormatter) : TypedEpoxyController<PublicRoomsViewState>() {

var callback: Callback? = null

View File

@ -28,6 +28,7 @@ import com.google.android.material.snackbar.Snackbar
import com.jakewharton.rxbinding2.widget.RxTextView
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.VectorBaseFragment
@ -55,6 +56,10 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback

override fun getMenuRes() = R.menu.menu_room_directory

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)


View File

@ -1,54 +0,0 @@
/*
* Copyright 2019 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.riotredesign.features.roomdirectory

import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomController
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryListCreator
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerController
import org.koin.dsl.module.module

class RoomDirectoryModule {

companion object {
const val ROOM_DIRECTORY_SCOPE = "ROOM_DIRECTORY_SCOPE"
}

val definition = module(override = true) {

scope(ROOM_DIRECTORY_SCOPE) {
RoomDirectoryPickerController(get(), get(), get())
}

scope(ROOM_DIRECTORY_SCOPE) {
RoomDirectoryListCreator(get(), get<Session>().sessionParams.credentials)
}

scope(ROOM_DIRECTORY_SCOPE) {
PublicRoomsController(get(), get())
}

/* ==========================================================================================
* Create room
* ========================================================================================== */

scope(ROOM_DIRECTORY_SCOPE) {
CreateRoomController(get(), get())
}

}
}

View File

@ -28,8 +28,9 @@ import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.resources.StringProvider
import im.vector.riotredesign.features.form.formEditTextItem
import im.vector.riotredesign.features.form.formSwitchItem
import javax.inject.Inject

class CreateRoomController(private val stringProvider: StringProvider,
class CreateRoomController @Inject constructor(private val stringProvider: StringProvider,
private val errorFormatter: ErrorFormatter
) : TypedEpoxyController<CreateRoomViewState>() {


View File

@ -24,36 +24,34 @@ import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryModule
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryNavigationViewModel
import kotlinx.android.synthetic.main.fragment_create_room.*
import org.koin.android.ext.android.inject
import org.koin.android.scope.ext.android.bindScope
import org.koin.android.scope.ext.android.getOrCreateScope
import timber.log.Timber
import javax.inject.Inject

class CreateRoomFragment : VectorBaseFragment(), CreateRoomController.Listener {

private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel
private val viewModel: CreateRoomViewModel by fragmentViewModel()
private val createRoomController: CreateRoomController by inject()
@Inject lateinit var createRoomController: CreateRoomController
@Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory

override fun getLayoutResId() = R.layout.fragment_create_room

override fun getMenuRes() = R.menu.vector_room_creation

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
bindScope(getOrCreateScope(RoomDirectoryModule.ROOM_DIRECTORY_SCOPE))

vectorBaseActivity.setSupportActionBar(createRoomToolbar)

navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java)

setupRecyclerView()

createRoomClose.setOnClickListener {
navigationViewModel.goTo(RoomDirectoryActivity.Navigation.Back)
}

View File

@ -17,24 +17,30 @@
package im.vector.riotredesign.features.roomdirectory.createroom

import com.airbnb.mvrx.*
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
import im.vector.matrix.android.api.session.room.model.create.CreateRoomPreset
import im.vector.riotredesign.core.platform.VectorViewModel
import org.koin.android.ext.android.get

class CreateRoomViewModel(initialState: CreateRoomViewState,
private val session: Session) : VectorViewModel<CreateRoomViewState>(initialState) {
class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: CreateRoomViewState,
private val session: Session
) : VectorViewModel<CreateRoomViewState>(initialState) {

@AssistedInject.Factory
interface Factory {
fun create(initialState: CreateRoomViewState): CreateRoomViewModel
}

companion object : MvRxViewModelFactory<CreateRoomViewModel, CreateRoomViewState> {

@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: CreateRoomViewState): CreateRoomViewModel? {
val currentSession = viewModelContext.activity.get<Session>()

return CreateRoomViewModel(state, currentSession)
val fragment: CreateRoomFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.createRoomViewModelFactory.create(state)
}
}


View File

@ -26,6 +26,7 @@ import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryNavigationViewModel
@ -70,8 +71,11 @@ class RoomDirectoryPickerFragment : VectorBaseFragment(), RoomDirectoryPickerCon
return super.onOptionsItemSelected(item)
}

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
injector().inject(this)
super.onActivityCreated(savedInstanceState)
navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java)
setupRecyclerView()

View File

@ -24,6 +24,7 @@ import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.extensions.setTextOrHide
import im.vector.riotredesign.core.platform.ButtonStateView
@ -49,8 +50,11 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel()
private val roomPreviewData: RoomPreviewData by args()

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
injector().inject(this)
super.onActivityCreated(savedInstanceState)
setupToolbar(roomPreviewNoPreviewToolbar)
}

View File

@ -23,9 +23,10 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import im.vector.matrix.android.api.session.Session
import im.vector.riotredesign.R
import im.vector.riotredesign.core.di.ScreenComponent
import im.vector.riotredesign.core.platform.VectorBaseActivity
import kotlinx.android.synthetic.main.activity_vector_settings.*
import org.koin.android.ext.android.inject
import javax.inject.Inject

/**
* Displays the client settings.
@ -43,7 +44,11 @@ class VectorSettingsActivity : VectorBaseActivity(),

private var keyToHighlight: String? = null

private val session by inject<Session>()
@Inject lateinit var session: Session

override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}

override fun initUiAndData() {
configureToolbar(settingsToolbar)

View File

@ -34,12 +34,12 @@ import im.vector.riotredesign.core.preference.BingRule
import im.vector.riotredesign.core.preference.BingRulePreference
import im.vector.riotredesign.features.notifications.NotificationUtils
import im.vector.riotredesign.features.notifications.supportNotificationChannels
import org.koin.android.ext.android.inject
import javax.inject.Inject

class VectorSettingsAdvancedNotificationPreferenceFragment : VectorPreferenceFragment() {

// members
private val mSession by inject<Session>()
@Inject lateinit var session: Session
private var mLoadingView: View? = null

// events listener

View File

@ -37,7 +37,7 @@ import im.vector.riotredesign.features.rageshake.BugReporter
import im.vector.riotredesign.features.settings.troubleshoot.NotificationTroubleshootTestManager
import im.vector.riotredesign.features.settings.troubleshoot.TroubleshootTest
import im.vector.riotredesign.push.fcm.NotificationTroubleshootTestManagerFactory
import org.koin.android.ext.android.inject
import javax.inject.Inject

class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() {

@ -54,7 +54,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() {

private var testManager: NotificationTroubleshootTestManager? = null
// members
private val mSession by inject<Session>()
@Inject lateinit var session: Session

override fun getLayoutResId() = R.layout.fragment_settings_notifications_troubleshoot

@ -92,7 +92,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() {
mSummaryDescription.text = getString(R.string.settings_troubleshoot_diagnostic_running_status,
0, 0)

testManager = NotificationTroubleshootTestManagerFactory.createTestManager(this, mSession)
testManager = NotificationTroubleshootTestManagerFactory.createTestManager(this, session)

testManager?.statusListener = { troubleshootTestManager ->
if (isAdded) {

View File

@ -64,17 +64,18 @@ import im.vector.riotredesign.features.MainActivity
import im.vector.riotredesign.features.configuration.VectorConfiguration
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupManageActivity
import im.vector.riotredesign.features.themes.ThemeUtils
import org.koin.android.ext.android.inject
import timber.log.Timber
import java.lang.ref.WeakReference
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject

class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {

// members
private val mSession by inject<Session>()
@Inject lateinit var session: Session
@Inject lateinit var vectorConfiguration: VectorConfiguration

// disable some updates if there is
// TODO private val mNetworkListener = IMXNetworkEventListener { refreshDisplay() }
@ -111,7 +112,6 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
// used to avoid requesting to enter the password for each deletion
private var mAccountPassword: String = ""

private val vectorConfiguration by inject<VectorConfiguration>()

// current publicised group list
private var mPublicisedGroups: MutableSet<String>? = null
@ -272,7 +272,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

// Avatar
mUserAvatarPreference.let {
it.setSession(mSession)
it.setSession(session)
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
onUpdateAvatarClick()
false
@ -479,7 +479,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
val cryptoIsEnabledPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY)


if (mSession.isCryptoEnabled()) {
if (session.isCryptoEnabled()) {
mLabsCategory.removePreference(useCryptoPref)

cryptoIsEnabledPref.isEnabled = false
@ -489,7 +489,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
useCryptoPref.isChecked = false

useCryptoPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid ->
if (TextUtils.isEmpty(mSession.sessionParams.credentials.deviceId)) {
if (TextUtils.isEmpty(session.sessionParams.credentials.deviceId)) {
activity?.let { activity ->
AlertDialog.Builder(activity)
.setMessage(R.string.room_settings_labs_end_to_end_warnings)
@ -508,7 +508,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
} else {
val newValue = newValueAsVoid as Boolean

if (mSession.isCryptoEnabled() != newValue) {
if (session.isCryptoEnabled() != newValue) {
notImplemented()
/* TODO
displayLoadingView()
@ -575,15 +575,15 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

// user account
findPreference(PreferencesManager.SETTINGS_LOGGED_IN_PREFERENCE_KEY)
.summary = mSession.sessionParams.credentials.userId
.summary = session.sessionParams.credentials.userId

// home server
findPreference(PreferencesManager.SETTINGS_HOME_SERVER_PREFERENCE_KEY)
.summary = mSession.sessionParams.homeServerConnectionConfig.homeServerUri.toString()
.summary = session.sessionParams.homeServerConnectionConfig.homeServerUri.toString()

// identity server
findPreference(PreferencesManager.SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY)
.summary = mSession.sessionParams.homeServerConnectionConfig.identityServerUri.toString()
.summary = session.sessionParams.homeServerConnectionConfig.identityServerUri.toString()

// Analytics

@ -641,7 +641,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

// olm version
findPreference(PreferencesManager.SETTINGS_OLM_VERSION_PREFERENCE_KEY)
.summary = mSession.getCryptoVersion(requireContext(), false)
.summary = session.getCryptoVersion(requireContext(), false)

// copyright
findPreference(PreferencesManager.SETTINGS_COPYRIGHT_PREFERENCE_KEY)
@ -2163,8 +2163,8 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
* @param aMyDeviceInfo the device info
*/
private fun refreshCryptographyPreference(aMyDeviceInfo: DeviceInfo?) {
val userId = mSession.sessionParams.credentials.userId
val deviceId = mSession.sessionParams.credentials.deviceId
val userId = session.sessionParams.credentials.userId
val deviceId = session.sessionParams.credentials.deviceId

// device name
if (null != aMyDeviceInfo) {
@ -2195,7 +2195,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

// crypto section: device key (fingerprint)
if (!TextUtils.isEmpty(deviceId) && !TextUtils.isEmpty(userId)) {
val deviceInfo = mSession.getDeviceInfo(userId, deviceId)
val deviceInfo = session.getDeviceInfo(userId, deviceId)

if (null != deviceInfo && !TextUtils.isEmpty(deviceInfo.fingerprint())) {
cryptoInfoTextPreference.summary = deviceInfo.getFingerprintHumanReadable()
@ -2211,10 +2211,10 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

sendToUnverifiedDevicesPref.isChecked = false

sendToUnverifiedDevicesPref.isChecked = mSession.getGlobalBlacklistUnverifiedDevices()
sendToUnverifiedDevicesPref.isChecked = session.getGlobalBlacklistUnverifiedDevices()

sendToUnverifiedDevicesPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
mSession.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)
session.setGlobalBlacklistUnverifiedDevices(sendToUnverifiedDevicesPref.isChecked)

true
}
@ -2258,7 +2258,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
* It can be any mobile device, as any browser.
*/
private fun refreshDevicesList() {
if (mSession.isCryptoEnabled() && !TextUtils.isEmpty(mSession.sessionParams.credentials.deviceId)) {
if (session.isCryptoEnabled() && !TextUtils.isEmpty(session.sessionParams.credentials.deviceId)) {
// display a spinner while loading the devices list
if (0 == mDevicesListSettingsCategory.preferenceCount) {
activity?.let {
@ -2267,7 +2267,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
}
}

mSession.getDevicesList(object : MatrixCallback<DevicesListResponse> {
session.getDevicesList(object : MatrixCallback<DevicesListResponse> {
override fun onSuccess(data: DevicesListResponse) {
if (!isAdded) {
return
@ -2306,7 +2306,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
var preference: VectorPreference
var typeFaceHighlight: Int
var isNewList = true
val myDeviceId = mSession.sessionParams.credentials.deviceId
val myDeviceId = session.sessionParams.credentials.deviceId

if (aDeviceInfoList.size == mDevicesNameList.size) {
isNewList = !mDevicesNameList.containsAll(aDeviceInfoList)
@ -2412,7 +2412,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
.setPositiveButton(R.string.rename) { _, _ -> displayDeviceRenameDialog(aDeviceInfo) }

// disable the deletion for our own device
if (!TextUtils.equals(mSession.getMyDevice()?.deviceId, aDeviceInfo.deviceId)) {
if (!TextUtils.equals(session.getMyDevice()?.deviceId, aDeviceInfo.deviceId)) {
builder.setNegativeButton(R.string.delete) { _, _ -> displayDeviceDeletionDialog(aDeviceInfo) }
}

@ -2449,7 +2449,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref

val newName = input.text.toString()

mSession.setDeviceName(aDeviceInfoToRename.deviceId!!, newName, object : MatrixCallback<Unit> {
session.setDeviceName(aDeviceInfoToRename.deviceId!!, newName, object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) {
hideLoadingView()


View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"/>