forked from GitHub-Mirror/riotX-android
Dagger: start handling app dependencies [WIP]
This commit is contained in:
parent
c2c2d0b21e
commit
9c1f870694
@ -54,7 +54,7 @@ internal class RoomMembers(private val realm: Realm,
|
|||||||
}
|
}
|
||||||
return EventEntity
|
return EventEntity
|
||||||
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
||||||
.contains(EventEntityFields.CONTENT, displayName)
|
.equalTo(EventEntityFields.CONTENT, displayName)
|
||||||
.distinct(EventEntityFields.STATE_KEY)
|
.distinct(EventEntityFields.STATE_KEY)
|
||||||
.findAll()
|
.findAll()
|
||||||
.size == 1
|
.size == 1
|
||||||
|
@ -138,6 +138,7 @@ dependencies {
|
|||||||
def big_image_viewer_version = '1.5.6'
|
def big_image_viewer_version = '1.5.6'
|
||||||
def glide_version = '4.9.0'
|
def glide_version = '4.9.0'
|
||||||
def moshi_version = '1.8.0'
|
def moshi_version = '1.8.0'
|
||||||
|
def daggerVersion = '2.23.1'
|
||||||
|
|
||||||
implementation project(":matrix-sdk-android")
|
implementation project(":matrix-sdk-android")
|
||||||
implementation project(":matrix-sdk-android-rx")
|
implementation project(":matrix-sdk-android-rx")
|
||||||
@ -219,8 +220,10 @@ dependencies {
|
|||||||
implementation 'com.github.jaiselrahman:FilePicker:1.2.2'
|
implementation 'com.github.jaiselrahman:FilePicker:1.2.2'
|
||||||
|
|
||||||
// DI
|
// DI
|
||||||
implementation "org.koin:koin-android:$koin_version"
|
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||||
implementation "org.koin:koin-android-scope:$koin_version"
|
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||||
|
compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
|
||||||
|
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'
|
||||||
|
|
||||||
// gplay flavor only
|
// gplay flavor only
|
||||||
gplayImplementation 'com.google.firebase:firebase-core:16.0.8'
|
gplayImplementation 'com.google.firebase:firebase-core:16.0.8'
|
||||||
|
@ -3,9 +3,9 @@ package im.vector.riotredesign
|
|||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.core.provider.FontsContractCompat
|
import androidx.core.provider.FontsContractCompat
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EmojiCompatFontProvider @Inject constructor(): FontsContractCompat.FontRequestCallback() {
|
||||||
class EmojiCompatFontProvider : FontsContractCompat.FontRequestCallback() {
|
|
||||||
|
|
||||||
var typeface: Typeface? = null
|
var typeface: Typeface? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -31,67 +31,56 @@ import com.github.piasy.biv.BigImageViewer
|
|||||||
import com.github.piasy.biv.loader.glide.GlideImageLoader
|
import com.github.piasy.biv.loader.glide.GlideImageLoader
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.riotredesign.core.di.AppModule
|
import im.vector.riotredesign.core.di.HasInjector
|
||||||
|
import im.vector.riotredesign.core.di.VectorComponent
|
||||||
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.KeysBackupModule
|
|
||||||
import im.vector.riotredesign.features.home.HomeModule
|
|
||||||
import im.vector.riotredesign.features.lifecycle.VectorActivityLifecycleCallbacks
|
import im.vector.riotredesign.features.lifecycle.VectorActivityLifecycleCallbacks
|
||||||
import im.vector.riotredesign.features.rageshake.VectorFileLogger
|
import im.vector.riotredesign.features.rageshake.VectorFileLogger
|
||||||
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
||||||
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryModule
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import org.koin.log.EmptyLogger
|
|
||||||
import org.koin.standalone.StandAloneContext.startKoin
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class VectorApplication : Application() {
|
class VectorApplication : Application(), HasInjector<VectorComponent> {
|
||||||
|
|
||||||
lateinit var appContext: Context
|
lateinit var appContext: Context
|
||||||
//font thread handler
|
//font thread handler
|
||||||
private var mFontThreadHandler: Handler? = null
|
@Inject lateinit var vectorConfiguration: VectorConfiguration
|
||||||
|
@Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider
|
||||||
val vectorConfiguration: VectorConfiguration by inject()
|
lateinit var vectorComponent: VectorComponent
|
||||||
|
private var fontThreadHandler: Handler? = null
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
appContext = this
|
appContext = this
|
||||||
|
|
||||||
VectorUncaughtExceptionHandler.activate(this)
|
VectorUncaughtExceptionHandler.activate(this)
|
||||||
|
|
||||||
// Log
|
// Log
|
||||||
VectorFileLogger.init(this)
|
VectorFileLogger.init(this)
|
||||||
Timber.plant(Timber.DebugTree(), VectorFileLogger)
|
Timber.plant(Timber.DebugTree(), VectorFileLogger)
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Stetho.initializeWithDefaults(this)
|
Stetho.initializeWithDefaults(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidThreeTen.init(this)
|
AndroidThreeTen.init(this)
|
||||||
BigImageViewer.initialize(GlideImageLoader.with(applicationContext))
|
BigImageViewer.initialize(GlideImageLoader.with(applicationContext))
|
||||||
EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
val appModule = AppModule(applicationContext).definition
|
|
||||||
val homeModule = HomeModule().definition
|
|
||||||
val roomDirectoryModule = RoomDirectoryModule().definition
|
|
||||||
val keysBackupModule = KeysBackupModule().definition
|
|
||||||
val koin = startKoin(listOf(appModule, homeModule, roomDirectoryModule, keysBackupModule), logger = EmptyLogger())
|
|
||||||
Matrix.getInstance().setApplicationFlavor(BuildConfig.FLAVOR_DESCRIPTION)
|
Matrix.getInstance().setApplicationFlavor(BuildConfig.FLAVOR_DESCRIPTION)
|
||||||
registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks())
|
registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks())
|
||||||
|
|
||||||
val fontRequest = FontRequest(
|
val fontRequest = FontRequest(
|
||||||
"com.google.android.gms.fonts",
|
"com.google.android.gms.fonts",
|
||||||
"com.google.android.gms",
|
"com.google.android.gms",
|
||||||
"Noto Color Emoji Compat",
|
"Noto Color Emoji Compat",
|
||||||
R.array.com_google_android_gms_fonts_certs
|
R.array.com_google_android_gms_fonts_certs
|
||||||
)
|
)
|
||||||
|
FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
|
||||||
// val efp = koin.koinContext.get<EmojiCompatFontProvider>()
|
|
||||||
FontsContractCompat.requestFont(this, fontRequest, koin.koinContext.get<EmojiCompatFontProvider>(), getFontThreadHandler())
|
|
||||||
|
|
||||||
vectorConfiguration.initConfiguration()
|
vectorConfiguration.initConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun injector(): VectorComponent {
|
||||||
|
return vectorComponent
|
||||||
|
}
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context) {
|
override fun attachBaseContext(base: Context) {
|
||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
MultiDex.install(this)
|
MultiDex.install(this)
|
||||||
@ -103,12 +92,15 @@ class VectorApplication : Application() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getFontThreadHandler(): Handler {
|
private fun getFontThreadHandler(): Handler {
|
||||||
if (mFontThreadHandler == null) {
|
return fontThreadHandler ?: createFontThreadHandler().also {
|
||||||
|
fontThreadHandler = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFontThreadHandler(): Handler {
|
||||||
val handlerThread = HandlerThread("fonts")
|
val handlerThread = HandlerThread("fonts")
|
||||||
handlerThread.start()
|
handlerThread.start()
|
||||||
mFontThreadHandler = Handler(handlerThread.looper)
|
return Handler(handlerThread.looper)
|
||||||
}
|
|
||||||
return mFontThreadHandler!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,107 +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.core.di
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Context.MODE_PRIVATE
|
|
||||||
import im.vector.matrix.android.api.Matrix
|
|
||||||
import im.vector.riotredesign.EmojiCompatFontProvider
|
|
||||||
import im.vector.riotredesign.core.error.ErrorFormatter
|
|
||||||
import im.vector.riotredesign.core.resources.LocaleProvider
|
|
||||||
import im.vector.riotredesign.core.resources.StringArrayProvider
|
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
|
||||||
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.HomeRoomListObservableStore
|
|
||||||
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
|
||||||
import im.vector.riotredesign.features.home.room.list.AlphabeticalRoomComparator
|
|
||||||
import im.vector.riotredesign.features.home.room.list.ChronologicalRoomComparator
|
|
||||||
import im.vector.riotredesign.features.navigation.DefaultNavigator
|
|
||||||
import im.vector.riotredesign.features.navigation.Navigator
|
|
||||||
import im.vector.riotredesign.features.notifications.NotificationDrawerManager
|
|
||||||
import org.koin.dsl.module.module
|
|
||||||
|
|
||||||
class AppModule(private val context: Context) {
|
|
||||||
|
|
||||||
val definition = module {
|
|
||||||
|
|
||||||
single {
|
|
||||||
VectorConfiguration(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
LocaleProvider(context.resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
StringProvider(context.resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
StringArrayProvider(context.resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
context.getSharedPreferences("im.vector.riot", MODE_PRIVATE)
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
SelectedGroupStore()
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
HomeRoomListObservableStore()
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
ChronologicalRoomComparator()
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
AlphabeticalRoomComparator()
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
ErrorFormatter(get())
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
NotificationDrawerManager(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
factory {
|
|
||||||
Matrix.getInstance().currentSession!!
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
KeyRequestHandler(context, get())
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
IncomingVerificationRequestHandler(context, get())
|
|
||||||
}
|
|
||||||
|
|
||||||
factory {
|
|
||||||
DefaultNavigator() as Navigator
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
EmojiCompatFontProvider()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
interface HasInjector<C> {
|
||||||
|
|
||||||
|
fun injector(): C
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import dagger.BindsInstance
|
||||||
|
import dagger.Component
|
||||||
|
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
|
||||||
|
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupSettingsFragment
|
||||||
|
import im.vector.riotredesign.features.home.HomeActivity
|
||||||
|
import im.vector.riotredesign.features.home.HomeModule
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerFragment
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment
|
||||||
|
|
||||||
|
@Component(dependencies = [VectorComponent::class], modules = [ViewModelModule::class, HomeModule::class])
|
||||||
|
@ScreenScope
|
||||||
|
interface ScreenComponent {
|
||||||
|
|
||||||
|
fun viewModelFactory(): ViewModelProvider.Factory
|
||||||
|
|
||||||
|
fun inject(activity: SimpleFragmentActivity)
|
||||||
|
|
||||||
|
fun inject(activity: HomeActivity)
|
||||||
|
|
||||||
|
fun inject(roomDetailFragment: RoomDetailFragment)
|
||||||
|
|
||||||
|
fun inject(roomDirectoryPickerFragment: RoomDirectoryPickerFragment)
|
||||||
|
|
||||||
|
fun inject(roomPreviewNoPreviewFragment: RoomPreviewNoPreviewFragment)
|
||||||
|
|
||||||
|
fun inject(keysBackupSettingsFragment: KeysBackupSettingsFragment)
|
||||||
|
|
||||||
|
@Component.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(vectorComponent: VectorComponent,
|
||||||
|
@BindsInstance context: AppCompatActivity
|
||||||
|
): ScreenComponent
|
||||||
|
}
|
||||||
|
}
|
@ -14,22 +14,18 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.riotredesign.features.crypto.keysbackup
|
package im.vector.riotredesign.core.di
|
||||||
|
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupSettingsRecyclerViewController
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import org.koin.dsl.module.module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
|
|
||||||
class KeysBackupModule {
|
@Module
|
||||||
|
object ScreenModule {
|
||||||
|
|
||||||
companion object {
|
@Provides
|
||||||
const val KEYS_BACKUP_SCOPE = "KEYS_BACKUP_SCOPE"
|
@JvmStatic
|
||||||
}
|
fun providesGlideRequests(context: AppCompatActivity) = GlideApp.with(context)
|
||||||
|
|
||||||
val definition = module(override = true) {
|
|
||||||
|
|
||||||
scope(KEYS_BACKUP_SCOPE) {
|
|
||||||
KeysBackupSettingsRecyclerViewController(get(), get())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
|
import javax.inject.Scope;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
@Scope
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
public @interface ScreenScope {}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import com.squareup.inject.assisted.dagger2.AssistedModule
|
||||||
|
import dagger.Module
|
||||||
|
|
||||||
|
/*
|
||||||
|
@Module(includes = [AssistedInject_VectorAssistedModule::class])
|
||||||
|
@AssistedModule
|
||||||
|
class VectorAssistedModule*/
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
|
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.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.HomeRoomListObservableStore
|
||||||
|
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
||||||
|
import im.vector.riotredesign.features.navigation.Navigator
|
||||||
|
import im.vector.riotredesign.features.notifications.NotificationDrawerManager
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Component(modules = [VectorModule::class])
|
||||||
|
@Singleton
|
||||||
|
interface VectorComponent {
|
||||||
|
|
||||||
|
fun matrix(): Matrix
|
||||||
|
|
||||||
|
fun currentSession(): Session
|
||||||
|
|
||||||
|
fun notificationDrawerManager(): NotificationDrawerManager
|
||||||
|
|
||||||
|
fun appContext(): Context
|
||||||
|
|
||||||
|
fun resources(): Resources
|
||||||
|
|
||||||
|
fun vectorConfiguration(): VectorConfiguration
|
||||||
|
|
||||||
|
fun navigator(): Navigator
|
||||||
|
|
||||||
|
fun homeRoomListObservableStore(): HomeRoomListObservableStore
|
||||||
|
|
||||||
|
fun selectedGroupStore(): SelectedGroupStore
|
||||||
|
|
||||||
|
fun incomingVerificationRequestHandler(): IncomingVerificationRequestHandler
|
||||||
|
|
||||||
|
fun incomingKeyRequestHandler(): KeyRequestHandler
|
||||||
|
|
||||||
|
@Component.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(@BindsInstance context: Context): VectorComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Context.MODE_PRIVATE
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.content.res.Resources
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import im.vector.matrix.android.api.Matrix
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.riotredesign.features.navigation.DefaultNavigator
|
||||||
|
import im.vector.riotredesign.features.navigation.Navigator
|
||||||
|
|
||||||
|
@Module
|
||||||
|
abstract class VectorModule {
|
||||||
|
|
||||||
|
@Module
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
fun providesResources(context: Context): Resources {
|
||||||
|
return context.resources
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
fun providesSharedPreferences(context: Context): SharedPreferences {
|
||||||
|
return context.getSharedPreferences("im.vector.riot", MODE_PRIVATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
fun providesMatrix(): Matrix {
|
||||||
|
return Matrix.getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@JvmStatic
|
||||||
|
fun providesCurrentSession(matrix: Matrix): Session {
|
||||||
|
//TODO: handle session injection better
|
||||||
|
return matrix.currentSession!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindNavigator(navigator: DefaultNavigator): Navigator
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Provider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewModelFactory which uses Dagger to create the instances.
|
||||||
|
*/
|
||||||
|
class VectorViewModelFactory @Inject constructor(
|
||||||
|
private val creators: @JvmSuppressWildcards Map<Class<out ViewModel>, Provider<ViewModel>>
|
||||||
|
) : ViewModelProvider.Factory {
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
var creator: Provider<out ViewModel>? = creators[modelClass]
|
||||||
|
if (creator == null) {
|
||||||
|
for ((key, value) in creators) {
|
||||||
|
if (modelClass.isAssignableFrom(key)) {
|
||||||
|
creator = value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (creator == null) {
|
||||||
|
throw IllegalArgumentException("Unknown model class: $modelClass")
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return creator.get() as T
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import dagger.MapKey
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@MapKey
|
||||||
|
annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.di
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.multibindings.IntoMap
|
||||||
|
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
|
||||||
|
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupSettingsViewModel
|
||||||
|
import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupSettingsViewModel_AssistedFactory
|
||||||
|
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel
|
||||||
|
import im.vector.riotredesign.features.crypto.verification.SasVerificationViewModel
|
||||||
|
import im.vector.riotredesign.features.home.HomeActivityViewModel
|
||||||
|
import im.vector.riotredesign.features.home.HomeActivityViewModel_AssistedFactory
|
||||||
|
import im.vector.riotredesign.features.home.HomeDetailViewModel
|
||||||
|
import im.vector.riotredesign.features.home.HomeDetailViewModel_AssistedFactory
|
||||||
|
import im.vector.riotredesign.features.home.HomeNavigationViewModel
|
||||||
|
import im.vector.riotredesign.features.home.group.GroupListViewModel
|
||||||
|
import im.vector.riotredesign.features.home.group.GroupListViewModel_AssistedFactory
|
||||||
|
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.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.picker.RoomDirectoryPickerViewModel
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerViewModel_AssistedFactory
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewViewModel
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewViewModel_AssistedFactory
|
||||||
|
import im.vector.riotredesign.features.workers.signout.SignOutViewModel
|
||||||
|
|
||||||
|
@Module
|
||||||
|
interface ViewModelModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bindViewModelFactory(factory: VectorViewModelFactory): ViewModelProvider.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(SignOutViewModel::class)
|
||||||
|
fun bindSignOutViewModel(viewModel: SignOutViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(EmojiChooserViewModel::class)
|
||||||
|
fun bindEmojiChooserViewModel(viewModel: EmojiChooserViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(SasVerificationViewModel::class)
|
||||||
|
fun bindSasVerificationViewModel(viewModel: SasVerificationViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(KeysBackupRestoreFromKeyViewModel::class)
|
||||||
|
fun bindKeysBackupRestoreFromKeyViewModel(viewModel: KeysBackupRestoreFromKeyViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(KeysBackupRestoreSharedViewModel::class)
|
||||||
|
fun bindKeysBackupRestoreSharedViewModel(viewModel: KeysBackupRestoreSharedViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(KeysBackupRestoreFromPassphraseViewModel::class)
|
||||||
|
fun bindKeysBackupRestoreFromPassphraseViewModel(viewModel: KeysBackupRestoreFromPassphraseViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(RoomDirectoryNavigationViewModel::class)
|
||||||
|
fun bindRoomDirectoryNavigationViewModel(viewModel: RoomDirectoryNavigationViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(HomeNavigationViewModel::class)
|
||||||
|
fun bindHomeNavigationViewModel(viewModel: HomeNavigationViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(KeysBackupSetupSharedViewModel::class)
|
||||||
|
fun bindKeysBackupSetupSharedViewModel(viewModel: KeysBackupSetupSharedViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_HomeActivityViewModel(factory: HomeActivityViewModel_AssistedFactory): HomeActivityViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_detail_composer_TextComposerViewModel(factory: TextComposerViewModel_AssistedFactory): TextComposerViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_detail_RoomDetailViewModel(factory: RoomDetailViewModel_AssistedFactory): RoomDetailViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_QuickReactionViewModel(factory: QuickReactionViewModel_AssistedFactory): QuickReactionViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_MessageActionsViewModel(factory: MessageActionsViewModel_AssistedFactory): MessageActionsViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_detail_timeline_action_MessageMenuViewModel(factory: MessageMenuViewModel_AssistedFactory): MessageMenuViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_room_list_RoomListViewModel(factory: RoomListViewModel_AssistedFactory): RoomListViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_group_GroupListViewModel(factory: GroupListViewModel_AssistedFactory): GroupListViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_home_HomeDetailViewModel(factory: HomeDetailViewModel_AssistedFactory): HomeDetailViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_crypto_keysbackup_settings_KeysBackupSettingsViewModel(factory: KeysBackupSettingsViewModel_AssistedFactory): KeysBackupSettingsViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_roomdirectory_picker_RoomDirectoryPickerViewModel(factory: RoomDirectoryPickerViewModel_AssistedFactory): RoomDirectoryPickerViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_roomdirectory_RoomDirectoryViewModel(factory: RoomDirectoryViewModel_AssistedFactory): RoomDirectoryViewModel.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
fun bind_im_vector_riotredesign_features_roomdirectory_roompreview_RoomPreviewViewModel(factory: RoomPreviewViewModel_AssistedFactory): RoomPreviewViewModel.Factory
|
||||||
|
|
||||||
|
}
|
@ -19,8 +19,9 @@ package im.vector.riotredesign.core.error
|
|||||||
import im.vector.matrix.android.api.failure.Failure
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ErrorFormatter(val stringProvider: StringProvider) {
|
class ErrorFormatter @Inject constructor(val stringProvider: StringProvider) {
|
||||||
|
|
||||||
|
|
||||||
fun toHumanReadable(failure: Failure): String {
|
fun toHumanReadable(failure: Failure): String {
|
||||||
|
@ -21,13 +21,12 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
||||||
import org.koin.standalone.KoinComponent
|
|
||||||
import org.koin.standalone.inject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ConfigurationViewModel : ViewModel(), KoinComponent {
|
class ConfigurationViewModel @Inject constructor(
|
||||||
|
private val vectorConfiguration: VectorConfiguration
|
||||||
private val vectorConfiguration: VectorConfiguration by inject()
|
) : ViewModel() {
|
||||||
|
|
||||||
private var currentConfigurationValue: String? = null
|
private var currentConfigurationValue: String? = null
|
||||||
|
|
||||||
@ -47,7 +46,6 @@ class ConfigurationViewModel : ViewModel(), KoinComponent {
|
|||||||
if (newHash != currentConfigurationValue) {
|
if (newHash != currentConfigurationValue) {
|
||||||
Timber.v("Configuration: recreate the Activity")
|
Timber.v("Configuration: recreate the Activity")
|
||||||
currentConfigurationValue = newHash
|
currentConfigurationValue = newHash
|
||||||
|
|
||||||
_activityRestarter.postValue(LiveEvent(Unit))
|
_activityRestarter.postValue(LiveEvent(Unit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.riotredesign.core.platform
|
package im.vector.riotredesign.core.platform
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@ -25,7 +26,7 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.hideKeyboard
|
import im.vector.riotredesign.core.extensions.hideKeyboard
|
||||||
import kotlinx.android.synthetic.main.activity.*
|
import kotlinx.android.synthetic.main.activity.*
|
||||||
import org.koin.android.ext.android.get
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple activity with a toolbar, a waiting overlay, and a fragment container and a session.
|
* Simple activity with a toolbar, a waiting overlay, and a fragment container and a session.
|
||||||
@ -43,7 +44,13 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
|
|||||||
@BindView(R.id.waiting_view_status_horizontal_progress)
|
@BindView(R.id.waiting_view_status_horizontal_progress)
|
||||||
lateinit var waitingHorizontalProgress: ProgressBar
|
lateinit var waitingHorizontalProgress: ProgressBar
|
||||||
|
|
||||||
protected val session = get<Session>()
|
@Inject
|
||||||
|
lateinit var session: Session
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
injector().inject(this)
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
configureToolbar(toolbar)
|
configureToolbar(toolbar)
|
||||||
|
@ -22,35 +22,48 @@ import android.os.Bundle
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.*
|
import androidx.annotation.AttrRes
|
||||||
|
import androidx.annotation.LayoutRes
|
||||||
|
import androidx.annotation.MainThread
|
||||||
|
import androidx.annotation.MenuRes
|
||||||
|
import androidx.annotation.Nullable
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.ButterKnife
|
import butterknife.ButterKnife
|
||||||
import butterknife.Unbinder
|
import butterknife.Unbinder
|
||||||
import com.airbnb.mvrx.BaseMvRxActivity
|
import com.airbnb.mvrx.BaseMvRxActivity
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.bumptech.glide.util.Util
|
import com.bumptech.glide.util.Util
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import im.vector.riotredesign.BuildConfig
|
import im.vector.riotredesign.BuildConfig
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.di.HasInjector
|
||||||
|
import im.vector.riotredesign.core.di.ScreenComponent
|
||||||
import im.vector.riotredesign.core.utils.toast
|
import im.vector.riotredesign.core.utils.toast
|
||||||
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
import im.vector.riotredesign.features.configuration.VectorConfiguration
|
||||||
import im.vector.riotredesign.features.rageshake.BugReportActivity
|
import im.vector.riotredesign.features.rageshake.BugReportActivity
|
||||||
import im.vector.riotredesign.features.rageshake.BugReporter
|
import im.vector.riotredesign.features.rageshake.BugReporter
|
||||||
import im.vector.riotredesign.features.rageshake.RageShake
|
import im.vector.riotredesign.features.rageshake.RageShake
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.PublicRoomsViewState
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryViewModel
|
||||||
import im.vector.riotredesign.features.themes.ActivityOtherThemes
|
import im.vector.riotredesign.features.themes.ActivityOtherThemes
|
||||||
import im.vector.riotredesign.features.themes.ThemeUtils
|
import im.vector.riotredesign.features.themes.ThemeUtils
|
||||||
import im.vector.riotredesign.receivers.DebugReceiver
|
import im.vector.riotredesign.receivers.DebugReceiver
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Provider
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
abstract class VectorBaseActivity : BaseMvRxActivity() {
|
abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenComponent> {
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* UI
|
* UI
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
@ -64,8 +77,8 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
|
|||||||
* DATA
|
* DATA
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
|
||||||
private val vectorConfiguration: VectorConfiguration by inject()
|
protected lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
private lateinit var vectorConfiguration: VectorConfiguration
|
||||||
private lateinit var configurationViewModel: ConfigurationViewModel
|
private lateinit var configurationViewModel: ConfigurationViewModel
|
||||||
|
|
||||||
private var unBinder: Unbinder? = null
|
private var unBinder: Unbinder? = null
|
||||||
@ -79,6 +92,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
|
|||||||
private val restorables = ArrayList<Restorable>()
|
private val restorables = ArrayList<Restorable>()
|
||||||
|
|
||||||
private var rageShake: RageShake? = null
|
private var rageShake: RageShake? = null
|
||||||
|
private lateinit var screenComponent: ScreenComponent
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context) {
|
override fun attachBaseContext(base: Context) {
|
||||||
super.attachBaseContext(vectorConfiguration.getLocalisedContext(base))
|
super.attachBaseContext(vectorConfiguration.getLocalisedContext(base))
|
||||||
@ -107,10 +121,9 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java)
|
||||||
configurationViewModel = ViewModelProviders.of(this).get(ConfigurationViewModel::class.java)
|
|
||||||
|
|
||||||
configurationViewModel.activityRestarter.observe(this, Observer {
|
configurationViewModel.activityRestarter.observe(this, Observer {
|
||||||
if (!it.hasBeenHandled) {
|
if (!it.hasBeenHandled) {
|
||||||
// Recreate the Activity because configuration has changed
|
// Recreate the Activity because configuration has changed
|
||||||
@ -202,6 +215,10 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun injector(): ScreenComponent {
|
||||||
|
return screenComponent
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* PRIVATE METHODS
|
* PRIVATE METHODS
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -18,24 +18,29 @@ package im.vector.riotredesign.core.platform
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.*
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import butterknife.ButterKnife
|
import butterknife.ButterKnife
|
||||||
import butterknife.Unbinder
|
import butterknife.Unbinder
|
||||||
import com.airbnb.mvrx.BaseMvRxFragment
|
import com.airbnb.mvrx.BaseMvRxFragment
|
||||||
import com.airbnb.mvrx.MvRx
|
import com.airbnb.mvrx.MvRx
|
||||||
import com.bumptech.glide.util.Util.assertMainThread
|
import com.bumptech.glide.util.Util.assertMainThread
|
||||||
|
import im.vector.riotredesign.core.di.HasInjector
|
||||||
|
import im.vector.riotredesign.core.di.ScreenComponent
|
||||||
import im.vector.riotredesign.features.navigation.Navigator
|
import im.vector.riotredesign.features.navigation.Navigator
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import org.koin.core.parameter.parametersOf
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
|
abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasInjector<ScreenComponent> {
|
||||||
|
|
||||||
// Butterknife unbinder
|
// Butterknife unbinder
|
||||||
private var mUnBinder: Unbinder? = null
|
private var mUnBinder: Unbinder? = null
|
||||||
@ -48,7 +53,8 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
|
|||||||
* Navigator
|
* Navigator
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
|
||||||
protected val navigator: Navigator by inject { parametersOf(this) }
|
protected lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
protected lateinit var navigator: Navigator
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Life cycle
|
* Life cycle
|
||||||
@ -57,7 +63,6 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
|
|||||||
@CallSuper
|
@CallSuper
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
if (getMenuRes() != -1) {
|
if (getMenuRes() != -1) {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
@ -92,10 +97,13 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|
||||||
uiDisposables.dispose()
|
uiDisposables.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun injector(): ScreenComponent {
|
||||||
|
return vectorBaseActivity.injector()
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Restorable
|
* Restorable
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -18,14 +18,15 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.core.resources
|
package im.vector.riotredesign.core.resources
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import im.vector.riotredesign.features.themes.ThemeUtils
|
import im.vector.riotredesign.features.themes.ThemeUtils
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ColorProvider(private val context: Context) {
|
class ColorProvider @Inject constructor(private val context: AppCompatActivity) {
|
||||||
|
|
||||||
fun getColor(@ColorRes colorRes: Int): Int {
|
fun getColor(@ColorRes colorRes: Int): Int {
|
||||||
return ContextCompat.getColor(context, colorRes)
|
return ContextCompat.getColor(context, colorRes)
|
||||||
|
@ -19,8 +19,9 @@ package im.vector.riotredesign.core.resources
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LocaleProvider(private val resources: Resources) {
|
class LocaleProvider @Inject constructor(private val resources: Resources) {
|
||||||
|
|
||||||
fun current(): Locale {
|
fun current(): Locale {
|
||||||
return ConfigurationCompat.getLocales(resources.configuration)[0]
|
return ConfigurationCompat.getLocales(resources.configuration)[0]
|
||||||
|
@ -19,8 +19,9 @@ package im.vector.riotredesign.core.resources
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import androidx.annotation.ArrayRes
|
import androidx.annotation.ArrayRes
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class StringArrayProvider(private val resources: Resources) {
|
class StringArrayProvider @Inject constructor(private val resources: Resources) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a localized string array from the application's package's
|
* Returns a localized string array from the application's package's
|
||||||
|
@ -20,8 +20,9 @@ import android.content.res.Resources
|
|||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.annotation.PluralsRes
|
import androidx.annotation.PluralsRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class StringProvider(private val resources: Resources) {
|
class StringProvider @Inject constructor(private val resources: Resources) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a localized string from the application's package's
|
* Returns a localized string from the application's package's
|
||||||
|
@ -28,7 +28,6 @@ import im.vector.matrix.android.api.session.events.model.Event
|
|||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.features.notifications.NotifiableEventResolver
|
import im.vector.riotredesign.features.notifications.NotifiableEventResolver
|
||||||
import im.vector.riotredesign.features.notifications.NotificationUtils
|
import im.vector.riotredesign.features.notifications.NotificationUtils
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
@ -20,8 +20,9 @@ import com.airbnb.epoxy.TypedEpoxyController
|
|||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.features.autocomplete.AutocompleteClickListener
|
import im.vector.riotredesign.features.autocomplete.AutocompleteClickListener
|
||||||
import im.vector.riotredesign.features.command.Command
|
import im.vector.riotredesign.features.command.Command
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteCommandController(private val stringProvider: StringProvider) : TypedEpoxyController<List<Command>>() {
|
class AutocompleteCommandController @Inject constructor(private val stringProvider: StringProvider) : TypedEpoxyController<List<Command>>() {
|
||||||
|
|
||||||
var listener: AutocompleteClickListener<Command>? = null
|
var listener: AutocompleteClickListener<Command>? = null
|
||||||
|
|
||||||
|
@ -20,8 +20,9 @@ import android.content.Context
|
|||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import im.vector.riotredesign.features.autocomplete.EpoxyAutocompletePresenter
|
import im.vector.riotredesign.features.autocomplete.EpoxyAutocompletePresenter
|
||||||
import im.vector.riotredesign.features.command.Command
|
import im.vector.riotredesign.features.command.Command
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteCommandPresenter(context: Context,
|
class AutocompleteCommandPresenter @Inject constructor(context: Context,
|
||||||
private val controller: AutocompleteCommandController) :
|
private val controller: AutocompleteCommandController) :
|
||||||
EpoxyAutocompletePresenter<Command>(context) {
|
EpoxyAutocompletePresenter<Command>(context) {
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ package im.vector.riotredesign.features.autocomplete.command
|
|||||||
|
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import com.otaliastudios.autocomplete.AutocompletePolicy
|
import com.otaliastudios.autocomplete.AutocompletePolicy
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CommandAutocompletePolicy : AutocompletePolicy {
|
class CommandAutocompletePolicy @Inject constructor() : AutocompletePolicy {
|
||||||
|
|
||||||
var enabled: Boolean = true
|
var enabled: Boolean = true
|
||||||
|
|
||||||
|
@ -19,8 +19,9 @@ package im.vector.riotredesign.features.autocomplete.user
|
|||||||
import com.airbnb.epoxy.TypedEpoxyController
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotredesign.features.autocomplete.AutocompleteClickListener
|
import im.vector.riotredesign.features.autocomplete.AutocompleteClickListener
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteUserController : TypedEpoxyController<List<User>>() {
|
class AutocompleteUserController @Inject constructor(): TypedEpoxyController<List<User>>() {
|
||||||
|
|
||||||
var listener: AutocompleteClickListener<User>? = null
|
var listener: AutocompleteClickListener<User>? = null
|
||||||
|
|
||||||
|
@ -22,8 +22,9 @@ import com.airbnb.mvrx.Async
|
|||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotredesign.features.autocomplete.EpoxyAutocompletePresenter
|
import im.vector.riotredesign.features.autocomplete.EpoxyAutocompletePresenter
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AutocompleteUserPresenter(context: Context,
|
class AutocompleteUserPresenter @Inject constructor(context: Context,
|
||||||
private val controller: AutocompleteUserController
|
private val controller: AutocompleteUserController
|
||||||
) : EpoxyAutocompletePresenter<User>(context) {
|
) : EpoxyAutocompletePresenter<User>(context) {
|
||||||
|
|
||||||
|
@ -25,11 +25,13 @@ import im.vector.riotredesign.features.settings.VectorLocale
|
|||||||
import im.vector.riotredesign.features.themes.ThemeUtils
|
import im.vector.riotredesign.features.themes.ThemeUtils
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle locale configuration change, such as theme, font size and locale chosen by the user
|
* Handle locale configuration change, such as theme, font size and locale chosen by the user
|
||||||
*/
|
*/
|
||||||
class VectorConfiguration(private val context: Context) {
|
|
||||||
|
class VectorConfiguration @Inject constructor(private val context: Context) {
|
||||||
|
|
||||||
// TODO Import mLanguageReceiver From Riot?
|
// TODO Import mLanguageReceiver From Riot?
|
||||||
fun onConfigurationChanged(newConfig: Configuration?) {
|
fun onConfigurationChanged(newConfig: Configuration?) {
|
||||||
|
@ -23,7 +23,6 @@ import androidx.fragment.app.FragmentManager
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment
|
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
|
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
|
||||||
@ -43,9 +42,8 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
|||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
super.initUiAndData()
|
super.initUiAndData()
|
||||||
viewModel = ViewModelProviders.of(this).get(KeysBackupRestoreSharedViewModel::class.java)
|
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java)
|
||||||
viewModel.initSession(session)
|
viewModel.initSession(session)
|
||||||
|
|
||||||
viewModel.keyVersionResult.observe(this, Observer { keyVersion ->
|
viewModel.keyVersionResult.observe(this, Observer { keyVersion ->
|
||||||
|
|
||||||
if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) {
|
if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) {
|
||||||
|
@ -27,7 +27,6 @@ import butterknife.BindView
|
|||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import butterknife.OnTextChanged
|
import butterknife.OnTextChanged
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.startImportTextFromFileIntent
|
import im.vector.riotredesign.core.utils.startImportTextFromFileIntent
|
||||||
@ -53,9 +52,9 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() {
|
|||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
viewModel = ViewModelProviders.of(this).get(KeysBackupRestoreFromKeyViewModel::class.java)
|
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java)
|
||||||
sharedViewModel = activity?.run {
|
sharedViewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupRestoreSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
mKeyTextEdit.setText(viewModel.recoveryCode.value)
|
mKeyTextEdit.setText(viewModel.recoveryCode.value)
|
||||||
|
@ -18,7 +18,6 @@ package im.vector.riotredesign.features.crypto.keysbackup.restore
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.listeners.StepProgressListener
|
import im.vector.matrix.android.api.listeners.StepProgressListener
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
||||||
@ -28,8 +27,9 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.core.ui.views.KeysBackupBanner
|
import im.vector.riotredesign.core.ui.views.KeysBackupBanner
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KeysBackupRestoreFromKeyViewModel : ViewModel() {
|
class KeysBackupRestoreFromKeyViewModel @Inject constructor() : ViewModel() {
|
||||||
|
|
||||||
var recoveryCode: MutableLiveData<String> = MutableLiveData()
|
var recoveryCode: MutableLiveData<String> = MutableLiveData()
|
||||||
var recoveryCodeErrorText: MutableLiveData<String> = MutableLiveData()
|
var recoveryCodeErrorText: MutableLiveData<String> = MutableLiveData()
|
||||||
|
@ -36,6 +36,7 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.extensions.showPassword
|
import im.vector.riotredesign.core.extensions.showPassword
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
|
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
|
||||||
|
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
||||||
|
|
||||||
class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
||||||
|
|
||||||
@ -68,9 +69,9 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel = ViewModelProviders.of(this).get(KeysBackupRestoreFromPassphraseViewModel::class.java)
|
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromPassphraseViewModel::class.java)
|
||||||
sharedViewModel = activity?.run {
|
sharedViewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupRestoreSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ package im.vector.riotredesign.features.crypto.keysbackup.restore
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.listeners.StepProgressListener
|
import im.vector.matrix.android.api.listeners.StepProgressListener
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
||||||
@ -28,8 +27,9 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.core.ui.views.KeysBackupBanner
|
import im.vector.riotredesign.core.ui.views.KeysBackupBanner
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KeysBackupRestoreFromPassphraseViewModel : ViewModel() {
|
class KeysBackupRestoreFromPassphraseViewModel @Inject constructor() : ViewModel() {
|
||||||
|
|
||||||
var passphrase: MutableLiveData<String> = MutableLiveData()
|
var passphrase: MutableLiveData<String> = MutableLiveData()
|
||||||
var passphraseErrorText: MutableLiveData<String> = MutableLiveData()
|
var passphraseErrorText: MutableLiveData<String> = MutableLiveData()
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package im.vector.fragments.keysbackup.restore
|
package im.vector.riotredesign.features.crypto.keysbackup.restore
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
@ -21,13 +21,14 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KeysBackupRestoreSharedViewModel : ViewModel() {
|
class KeysBackupRestoreSharedViewModel @Inject constructor() : ViewModel() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val NAVIGATE_TO_RECOVER_WITH_KEY = "NAVIGATE_TO_RECOVER_WITH_KEY"
|
const val NAVIGATE_TO_RECOVER_WITH_KEY = "NAVIGATE_TO_RECOVER_WITH_KEY"
|
||||||
|
@ -20,7 +20,6 @@ import android.widget.TextView
|
|||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import im.vector.fragments.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
@ -40,7 +39,7 @@ class KeysBackupRestoreSuccessFragment : VectorBaseFragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
sharedViewModel = activity?.run {
|
sharedViewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupRestoreSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
sharedViewModel.importKeyResult?.let {
|
sharedViewModel.importKeyResult?.let {
|
||||||
|
@ -17,16 +17,16 @@ package im.vector.riotredesign.features.crypto.keysbackup.settings
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.viewModel
|
import com.airbnb.mvrx.viewModel
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.injector
|
||||||
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
|
import im.vector.riotredesign.core.platform.SimpleFragmentActivity
|
||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.KeysBackupModule
|
import javax.inject.Inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
|
||||||
|
|
||||||
|
|
||||||
class KeysBackupManageActivity : SimpleFragmentActivity() {
|
class KeysBackupManageActivity : SimpleFragmentActivity() {
|
||||||
@ -41,12 +41,15 @@ class KeysBackupManageActivity : SimpleFragmentActivity() {
|
|||||||
override fun getTitleRes() = R.string.encryption_message_recovery
|
override fun getTitleRes() = R.string.encryption_message_recovery
|
||||||
|
|
||||||
private val viewModel: KeysBackupSettingsViewModel by viewModel()
|
private val viewModel: KeysBackupSettingsViewModel by viewModel()
|
||||||
|
@Inject lateinit var keysBackupSettingsViewModelFactory: KeysBackupSettingsViewModel.Factory
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
injector.inject(this)
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
super.initUiAndData()
|
super.initUiAndData()
|
||||||
|
|
||||||
bindScope(getOrCreateScope(KeysBackupModule.KEYS_BACKUP_SCOPE))
|
|
||||||
|
|
||||||
if (supportFragmentManager.fragments.isEmpty()) {
|
if (supportFragmentManager.fragments.isEmpty()) {
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.container, KeysBackupSettingsFragment.newInstance())
|
.replace(R.id.container, KeysBackupSettingsFragment.newInstance())
|
||||||
|
@ -21,14 +21,12 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.injector
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.KeysBackupModule
|
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
import im.vector.riotredesign.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||||
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
||||||
import kotlinx.android.synthetic.main.fragment_keys_backup_settings.*
|
import kotlinx.android.synthetic.main.fragment_keys_backup_settings.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
|
||||||
|
|
||||||
class KeysBackupSettingsFragment : VectorBaseFragment(),
|
class KeysBackupSettingsFragment : VectorBaseFragment(),
|
||||||
KeysBackupSettingsRecyclerViewController.Listener {
|
KeysBackupSettingsRecyclerViewController.Listener {
|
||||||
@ -39,14 +37,12 @@ class KeysBackupSettingsFragment : VectorBaseFragment(),
|
|||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_settings
|
override fun getLayoutResId() = R.layout.fragment_keys_backup_settings
|
||||||
|
|
||||||
private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController by inject()
|
@Inject lateinit var keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController
|
||||||
|
|
||||||
private val viewModel: KeysBackupSettingsViewModel by activityViewModel()
|
private val viewModel: KeysBackupSettingsViewModel by activityViewModel()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
injector().inject(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
bindScope(getOrCreateScope(KeysBackupModule.KEYS_BACKUP_SCOPE))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
@ -17,11 +17,14 @@ package im.vector.riotredesign.features.crypto.keysbackup.settings
|
|||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.airbnb.epoxy.TypedEpoxyController
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.matrix.android.api.session.Session
|
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.crypto.keysbackup.KeysBackupState
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrust
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrust
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.errorWithRetryItem
|
import im.vector.riotredesign.core.epoxy.errorWithRetryItem
|
||||||
import im.vector.riotredesign.core.epoxy.loadingItem
|
import im.vector.riotredesign.core.epoxy.loadingItem
|
||||||
@ -29,8 +32,9 @@ import im.vector.riotredesign.core.resources.StringProvider
|
|||||||
import im.vector.riotredesign.core.ui.list.GenericItem
|
import im.vector.riotredesign.core.ui.list.GenericItem
|
||||||
import im.vector.riotredesign.core.ui.list.genericItem
|
import im.vector.riotredesign.core.ui.list.genericItem
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KeysBackupSettingsRecyclerViewController(val stringProvider: StringProvider,
|
class KeysBackupSettingsRecyclerViewController @Inject constructor(val stringProvider: StringProvider,
|
||||||
val session: Session) : TypedEpoxyController<KeysBackupSettingViewState>() {
|
val session: Session) : TypedEpoxyController<KeysBackupSettingViewState>() {
|
||||||
|
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
@ -15,7 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.riotredesign.features.crypto.keysbackup.settings
|
package im.vector.riotredesign.features.crypto.keysbackup.settings
|
||||||
|
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.ActivityViewModelContext
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
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.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
||||||
@ -23,33 +31,37 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
|||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrust
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrust
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
|
|
||||||
|
|
||||||
class KeysBackupSettingsViewModel(initialState: KeysBackupSettingViewState,
|
class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState,
|
||||||
session: Session) : VectorViewModel<KeysBackupSettingViewState>(initialState),
|
session: Session
|
||||||
|
) : VectorViewModel<KeysBackupSettingViewState>(initialState),
|
||||||
KeysBackupStateListener {
|
KeysBackupStateListener {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: KeysBackupSettingViewState): KeysBackupSettingsViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<KeysBackupSettingsViewModel, KeysBackupSettingViewState> {
|
companion object : MvRxViewModelFactory<KeysBackupSettingsViewModel, KeysBackupSettingViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: KeysBackupSettingViewState): KeysBackupSettingsViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: KeysBackupSettingViewState): KeysBackupSettingsViewModel? {
|
||||||
val session = viewModelContext.activity.get<Session>()
|
val activity: KeysBackupManageActivity = (viewModelContext as ActivityViewModelContext).activity()
|
||||||
|
return activity.keysBackupSettingsViewModelFactory.create(state)
|
||||||
val firstState = state.copy(
|
|
||||||
keysBackupState = session.getKeysBackupService().state,
|
|
||||||
keysBackupVersion = session.getKeysBackupService().keysBackupVersion
|
|
||||||
)
|
|
||||||
|
|
||||||
return KeysBackupSettingsViewModel(firstState, session)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var keysBackupService: KeysBackupService = session.getKeysBackupService()
|
private var keysBackupService: KeysBackupService = session.getKeysBackupService()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
setState {
|
||||||
|
this.copy(
|
||||||
|
keysBackupState = session.getKeysBackupService().state,
|
||||||
|
keysBackupVersion = session.getKeysBackupService().keysBackupVersion
|
||||||
|
)
|
||||||
|
}
|
||||||
keysBackupService.addListener(this)
|
keysBackupService.addListener(this)
|
||||||
|
|
||||||
getKeysBackupTrust()
|
getKeysBackupTrust()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +102,8 @@ class KeysBackupSettingsViewModel(initialState: KeysBackupSettingViewState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
|
||||||
keysBackupService.removeListener(this)
|
keysBackupService.removeListener(this)
|
||||||
|
super.onCleared()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChange(newState: KeysBackupState) {
|
override fun onStateChange(newState: KeysBackupState) {
|
||||||
|
@ -22,7 +22,6 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.dialogs.ExportKeysDialog
|
import im.vector.riotredesign.core.dialogs.ExportKeysDialog
|
||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
@ -42,7 +41,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||||||
.commitNow()
|
.commitNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel = ViewModelProviders.of(this).get(KeysBackupSetupSharedViewModel::class.java)
|
viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||||
viewModel.showManualExport.value = intent.getBooleanExtra(EXTRA_SHOW_MANUAL_EXPORT, false)
|
viewModel.showManualExport.value = intent.getBooleanExtra(EXTRA_SHOW_MANUAL_EXPORT, false)
|
||||||
viewModel.initSession(session)
|
viewModel.initSession(session)
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.fragments.keysbackup.setup
|
package im.vector.riotredesign.features.crypto.keysbackup.setup
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@ -30,11 +30,12 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The shared view model between all fragments.
|
* The shared view model between all fragments.
|
||||||
*/
|
*/
|
||||||
class KeysBackupSetupSharedViewModel : ViewModel() {
|
class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val NAVIGATE_TO_STEP_2 = "NAVIGATE_TO_STEP_2"
|
const val NAVIGATE_TO_STEP_2 = "NAVIGATE_TO_STEP_2"
|
||||||
|
@ -24,7 +24,6 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
@ -51,7 +50,7 @@ class KeysBackupSetupStep1Fragment : VectorBaseFragment() {
|
|||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupSetupSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
viewModel.showManualExport.observe(this, Observer {
|
viewModel.showManualExport.observe(this, Observer {
|
||||||
|
@ -30,7 +30,6 @@ import butterknife.OnClick
|
|||||||
import butterknife.OnTextChanged
|
import butterknife.OnTextChanged
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.nulabinc.zxcvbn.Zxcvbn
|
import com.nulabinc.zxcvbn.Zxcvbn
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.showPassword
|
import im.vector.riotredesign.core.extensions.showPassword
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
@ -82,7 +81,7 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() {
|
|||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupSetupSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
viewModel.shouldPromptOnBack = true
|
viewModel.shouldPromptOnBack = true
|
||||||
|
@ -28,7 +28,6 @@ import androidx.lifecycle.ViewModelProviders
|
|||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.files.addEntryToDownloadManager
|
import im.vector.riotredesign.core.files.addEntryToDownloadManager
|
||||||
import im.vector.riotredesign.core.files.saveStringToFile
|
import im.vector.riotredesign.core.files.saveStringToFile
|
||||||
@ -58,7 +57,7 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(KeysBackupSetupSharedViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@ import timber.log.Timber
|
|||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
@ -50,7 +52,9 @@ import kotlin.collections.HashMap
|
|||||||
* If several requests come from same user/device, a single alert is displayed (this alert will accept/reject all request
|
* If several requests come from same user/device, a single alert is displayed (this alert will accept/reject all request
|
||||||
* depending on user action)
|
* depending on user action)
|
||||||
*/
|
*/
|
||||||
class KeyRequestHandler(val context: Context,
|
|
||||||
|
@Singleton
|
||||||
|
class KeyRequestHandler @Inject constructor(val context: Context,
|
||||||
val session: Session)
|
val session: Session)
|
||||||
: RoomKeysRequestListener,
|
: RoomKeysRequestListener,
|
||||||
SasVerificationService.SasVerificationListener {
|
SasVerificationService.SasVerificationListener {
|
||||||
@ -59,12 +63,9 @@ class KeyRequestHandler(val context: Context,
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
session.getSasVerificationService().addListener(this)
|
session.getSasVerificationService().addListener(this)
|
||||||
|
|
||||||
session.addRoomKeysRequestListener(this)
|
session.addRoomKeysRequestListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ensureStarted() = Unit
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle incoming key request.
|
* Handle incoming key request.
|
||||||
*
|
*
|
||||||
|
@ -23,19 +23,21 @@ import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransactio
|
|||||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.features.popup.PopupAlertManager
|
import im.vector.riotredesign.features.popup.PopupAlertManager
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens to the VerificationManager and add a new notification when an incoming request is detected.
|
* Listens to the VerificationManager and add a new notification when an incoming request is detected.
|
||||||
*/
|
*/
|
||||||
class IncomingVerificationRequestHandler(val context: Context,
|
@Singleton
|
||||||
private val session: Session) : SasVerificationService.SasVerificationListener {
|
class IncomingVerificationRequestHandler @Inject constructor(val context: Context,
|
||||||
|
private val session: Session
|
||||||
|
) : SasVerificationService.SasVerificationListener {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
session.getSasVerificationService().addListener(this)
|
session.getSasVerificationService().addListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ensureStarted() = Unit
|
|
||||||
|
|
||||||
override fun transactionCreated(tx: SasVerificationTransaction) {}
|
override fun transactionCreated(tx: SasVerificationTransaction) {}
|
||||||
|
|
||||||
override fun transactionUpdated(tx: SasVerificationTransaction) {
|
override fun transactionUpdated(tx: SasVerificationTransaction) {
|
||||||
|
@ -84,7 +84,7 @@ class SASVerificationActivity : SimpleFragmentActivity() {
|
|||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
super.initUiAndData()
|
super.initUiAndData()
|
||||||
viewModel = ViewModelProviders.of(this).get(SasVerificationViewModel::class.java)
|
viewModel = ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||||
val transactionID: String? = intent.getStringExtra(EXTRA_TRANSACTION_ID)
|
val transactionID: String? = intent.getStringExtra(EXTRA_TRANSACTION_ID)
|
||||||
|
|
||||||
if (isFirstCreation()) {
|
if (isFirstCreation()) {
|
||||||
|
@ -53,7 +53,7 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {
|
|||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(SasVerificationViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
otherUserDisplayNameTextView.text = viewModel.otherUser?.displayName ?: viewModel.otherUserId
|
otherUserDisplayNameTextView.text = viewModel.otherUser?.displayName ?: viewModel.otherUserId
|
||||||
|
@ -69,7 +69,7 @@ class SASVerificationShortCodeFragment : VectorBaseFragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(SasVerificationViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,11 +58,7 @@ class SASVerificationStartFragment : VectorBaseFragment() {
|
|||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
viewModel = ViewModelProviders.of(vectorBaseActivity, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||||
viewModel = activity?.run {
|
|
||||||
ViewModelProviders.of(this).get(SasVerificationViewModel::class.java)
|
|
||||||
} ?: throw Exception("Invalid Activity")
|
|
||||||
|
|
||||||
viewModel.transactionState.observe(this, Observer {
|
viewModel.transactionState.observe(this, Observer {
|
||||||
val uxState = (viewModel.transaction as? OutgoingSasVerificationRequest)?.uxState
|
val uxState = (viewModel.transaction as? OutgoingSasVerificationRequest)?.uxState
|
||||||
when (uxState) {
|
when (uxState) {
|
||||||
|
@ -35,7 +35,7 @@ class SASVerificationVerifiedFragment : VectorBaseFragment() {
|
|||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel = activity?.run {
|
viewModel = activity?.run {
|
||||||
ViewModelProviders.of(this).get(SasVerificationViewModel::class.java)
|
ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java)
|
||||||
} ?: throw Exception("Invalid Activity")
|
} ?: throw Exception("Invalid Activity")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,10 @@ import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransactio
|
|||||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class SasVerificationViewModel : ViewModel(),
|
class SasVerificationViewModel @Inject constructor() : ViewModel(),
|
||||||
SasVerificationService.SasVerificationListener {
|
SasVerificationService.SasVerificationListener {
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,9 +43,7 @@ import im.vector.riotredesign.features.rageshake.BugReporter
|
|||||||
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
|
||||||
import im.vector.riotredesign.features.workers.signout.SignOutUiWorker
|
import im.vector.riotredesign.features.workers.signout.SignOutUiWorker
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
|
||||||
|
|
||||||
|
|
||||||
class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
@ -57,12 +55,13 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||||||
|
|
||||||
private val homeActivityViewModel: HomeActivityViewModel by viewModel()
|
private val homeActivityViewModel: HomeActivityViewModel by viewModel()
|
||||||
private lateinit var navigationViewModel: HomeNavigationViewModel
|
private lateinit var navigationViewModel: HomeNavigationViewModel
|
||||||
private val homeNavigator by inject<HomeNavigator>()
|
|
||||||
|
|
||||||
|
@Inject lateinit var homeActivityViewModelFactory: HomeActivityViewModel.Factory
|
||||||
|
@Inject lateinit var homeNavigator: HomeNavigator
|
||||||
// TODO Move this elsewhere
|
// TODO Move this elsewhere
|
||||||
private val incomingVerificationRequestHandler by inject<IncomingVerificationRequestHandler>()
|
@Inject lateinit var incomingVerificationRequestHandler: IncomingVerificationRequestHandler
|
||||||
// TODO Move this elsewhere
|
// TODO Move this elsewhere
|
||||||
private val keyRequestHandler by inject<KeyRequestHandler>()
|
@Inject lateinit var keyRequestHandler: KeyRequestHandler
|
||||||
|
|
||||||
private var progress: ProgressDialog? = null
|
private var progress: ProgressDialog? = null
|
||||||
|
|
||||||
@ -76,10 +75,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
bindScope(getOrCreateScope(HomeModule.HOME_SCOPE))
|
|
||||||
homeNavigator.activity = this
|
homeNavigator.activity = this
|
||||||
|
navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(HomeNavigationViewModel::class.java)
|
||||||
navigationViewModel = ViewModelProviders.of(this).get(HomeNavigationViewModel::class.java)
|
|
||||||
|
|
||||||
drawerLayout.addDrawerListener(drawerListener)
|
drawerLayout.addDrawerListener(drawerListener)
|
||||||
if (isFirstCreation()) {
|
if (isFirstCreation()) {
|
||||||
|
@ -19,10 +19,12 @@ package im.vector.riotredesign.features.home
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
|
import com.airbnb.mvrx.ActivityViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import im.vector.matrix.android.api.Matrix
|
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.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
@ -34,28 +36,31 @@ import im.vector.riotredesign.features.home.group.ALL_COMMUNITIES_GROUP_ID
|
|||||||
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
import im.vector.riotredesign.features.home.group.SelectedGroupStore
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
data class EmptyState(val isEmpty: Boolean = true) : MvRxState
|
data class EmptyState(val isEmpty: Boolean = true) : MvRxState
|
||||||
|
|
||||||
class HomeActivityViewModel(state: EmptyState,
|
class HomeActivityViewModel @AssistedInject constructor(@Assisted initialState: EmptyState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val selectedGroupStore: SelectedGroupStore,
|
private val selectedGroupStore: SelectedGroupStore,
|
||||||
private val homeRoomListStore: HomeRoomListObservableStore
|
private val homeRoomListStore: HomeRoomListObservableStore
|
||||||
) : VectorViewModel<EmptyState>(state), Session.Listener {
|
) : VectorViewModel<EmptyState>(initialState), Session.Listener {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: EmptyState): HomeActivityViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<HomeActivityViewModel, EmptyState> {
|
companion object : MvRxViewModelFactory<HomeActivityViewModel, EmptyState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: EmptyState): HomeActivityViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: EmptyState): HomeActivityViewModel? {
|
||||||
val session = Matrix.getInstance().currentSession!!
|
val homeActivity: HomeActivity = (viewModelContext as ActivityViewModelContext).activity()
|
||||||
val selectedGroupStore = viewModelContext.activity.get<SelectedGroupStore>()
|
return homeActivity.homeActivityViewModelFactory.create(state)
|
||||||
val homeRoomListObservableSource = viewModelContext.activity.get<HomeRoomListObservableStore>()
|
|
||||||
return HomeActivityViewModel(state, session, selectedGroupStore, homeRoomListObservableSource)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val _isLoading = MutableLiveData<Boolean>()
|
private val _isLoading = MutableLiveData<Boolean>()
|
||||||
val isLoading: LiveData<Boolean>
|
val isLoading: LiveData<Boolean>
|
||||||
get() = _isLoading
|
get() = _isLoading
|
||||||
|
@ -41,7 +41,7 @@ import im.vector.riotredesign.features.home.room.list.UnreadCounterBadgeView
|
|||||||
import im.vector.riotredesign.features.workers.signout.SignOutViewModel
|
import im.vector.riotredesign.features.workers.signout.SignOutViewModel
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
import kotlinx.android.synthetic.main.fragment_home_detail.*
|
import kotlinx.android.synthetic.main.fragment_home_detail.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@ -67,7 +67,8 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||||||
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
||||||
private lateinit var navigationViewModel: HomeNavigationViewModel
|
private lateinit var navigationViewModel: HomeNavigationViewModel
|
||||||
|
|
||||||
private val session by inject<Session>()
|
@Inject lateinit var session: Session
|
||||||
|
@Inject lateinit var homeDetailViewModelFactory: HomeDetailViewModel.Factory
|
||||||
|
|
||||||
override fun getLayoutResId(): Int {
|
override fun getLayoutResId(): Int {
|
||||||
return R.layout.fragment_home_detail
|
return R.layout.fragment_home_detail
|
||||||
@ -89,7 +90,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||||||
private fun setupKeysBackupBanner() {
|
private fun setupKeysBackupBanner() {
|
||||||
// Keys backup banner
|
// Keys backup banner
|
||||||
// Use the SignOutViewModel, it observe the keys backup state and this is what we need here
|
// Use the SignOutViewModel, it observe the keys backup state and this is what we need here
|
||||||
val model = ViewModelProviders.of(this).get(SignOutViewModel::class.java)
|
val model = ViewModelProviders.of(this, viewModelFactory).get(SignOutViewModel::class.java)
|
||||||
|
|
||||||
model.init(session)
|
model.init(session)
|
||||||
|
|
||||||
|
@ -16,28 +16,34 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home
|
package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model used to update the home bottom bar notification counts
|
* View model used to update the home bottom bar notification counts
|
||||||
*/
|
*/
|
||||||
class HomeDetailViewModel(initialState: HomeDetailViewState,
|
class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val homeRoomListStore: HomeRoomListObservableStore)
|
private val homeRoomListStore: HomeRoomListObservableStore)
|
||||||
: VectorViewModel<HomeDetailViewState>(initialState) {
|
: VectorViewModel<HomeDetailViewState>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: HomeDetailViewState): HomeDetailViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<HomeDetailViewModel, HomeDetailViewState> {
|
companion object : MvRxViewModelFactory<HomeDetailViewModel, HomeDetailViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: HomeDetailViewState): HomeDetailViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: HomeDetailViewState): HomeDetailViewModel? {
|
||||||
val homeRoomListStore = viewModelContext.activity.get<HomeRoomListObservableStore>()
|
val fragment: HomeDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
val session = viewModelContext.activity.get<Session>()
|
return fragment.homeDetailViewModelFactory.create(state)
|
||||||
return HomeDetailViewModel(state, session, homeRoomListStore)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import im.vector.riotredesign.core.extensions.replaceChildFragment
|
|||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.group.GroupListFragment
|
import im.vector.riotredesign.features.home.group.GroupListFragment
|
||||||
import kotlinx.android.synthetic.main.fragment_home_drawer.*
|
import kotlinx.android.synthetic.main.fragment_home_drawer.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeDrawerFragment : VectorBaseFragment() {
|
class HomeDrawerFragment : VectorBaseFragment() {
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class HomeDrawerFragment : VectorBaseFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val session by inject<Session>()
|
@Inject lateinit var session: Session
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_home_drawer
|
override fun getLayoutResId() = R.layout.fragment_home_drawer
|
||||||
|
|
||||||
|
@ -16,89 +16,20 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home
|
package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
import android.os.Handler
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
import dagger.Module
|
||||||
import im.vector.riotredesign.core.resources.ColorProvider
|
import dagger.Provides
|
||||||
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventControllerHandler
|
||||||
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineAsyncHelper
|
||||||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserController
|
|
||||||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
|
||||||
import im.vector.riotredesign.features.home.group.GroupSummaryController
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.*
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
|
||||||
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
|
||||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
|
||||||
import org.koin.core.parameter.parametersOf
|
|
||||||
import org.koin.dsl.module.module
|
|
||||||
|
|
||||||
class HomeModule {
|
@Module
|
||||||
|
object HomeModule {
|
||||||
|
|
||||||
companion object {
|
@Provides
|
||||||
const val HOME_SCOPE = "HOME_SCOPE"
|
@JvmStatic
|
||||||
const val ROOM_DETAIL_SCOPE = "ROOM_DETAIL_SCOPE"
|
@TimelineEventControllerHandler
|
||||||
}
|
fun providesTimelineBackgroundHandler(): Handler {
|
||||||
|
return TimelineAsyncHelper.getBackgroundHandler()
|
||||||
val definition = module {
|
|
||||||
|
|
||||||
// Activity scope
|
|
||||||
|
|
||||||
scope(HOME_SCOPE) {
|
|
||||||
HomeNavigator()
|
|
||||||
}
|
|
||||||
|
|
||||||
scope(HOME_SCOPE) {
|
|
||||||
HomePermalinkHandler(get(), get())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fragment scopes
|
|
||||||
|
|
||||||
factory {
|
|
||||||
TimelineDateFormatter(get())
|
|
||||||
}
|
|
||||||
|
|
||||||
factory {
|
|
||||||
NoticeEventFormatter(get())
|
|
||||||
}
|
|
||||||
|
|
||||||
factory { (fragment: Fragment) ->
|
|
||||||
val colorProvider = ColorProvider(fragment.requireContext())
|
|
||||||
val timelineDateFormatter = get<TimelineDateFormatter>()
|
|
||||||
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
|
||||||
val noticeEventFormatter = get<NoticeEventFormatter>(parameters = { parametersOf(fragment) })
|
|
||||||
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
|
||||||
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider,
|
|
||||||
timelineDateFormatter, eventHtmlRenderer, get(), get())
|
|
||||||
|
|
||||||
val timelineItemFactory = TimelineItemFactory(
|
|
||||||
messageItemFactory = messageItemFactory,
|
|
||||||
noticeItemFactory = NoticeItemFactory(noticeEventFormatter),
|
|
||||||
defaultItemFactory = DefaultItemFactory(),
|
|
||||||
encryptionItemFactory = EncryptionItemFactory(get()),
|
|
||||||
encryptedItemFactory = EncryptedItemFactory(get())
|
|
||||||
)
|
|
||||||
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
factory {
|
|
||||||
RoomSummaryController(get(), get(), get())
|
|
||||||
}
|
|
||||||
|
|
||||||
factory {
|
|
||||||
GroupSummaryController()
|
|
||||||
}
|
|
||||||
|
|
||||||
scope(ROOM_DETAIL_SCOPE) { (fragment: Fragment) ->
|
|
||||||
val commandController = AutocompleteCommandController(get())
|
|
||||||
AutocompleteCommandPresenter(fragment.requireContext(), commandController)
|
|
||||||
}
|
|
||||||
|
|
||||||
scope(ROOM_DETAIL_SCOPE) { (fragment: Fragment) ->
|
|
||||||
val userController = AutocompleteUserController()
|
|
||||||
AutocompleteUserPresenter(fragment.requireContext(), userController)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
@ -17,5 +17,6 @@
|
|||||||
package im.vector.riotredesign.features.home
|
package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
import im.vector.riotredesign.core.mvrx.NavigationViewModel
|
import im.vector.riotredesign.core.mvrx.NavigationViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeNavigationViewModel : NavigationViewModel<HomeActivity.Navigation>()
|
class HomeNavigationViewModel @Inject constructor() : NavigationViewModel<HomeActivity.Navigation>()
|
@ -24,11 +24,11 @@ import im.vector.riotredesign.core.extensions.replaceFragment
|
|||||||
import im.vector.riotredesign.features.navigation.Navigator
|
import im.vector.riotredesign.features.navigation.Navigator
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeNavigator {
|
class HomeNavigator @Inject constructor() {
|
||||||
|
|
||||||
var activity: HomeActivity? = null
|
var activity: HomeActivity? = null
|
||||||
|
|
||||||
private var rootRoomId: String? = null
|
private var rootRoomId: String? = null
|
||||||
|
|
||||||
fun openSelectedGroup(groupSummary: GroupSummary) {
|
fun openSelectedGroup(groupSummary: GroupSummary) {
|
||||||
|
@ -20,8 +20,9 @@ import android.net.Uri
|
|||||||
import im.vector.matrix.android.api.permalinks.PermalinkData
|
import im.vector.matrix.android.api.permalinks.PermalinkData
|
||||||
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
||||||
import im.vector.riotredesign.features.navigation.Navigator
|
import im.vector.riotredesign.features.navigation.Navigator
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomePermalinkHandler(private val homeNavigator: HomeNavigator,
|
class HomePermalinkHandler @Inject constructor(private val homeNavigator: HomeNavigator,
|
||||||
private val navigator: Navigator) {
|
private val navigator: Navigator) {
|
||||||
|
|
||||||
fun launch(deepLink: String?) {
|
fun launch(deepLink: String?) {
|
||||||
|
@ -21,8 +21,11 @@ import im.vector.riotredesign.core.utils.RxStore
|
|||||||
import im.vector.riotredesign.features.home.room.list.RoomListDisplayModeFilter
|
import im.vector.riotredesign.features.home.room.list.RoomListDisplayModeFilter
|
||||||
import im.vector.riotredesign.features.home.room.list.RoomListFragment
|
import im.vector.riotredesign.features.home.room.list.RoomListFragment
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
class HomeRoomListObservableStore : RxStore<List<RoomSummary>>() {
|
@Singleton
|
||||||
|
class HomeRoomListObservableStore @Inject constructor() : RxStore<List<RoomSummary>>() {
|
||||||
|
|
||||||
fun observeFilteredBy(displayMode: RoomListFragment.DisplayMode): Observable<List<RoomSummary>> {
|
fun observeFilteredBy(displayMode: RoomListFragment.DisplayMode): Observable<List<RoomSummary>> {
|
||||||
return observe()
|
return observe()
|
||||||
|
@ -27,7 +27,7 @@ import im.vector.riotredesign.core.platform.StateView
|
|||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.HomeNavigator
|
import im.vector.riotredesign.features.home.HomeNavigator
|
||||||
import kotlinx.android.synthetic.main.fragment_group_list.*
|
import kotlinx.android.synthetic.main.fragment_group_list.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback {
|
class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback {
|
||||||
|
|
||||||
@ -38,8 +38,10 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val viewModel: GroupListViewModel by fragmentViewModel()
|
private val viewModel: GroupListViewModel by fragmentViewModel()
|
||||||
private val homeNavigator by inject<HomeNavigator>()
|
|
||||||
private val groupController by inject<GroupSummaryController>()
|
@Inject lateinit var groupListViewModelFactory: GroupListViewModel.Factory
|
||||||
|
@Inject lateinit var homeNavigator: HomeNavigator
|
||||||
|
@Inject lateinit var groupController: GroupSummaryController
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_group_list
|
override fun getLayoutResId() = R.layout.fragment_group_list
|
||||||
|
|
||||||
|
@ -19,8 +19,11 @@ package im.vector.riotredesign.features.home.group
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
@ -28,24 +31,27 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
|
|
||||||
const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
|
const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
|
||||||
|
|
||||||
class GroupListViewModel(initialState: GroupListViewState,
|
class GroupListViewModel @AssistedInject constructor(@Assisted initialState: GroupListViewState,
|
||||||
private val selectedGroupHolder: SelectedGroupStore,
|
private val selectedGroupHolder: SelectedGroupStore,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val stringProvider: StringProvider
|
private val stringProvider: StringProvider
|
||||||
) : VectorViewModel<GroupListViewState>(initialState) {
|
) : VectorViewModel<GroupListViewState>(initialState) {
|
||||||
|
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: GroupListViewState): GroupListViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<GroupListViewModel, GroupListViewState> {
|
companion object : MvRxViewModelFactory<GroupListViewModel, GroupListViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: GroupListViewState): GroupListViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val groupListFragment: GroupListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
val selectedGroupHolder = viewModelContext.activity.get<SelectedGroupStore>()
|
return groupListFragment.groupListViewModelFactory.create(state)
|
||||||
val stringProvider = viewModelContext.activity.get<StringProvider>()
|
|
||||||
return GroupListViewModel(state, selectedGroupHolder, currentSession, stringProvider)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ package im.vector.riotredesign.features.home.group
|
|||||||
|
|
||||||
import com.airbnb.epoxy.TypedEpoxyController
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GroupSummaryController : TypedEpoxyController<GroupListViewState>() {
|
class GroupSummaryController @Inject constructor(): TypedEpoxyController<GroupListViewState>() {
|
||||||
|
|
||||||
var callback: Callback? = null
|
var callback: Callback? = null
|
||||||
|
|
||||||
|
@ -19,5 +19,8 @@ package im.vector.riotredesign.features.home.group
|
|||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
import im.vector.riotredesign.core.utils.RxStore
|
import im.vector.riotredesign.core.utils.RxStore
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
class SelectedGroupStore : RxStore<Option<GroupSummary>>(Option.empty())
|
@Singleton
|
||||||
|
class SelectedGroupStore @Inject constructor() : RxStore<Option<GroupSummary>>(Option.empty())
|
||||||
|
@ -57,7 +57,13 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.message.*
|
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
@ -67,13 +73,19 @@ import im.vector.riotredesign.core.extensions.hideKeyboard
|
|||||||
import im.vector.riotredesign.core.extensions.observeEvent
|
import im.vector.riotredesign.core.extensions.observeEvent
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.*
|
import im.vector.riotredesign.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||||
|
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
|
||||||
|
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA
|
||||||
|
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA
|
||||||
|
import im.vector.riotredesign.core.utils.checkPermissions
|
||||||
|
import im.vector.riotredesign.core.utils.copyToClipboard
|
||||||
|
import im.vector.riotredesign.core.utils.openCamera
|
||||||
|
import im.vector.riotredesign.core.utils.shareMedia
|
||||||
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
|
||||||
import im.vector.riotredesign.features.autocomplete.command.CommandAutocompletePolicy
|
import im.vector.riotredesign.features.autocomplete.command.CommandAutocompletePolicy
|
||||||
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
|
||||||
import im.vector.riotredesign.features.command.Command
|
import im.vector.riotredesign.features.command.Command
|
||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
import im.vector.riotredesign.features.home.HomeModule
|
|
||||||
import im.vector.riotredesign.features.home.HomePermalinkHandler
|
import im.vector.riotredesign.features.home.HomePermalinkHandler
|
||||||
import im.vector.riotredesign.features.home.getColorFromUserId
|
import im.vector.riotredesign.features.home.getColorFromUserId
|
||||||
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerActions
|
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerActions
|
||||||
@ -99,14 +111,11 @@ import kotlinx.android.parcel.Parcelize
|
|||||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||||
import kotlinx.android.synthetic.main.merge_composer_layout.view.*
|
import kotlinx.android.synthetic.main.merge_composer_layout.view.*
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
|
||||||
import org.koin.core.parameter.parametersOf
|
|
||||||
import ru.noties.markwon.Markwon
|
import ru.noties.markwon.Markwon
|
||||||
import ru.noties.markwon.html.HtmlPlugin
|
import ru.noties.markwon.html.HtmlPlugin
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@ -156,19 +165,21 @@ class RoomDetailFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val roomDetailArgs: RoomDetailArgs by args()
|
private val roomDetailArgs: RoomDetailArgs by args()
|
||||||
private val session by inject<Session>()
|
|
||||||
private val glideRequests by lazy {
|
private val glideRequests by lazy {
|
||||||
GlideApp.with(this)
|
GlideApp.with(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
|
private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel()
|
||||||
private val textComposerViewModel: TextComposerViewModel by fragmentViewModel()
|
private val textComposerViewModel: TextComposerViewModel by fragmentViewModel()
|
||||||
private val timelineEventController: TimelineEventController by inject { parametersOf(this) }
|
|
||||||
private val commandAutocompletePolicy = CommandAutocompletePolicy()
|
|
||||||
private val autocompleteCommandPresenter: AutocompleteCommandPresenter by inject { parametersOf(this) }
|
|
||||||
private val autocompleteUserPresenter: AutocompleteUserPresenter by inject { parametersOf(this) }
|
|
||||||
private val homePermalinkHandler: HomePermalinkHandler by inject()
|
|
||||||
|
|
||||||
|
@Inject lateinit var session: Session
|
||||||
|
@Inject lateinit var timelineEventController: TimelineEventController
|
||||||
|
@Inject lateinit var commandAutocompletePolicy: CommandAutocompletePolicy
|
||||||
|
@Inject lateinit var autocompleteCommandPresenter: AutocompleteCommandPresenter
|
||||||
|
@Inject lateinit var autocompleteUserPresenter: AutocompleteUserPresenter
|
||||||
|
@Inject lateinit var homePermalinkHandler: HomePermalinkHandler
|
||||||
|
@Inject lateinit var roomDetailViewModelFactory: RoomDetailViewModel.Factory
|
||||||
|
@Inject lateinit var textComposerViewModelFactory: TextComposerViewModel.Factory
|
||||||
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
|
private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_room_detail
|
override fun getLayoutResId() = R.layout.fragment_room_detail
|
||||||
@ -179,9 +190,9 @@ class RoomDetailFragment :
|
|||||||
lateinit var composerLayout: TextComposerView
|
lateinit var composerLayout: TextComposerView
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
injector().inject(this)
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
|
||||||
bindScope(getOrCreateScope(HomeModule.ROOM_DETAIL_SCOPE))
|
|
||||||
setupToolbar(roomToolbar)
|
setupToolbar(roomToolbar)
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
setupComposer()
|
setupComposer()
|
||||||
@ -363,7 +374,7 @@ class RoomDetailFragment :
|
|||||||
|
|
||||||
// Add the span
|
// Add the span
|
||||||
val user = session.getUser(item.userId)
|
val user = session.getUser(item.userId)
|
||||||
val span = PillImageSpan(glideRequests, context!!, item.userId, user)
|
val span = PillImageSpan(glideRequests, requireContext(), item.userId, user)
|
||||||
span.bind(composerLayout.composerEditText)
|
span.bind(composerLayout.composerEditText)
|
||||||
|
|
||||||
editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
@ -19,10 +19,13 @@ package im.vector.riotredesign.features.home.room.detail
|
|||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||||
|
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.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||||
@ -41,13 +44,12 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.Timeline
|
|||||||
import io.reactivex.rxkotlin.subscribeBy
|
import io.reactivex.rxkotlin.subscribeBy
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
import org.commonmark.renderer.html.HtmlRenderer
|
import org.commonmark.renderer.html.HtmlRenderer
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class RoomDetailViewModel(initialState: RoomDetailViewState,
|
class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState,
|
||||||
private val session: Session
|
private val session: Session
|
||||||
) : VectorViewModel<RoomDetailViewState>(initialState) {
|
) : VectorViewModel<RoomDetailViewState>(initialState) {
|
||||||
|
|
||||||
@ -62,14 +64,19 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
|||||||
}
|
}
|
||||||
private val timeline = room.createTimeline(eventId, allowedTypes)
|
private val timeline = room.createTimeline(eventId, allowedTypes)
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: RoomDetailViewState): RoomDetailViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<RoomDetailViewModel, RoomDetailViewState> {
|
companion object : MvRxViewModelFactory<RoomDetailViewModel, RoomDetailViewState> {
|
||||||
|
|
||||||
const val PAGINATION_COUNT = 50
|
const val PAGINATION_COUNT = 50
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return RoomDetailViewModel(state, currentSession)
|
return fragment.roomDetailViewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,35 +17,44 @@
|
|||||||
package im.vector.riotredesign.features.home.room.detail.composer
|
package im.vector.riotredesign.features.home.room.detail.composer
|
||||||
|
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
typealias AutocompleteUserQuery = CharSequence
|
typealias AutocompleteUserQuery = CharSequence
|
||||||
|
|
||||||
class TextComposerViewModel(initialState: TextComposerViewState,
|
class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: TextComposerViewState,
|
||||||
private val session: Session
|
private val session: Session
|
||||||
) : VectorViewModel<TextComposerViewState>(initialState) {
|
) : VectorViewModel<TextComposerViewState>(initialState) {
|
||||||
|
|
||||||
|
|
||||||
private val room = session.getRoom(initialState.roomId)!!
|
private val room = session.getRoom(initialState.roomId)!!
|
||||||
private val roomId = initialState.roomId
|
private val roomId = initialState.roomId
|
||||||
|
|
||||||
private val usersQueryObservable = BehaviorRelay.create<Option<AutocompleteUserQuery>>()
|
private val usersQueryObservable = BehaviorRelay.create<Option<AutocompleteUserQuery>>()
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: TextComposerViewState): TextComposerViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<TextComposerViewModel, TextComposerViewState> {
|
companion object : MvRxViewModelFactory<TextComposerViewModel, TextComposerViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val fragment : RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return TextComposerViewModel(state, currentSession)
|
return fragment.textComposerViewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,25 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import com.airbnb.epoxy.EpoxyModel
|
import com.airbnb.epoxy.EpoxyModel
|
||||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.message.*
|
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.core.epoxy.LoadingItem_
|
import im.vector.riotredesign.core.epoxy.LoadingItem_
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
|
import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.*
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.canBeMerged
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.nextDisplayableEvent
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.prevSameTypeEvents
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem_
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MergedHeaderItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MergedHeaderItem
|
||||||
@ -39,11 +51,12 @@ import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInf
|
|||||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
class TimelineEventController @Inject constructor(private val dateFormatter: TimelineDateFormatter,
|
||||||
private val timelineItemFactory: TimelineItemFactory,
|
private val timelineItemFactory: TimelineItemFactory,
|
||||||
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
||||||
private val backgroundHandler: Handler = TimelineAsyncHelper.getBackgroundHandler()
|
@TimelineEventControllerHandler private val backgroundHandler: Handler
|
||||||
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
|
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
|
||||||
|
|
||||||
interface Callback : ReactionPillCallback, AvatarCallback, BaseCallback {
|
interface Callback : ReactionPillCallback, AvatarCallback, BaseCallback {
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.home.room.detail.timeline
|
||||||
|
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class TimelineEventControllerHandler
|
@ -18,11 +18,12 @@ package im.vector.riotredesign.features.home.room.detail.timeline.action
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity shared view model to handle message actions
|
* Activity shared view model to handle message actions
|
||||||
*/
|
*/
|
||||||
class ActionsHandler : ViewModel() {
|
class ActionsHandler @Inject constructor() : ViewModel() {
|
||||||
|
|
||||||
data class ActionData(
|
data class ActionData(
|
||||||
val actionId: String,
|
val actionId: String,
|
||||||
|
@ -36,6 +36,7 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import kotlinx.android.synthetic.main.bottom_sheet_message_actions.*
|
import kotlinx.android.synthetic.main.bottom_sheet_message_actions.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bottom sheet fragment that shows a message preview with list of contextual actions
|
* Bottom sheet fragment that shows a message preview with list of contextual actions
|
||||||
@ -43,6 +44,7 @@ import kotlinx.android.synthetic.main.bottom_sheet_message_actions.*
|
|||||||
*/
|
*/
|
||||||
class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
|
class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
|
||||||
|
|
||||||
|
@Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory
|
||||||
private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
|
private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
|
||||||
|
|
||||||
private lateinit var actionHandlerModel: ActionsHandler
|
private lateinit var actionHandlerModel: ActionsHandler
|
||||||
|
@ -19,6 +19,8 @@ import com.airbnb.mvrx.FragmentViewModelContext
|
|||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
@ -27,17 +29,16 @@ import im.vector.matrix.android.api.session.room.model.message.MessageTextConten
|
|||||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import org.commonmark.parser.Parser
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import org.koin.android.ext.android.get
|
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||||
import org.koin.core.parameter.parametersOf
|
|
||||||
import ru.noties.markwon.Markwon
|
|
||||||
import ru.noties.markwon.html.HtmlPlugin
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
data class MessageActionState(
|
data class MessageActionState(
|
||||||
|
val roomId: String,
|
||||||
|
val eventId: String,
|
||||||
|
val informationData: MessageInformationData,
|
||||||
val userId: String = "",
|
val userId: String = "",
|
||||||
val senderName: String = "",
|
val senderName: String = "",
|
||||||
val messageBody: CharSequence? = null,
|
val messageBody: CharSequence? = null,
|
||||||
@ -45,38 +46,56 @@ data class MessageActionState(
|
|||||||
val showPreview: Boolean = false,
|
val showPreview: Boolean = false,
|
||||||
val canReact: Boolean = false,
|
val canReact: Boolean = false,
|
||||||
val senderAvatarPath: String? = null)
|
val senderAvatarPath: String? = null)
|
||||||
: MvRxState
|
: MvRxState {
|
||||||
|
|
||||||
|
constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId, informationData = args.informationData)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information related to an event and used to display preview in contextual bottomsheet.
|
* Information related to an event and used to display preview in contextual bottomsheet.
|
||||||
*/
|
*/
|
||||||
class MessageActionsViewModel(initialState: MessageActionState) : VectorViewModel<MessageActionState>(initialState) {
|
class MessageActionsViewModel @AssistedInject constructor(@Assisted initialState: MessageActionState,
|
||||||
|
private val eventHtmlRenderer: EventHtmlRenderer,
|
||||||
|
private val session: Session,
|
||||||
|
private val noticeEventFormatter: NoticeEventFormatter
|
||||||
|
) : VectorViewModel<MessageActionState>(initialState) {
|
||||||
|
|
||||||
|
private val roomId = initialState.roomId
|
||||||
|
private val eventId = initialState.eventId
|
||||||
|
private val informationData = initialState.informationData
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: MessageActionState): MessageActionsViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<MessageActionsViewModel, MessageActionState> {
|
companion object : MvRxViewModelFactory<MessageActionsViewModel, MessageActionState> {
|
||||||
|
|
||||||
override fun initialState(viewModelContext: ViewModelContext): MessageActionState? {
|
override fun create(viewModelContext: ViewModelContext, state: MessageActionState): MessageActionsViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val fragment: MessageActionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
val fragment = (viewModelContext as? FragmentViewModelContext)?.fragment
|
return fragment.messageActionViewModelFactory.create(state)
|
||||||
val noticeFormatter = fragment?.get<NoticeEventFormatter>(parameters = { parametersOf(fragment) })
|
}
|
||||||
val parcel = viewModelContext.args as TimelineEventFragmentArgs
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
setState { reduceState(this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reduceState(state: MessageActionState): MessageActionState {
|
||||||
val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm", Locale.getDefault())
|
val dateFormat = SimpleDateFormat("EEE, d MMM yyyy HH:mm", Locale.getDefault())
|
||||||
|
val event = session.getRoom(roomId)?.getTimeLineEvent(eventId) ?: return state
|
||||||
val event = currentSession.getRoom(parcel.roomId)?.getTimeLineEvent(parcel.eventId)
|
|
||||||
var body: CharSequence? = null
|
var body: CharSequence? = null
|
||||||
val originTs = event?.root?.originServerTs
|
val originTs = event.root.originServerTs
|
||||||
return if (event != null) {
|
|
||||||
when (event.root.type) {
|
when (event.root.type) {
|
||||||
EventType.MESSAGE -> {
|
EventType.MESSAGE -> {
|
||||||
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
|
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
|
||||||
?: event.root.content.toModel()
|
?: event.root.content.toModel()
|
||||||
body = messageContent?.body
|
body = messageContent?.body
|
||||||
if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) {
|
if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) {
|
||||||
val parser = Parser.builder().build()
|
body = eventHtmlRenderer.render(messageContent.formattedBody
|
||||||
val document = parser.parse(messageContent.formattedBody
|
|
||||||
?: messageContent.body)
|
?: messageContent.body)
|
||||||
body = Markwon.builder(viewModelContext.activity)
|
|
||||||
.usePlugin(HtmlPlugin.create()).build().render(document)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventType.STATE_ROOM_NAME,
|
EventType.STATE_ROOM_NAME,
|
||||||
@ -86,23 +105,18 @@ class MessageActionsViewModel(initialState: MessageActionState) : VectorViewMode
|
|||||||
EventType.CALL_INVITE,
|
EventType.CALL_INVITE,
|
||||||
EventType.CALL_HANGUP,
|
EventType.CALL_HANGUP,
|
||||||
EventType.CALL_ANSWER -> {
|
EventType.CALL_ANSWER -> {
|
||||||
body = noticeFormatter?.format(event)
|
body = noticeEventFormatter.format(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessageActionState(
|
return state.copy(
|
||||||
userId = event.root.sender ?: "",
|
userId = event.root.sender ?: "",
|
||||||
senderName = parcel.informationData.memberName?.toString() ?: "",
|
senderName = informationData.memberName?.toString() ?: "",
|
||||||
messageBody = body,
|
messageBody = body,
|
||||||
ts = dateFormat.format(Date(originTs ?: 0)),
|
ts = dateFormat.format(Date(originTs ?: 0)),
|
||||||
showPreview = body != null,
|
showPreview = body != null,
|
||||||
canReact = event.root.type == EventType.MESSAGE && event.sendState.isSent(),
|
canReact = event.root.type == EventType.MESSAGE && event.sendState.isSent(),
|
||||||
senderAvatarPath = parcel.informationData.avatarUrl
|
senderAvatarPath = informationData.avatarUrl
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
//can this happen?
|
|
||||||
Timber.e("Failed to retrieve event")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -29,16 +29,16 @@ import com.airbnb.mvrx.fragmentViewModel
|
|||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.features.themes.ThemeUtils
|
import im.vector.riotredesign.features.themes.ThemeUtils
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment showing the list of available contextual action for a given message.
|
* Fragment showing the list of available contextual action for a given message.
|
||||||
*/
|
*/
|
||||||
class MessageMenuFragment : BaseMvRxFragment() {
|
class MessageMenuFragment : BaseMvRxFragment() {
|
||||||
|
|
||||||
|
@Inject lateinit var messageMenuViewModelFactory: MessageMenuViewModel.Factory
|
||||||
private val viewModel: MessageMenuViewModel by fragmentViewModel(MessageMenuViewModel::class)
|
private val viewModel: MessageMenuViewModel by fragmentViewModel(MessageMenuViewModel::class)
|
||||||
|
|
||||||
private var addSeparators = false
|
private var addSeparators = false
|
||||||
|
|
||||||
var interactionListener: InteractionListener? = null
|
var interactionListener: InteractionListener? = null
|
||||||
|
|
||||||
override fun invalidate() = withState(viewModel) { state ->
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
@ -15,9 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.toContent
|
import im.vector.matrix.android.api.session.events.model.toContent
|
||||||
@ -29,44 +32,76 @@ import im.vector.matrix.android.api.session.room.send.SendState
|
|||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
|
|
||||||
data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null)
|
data class SimpleAction(val uid: String, val titleRes: Int, val iconResId: Int?, val data: Any? = null)
|
||||||
|
|
||||||
data class MessageMenuState(val actions: List<SimpleAction> = emptyList()) : MvRxState
|
data class MessageMenuState(
|
||||||
|
val roomId: String,
|
||||||
|
val eventId: String,
|
||||||
|
val informationData: MessageInformationData,
|
||||||
|
val actions: List<SimpleAction> = emptyList()
|
||||||
|
) : MvRxState {
|
||||||
|
|
||||||
|
constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId, informationData = args.informationData)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages list actions for a given message (copy / paste / forward...)
|
* Manages list actions for a given message (copy / paste / forward...)
|
||||||
*/
|
*/
|
||||||
class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<MessageMenuState>(initialState) {
|
class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: MessageMenuState,
|
||||||
|
private val session: Session) : VectorViewModel<MessageMenuState>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: MessageMenuState): MessageMenuViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<MessageMenuViewModel, MessageMenuState> {
|
companion object : MvRxViewModelFactory<MessageMenuViewModel, MessageMenuState> {
|
||||||
|
|
||||||
override fun initialState(viewModelContext: ViewModelContext): MessageMenuState? {
|
const val ACTION_ADD_REACTION = "add_reaction"
|
||||||
// Args are accessible from the context.
|
const val ACTION_COPY = "copy"
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
const val ACTION_EDIT = "edit"
|
||||||
val parcel = viewModelContext.args as TimelineEventFragmentArgs
|
const val ACTION_QUOTE = "quote"
|
||||||
val event = currentSession.getRoom(parcel.roomId)?.getTimeLineEvent(parcel.eventId)
|
const val ACTION_REPLY = "reply"
|
||||||
?: return null
|
const val ACTION_SHARE = "share"
|
||||||
|
const val ACTION_RESEND = "resend"
|
||||||
|
const val ACTION_DELETE = "delete"
|
||||||
|
const val VIEW_SOURCE = "VIEW_SOURCE"
|
||||||
|
const val VIEW_DECRYPTED_SOURCE = "VIEW_DECRYPTED_SOURCE"
|
||||||
|
const val ACTION_COPY_PERMALINK = "ACTION_COPY_PERMALINK"
|
||||||
|
const val ACTION_FLAG = "ACTION_FLAG"
|
||||||
|
const val ACTION_QUICK_REACT = "ACTION_QUICK_REACT"
|
||||||
|
const val ACTION_VIEW_REACTIONS = "ACTION_VIEW_REACTIONS"
|
||||||
|
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: MessageMenuState): MessageMenuViewModel? {
|
||||||
|
val fragment: MessageMenuFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
|
return fragment.messageMenuViewModelFactory.create(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
setState { reduceState(this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reduceState(state: MessageMenuState): MessageMenuState {
|
||||||
|
val event = session.getRoom(state.roomId)?.getTimeLineEvent(state.eventId) ?: return state
|
||||||
|
|
||||||
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
|
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
|
||||||
?: event.root.content.toModel()
|
?: event.root.content.toModel()
|
||||||
val type = messageContent?.type
|
val type = messageContent?.type
|
||||||
|
|
||||||
if (!event.sendState.isSent()) {
|
val actions = if (!event.sendState.isSent()) {
|
||||||
//Resend and Delete
|
//Resend and Delete
|
||||||
return MessageMenuState(
|
listOf<SimpleAction>(
|
||||||
//TODO
|
|
||||||
listOf(
|
|
||||||
// SimpleAction(ACTION_RESEND, R.string.resend, R.drawable.ic_send, event.root.eventId),
|
// SimpleAction(ACTION_RESEND, R.string.resend, R.drawable.ic_send, event.root.eventId),
|
||||||
// //TODO delete icon
|
// //TODO delete icon
|
||||||
// SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId)
|
// SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId)
|
||||||
)
|
)
|
||||||
)
|
} else {
|
||||||
}
|
ArrayList<SimpleAction>().apply {
|
||||||
|
|
||||||
val actions = ArrayList<SimpleAction>().apply {
|
|
||||||
|
|
||||||
if (event.sendState == SendState.SENDING) {
|
if (event.sendState == SendState.SENDING) {
|
||||||
//TODO add cancel?
|
//TODO add cancel?
|
||||||
@ -86,20 +121,20 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
|||||||
this.add(SimpleAction(ACTION_REPLY, R.string.reply, R.drawable.ic_reply, event.root.eventId))
|
this.add(SimpleAction(ACTION_REPLY, R.string.reply, R.drawable.ic_reply, event.root.eventId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canEdit(event, currentSession.sessionParams.credentials.userId)) {
|
if (canEdit(event, session.sessionParams.credentials.userId)) {
|
||||||
this.add(SimpleAction(ACTION_EDIT, R.string.edit, R.drawable.ic_edit, event.root.eventId))
|
this.add(SimpleAction(ACTION_EDIT, R.string.edit, R.drawable.ic_edit, event.root.eventId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canRedact(event, currentSession.sessionParams.credentials.userId)) {
|
if (canRedact(event, session.sessionParams.credentials.userId)) {
|
||||||
this.add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId))
|
this.add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canQuote(event, messageContent)) {
|
if (canQuote(event, messageContent)) {
|
||||||
this.add(SimpleAction(ACTION_QUOTE, R.string.quote, R.drawable.ic_quote, parcel.eventId))
|
this.add(SimpleAction(ACTION_QUOTE, R.string.quote, R.drawable.ic_quote, state.eventId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canViewReactions(event)) {
|
if (canViewReactions(event)) {
|
||||||
this.add(SimpleAction(ACTION_VIEW_REACTIONS, R.string.message_view_reaction, R.drawable.ic_view_reactions, parcel.informationData))
|
this.add(SimpleAction(ACTION_VIEW_REACTIONS, R.string.message_view_reaction, R.drawable.ic_view_reactions, state.informationData))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canShare(type)) {
|
if (canShare(type)) {
|
||||||
@ -107,7 +142,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
|||||||
this.add(
|
this.add(
|
||||||
SimpleAction(ACTION_SHARE,
|
SimpleAction(ACTION_SHARE,
|
||||||
R.string.share, R.drawable.ic_share,
|
R.string.share, R.drawable.ic_share,
|
||||||
currentSession.contentUrlResolver().resolveFullSize(messageContent.url))
|
session.contentUrlResolver().resolveFullSize(messageContent.url))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
//TODO
|
//TODO
|
||||||
@ -123,18 +158,19 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
|||||||
|
|
||||||
this.add(SimpleAction(VIEW_SOURCE, R.string.view_source, R.drawable.ic_view_source, JSONObject(event.root.toContent()).toString(4)))
|
this.add(SimpleAction(VIEW_SOURCE, R.string.view_source, R.drawable.ic_view_source, JSONObject(event.root.toContent()).toString(4)))
|
||||||
if (event.isEncrypted()) {
|
if (event.isEncrypted()) {
|
||||||
this.add(SimpleAction(VIEW_DECRYPTED_SOURCE, R.string.view_decrypted_source, R.drawable.ic_view_source, parcel.eventId))
|
this.add(SimpleAction(VIEW_DECRYPTED_SOURCE, R.string.view_decrypted_source, R.drawable.ic_view_source, state.eventId))
|
||||||
}
|
}
|
||||||
this.add(SimpleAction(ACTION_COPY_PERMALINK, R.string.permalink, R.drawable.ic_permalink, parcel.eventId))
|
this.add(SimpleAction(ACTION_COPY_PERMALINK, R.string.permalink, R.drawable.ic_permalink, state.eventId))
|
||||||
|
|
||||||
if (currentSession.sessionParams.credentials.userId != event.root.sender && event.root.getClearType() == EventType.MESSAGE) {
|
if (session.sessionParams.credentials.userId != event.root.sender && event.root.getClearType() == EventType.MESSAGE) {
|
||||||
//not sent by me
|
//not sent by me
|
||||||
this.add(SimpleAction(ACTION_FLAG, R.string.report_content, R.drawable.ic_flag, parcel.eventId))
|
this.add(SimpleAction(ACTION_FLAG, R.string.report_content, R.drawable.ic_flag, state.eventId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return state.copy(actions = actions)
|
||||||
|
}
|
||||||
|
|
||||||
return MessageMenuState(actions)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun canReply(event: TimelineEvent, messageContent: MessageContent?): Boolean {
|
private fun canReply(event: TimelineEvent, messageContent: MessageContent?): Boolean {
|
||||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||||
@ -221,22 +257,4 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const val ACTION_ADD_REACTION = "add_reaction"
|
|
||||||
const val ACTION_COPY = "copy"
|
|
||||||
const val ACTION_EDIT = "edit"
|
|
||||||
const val ACTION_QUOTE = "quote"
|
|
||||||
const val ACTION_REPLY = "reply"
|
|
||||||
const val ACTION_SHARE = "share"
|
|
||||||
const val ACTION_RESEND = "resend"
|
|
||||||
const val ACTION_DELETE = "delete"
|
|
||||||
const val VIEW_SOURCE = "VIEW_SOURCE"
|
|
||||||
const val VIEW_DECRYPTED_SOURCE = "VIEW_DECRYPTED_SOURCE"
|
|
||||||
const val ACTION_COPY_PERMALINK = "ACTION_COPY_PERMALINK"
|
|
||||||
const val ACTION_FLAG = "ACTION_FLAG"
|
|
||||||
const val ACTION_QUICK_REACT = "ACTION_QUICK_REACT"
|
|
||||||
const val ACTION_VIEW_REACTIONS = "ACTION_VIEW_REACTIONS"
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import com.airbnb.mvrx.fragmentViewModel
|
|||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotredesign.EmojiCompatFontProvider
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick Reaction Fragment (agree / like reactions)
|
* Quick Reaction Fragment (agree / like reactions)
|
||||||
@ -57,7 +57,8 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
|
|
||||||
var interactionListener: InteractionListener? = null
|
var interactionListener: InteractionListener? = null
|
||||||
|
|
||||||
val fontProvider by inject<EmojiCompatFontProvider>()
|
@Inject lateinit var fontProvider: EmojiCompatFontProvider
|
||||||
|
@Inject lateinit var quickReactionViewModelFactory: QuickReactionViewModel.Factory
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.adapter_item_action_quick_reaction, container, false)
|
val view = inflater.inflate(R.layout.adapter_item_action_quick_reaction, container, false)
|
||||||
@ -68,10 +69,10 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
quickReact1Text.text = QuickReactionViewModel.agreePositive
|
quickReact1Text.text = QuickReactionViewModel.AGREE_POSITIVE
|
||||||
quickReact2Text.text = QuickReactionViewModel.agreeNegative
|
quickReact2Text.text = QuickReactionViewModel.AGREE_NEGATIVE
|
||||||
quickReact3Text.text = QuickReactionViewModel.likePositive
|
quickReact3Text.text = QuickReactionViewModel.LIKE_POSITIVE
|
||||||
quickReact4Text.text = QuickReactionViewModel.likeNegative
|
quickReact4Text.text = QuickReactionViewModel.LIKE_NEGATIVE
|
||||||
|
|
||||||
listOf(quickReact1Text, quickReact2Text, quickReact3Text, quickReact4Text).forEach {
|
listOf(quickReact1Text, quickReact2Text, quickReact3Text, quickReact4Text).forEach {
|
||||||
it.typeface = fontProvider.typeface ?: Typeface.DEFAULT
|
it.typeface = fontProvider.typeface ?: Typeface.DEFAULT
|
||||||
@ -96,7 +97,7 @@ class QuickReactionFragment : BaseMvRxFragment() {
|
|||||||
override fun invalidate() = withState(viewModel) {
|
override fun invalidate() = withState(viewModel) {
|
||||||
|
|
||||||
TransitionManager.beginDelayedTransition(rootLayout)
|
TransitionManager.beginDelayedTransition(rootLayout)
|
||||||
when (it.agreeTrigleState) {
|
when (it.agreeTriggleState) {
|
||||||
TriggleState.NONE -> {
|
TriggleState.NONE -> {
|
||||||
quickReact1Text.alpha = 1f
|
quickReact1Text.alpha = 1f
|
||||||
quickReact2Text.alpha = 1f
|
quickReact2Text.alpha = 1f
|
||||||
|
@ -15,12 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import org.koin.android.ext.android.get
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick reactions state, it's a toggle with 3rd state
|
* Quick reactions state, it's a toggle with 3rd state
|
||||||
@ -32,33 +35,99 @@ enum class TriggleState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class QuickReactionState(
|
data class QuickReactionState(
|
||||||
val agreeTrigleState: TriggleState = TriggleState.NONE,
|
val roomId: String,
|
||||||
|
val eventId: String,
|
||||||
|
val informationData: MessageInformationData,
|
||||||
|
val agreeTriggleState: TriggleState = TriggleState.NONE,
|
||||||
val likeTriggleState: TriggleState = TriggleState.NONE,
|
val likeTriggleState: TriggleState = TriggleState.NONE,
|
||||||
/** Pair of 'clickedOn' and current toggles state*/
|
/** Pair of 'clickedOn' and current toggles state*/
|
||||||
val selectionResult: Pair<String, List<String>>? = null,
|
val selectionResult: Pair<String, List<String>>? = null
|
||||||
val eventId: String = "") : MvRxState
|
) : MvRxState {
|
||||||
|
|
||||||
|
constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId, informationData = args.informationData)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick reaction view model
|
* Quick reaction view model
|
||||||
*/
|
*/
|
||||||
class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel<QuickReactionState>(initialState) {
|
class QuickReactionViewModel @AssistedInject constructor(@Assisted initialState: QuickReactionState,
|
||||||
|
private val session: Session) : VectorViewModel<QuickReactionState>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: QuickReactionState): QuickReactionViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<QuickReactionViewModel, QuickReactionState> {
|
||||||
|
|
||||||
|
const val AGREE_POSITIVE = "👍"
|
||||||
|
const val AGREE_NEGATIVE = "👎"
|
||||||
|
const val LIKE_POSITIVE = "🙂"
|
||||||
|
const val LIKE_NEGATIVE = "😔"
|
||||||
|
|
||||||
|
fun getOpposite(reaction: String): String? {
|
||||||
|
return when (reaction) {
|
||||||
|
AGREE_POSITIVE -> AGREE_NEGATIVE
|
||||||
|
AGREE_NEGATIVE -> AGREE_POSITIVE
|
||||||
|
LIKE_POSITIVE -> LIKE_NEGATIVE
|
||||||
|
LIKE_NEGATIVE -> LIKE_POSITIVE
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: QuickReactionState): QuickReactionViewModel? {
|
||||||
|
val fragment: QuickReactionFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
|
return fragment.quickReactionViewModelFactory.create(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
setState { reduceState(this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reduceState(state: QuickReactionState): QuickReactionState {
|
||||||
|
val event = session.getRoom(state.roomId)?.getTimeLineEvent(state.eventId) ?: return state
|
||||||
|
var agreeTriggle: TriggleState = TriggleState.NONE
|
||||||
|
var likeTriggle: TriggleState = TriggleState.NONE
|
||||||
|
event.annotations?.reactionsSummary?.forEach {
|
||||||
|
//it.addedByMe
|
||||||
|
if (it.addedByMe) {
|
||||||
|
if (AGREE_POSITIVE == it.key) {
|
||||||
|
agreeTriggle = TriggleState.FIRST
|
||||||
|
} else if (AGREE_NEGATIVE == it.key) {
|
||||||
|
agreeTriggle = TriggleState.SECOND
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LIKE_POSITIVE == it.key) {
|
||||||
|
likeTriggle = TriggleState.FIRST
|
||||||
|
} else if (LIKE_NEGATIVE == it.key) {
|
||||||
|
likeTriggle = TriggleState.SECOND
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state.copy(
|
||||||
|
agreeTriggleState = agreeTriggle,
|
||||||
|
likeTriggleState = likeTriggle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun toggleAgree(isFirst: Boolean) = withState {
|
fun toggleAgree(isFirst: Boolean) = withState {
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
setState {
|
setState {
|
||||||
val newTriggle = if (it.agreeTrigleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
val newTriggle = if (it.agreeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
||||||
copy(
|
copy(
|
||||||
agreeTrigleState = newTriggle,
|
agreeTriggleState = newTriggle,
|
||||||
selectionResult = Pair(agreePositive, getReactions(this, newTriggle, null))
|
selectionResult = Pair(AGREE_POSITIVE, getReactions(this, newTriggle, null))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setState {
|
setState {
|
||||||
val newTriggle = if (it.agreeTrigleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
val newTriggle = if (it.agreeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
||||||
copy(
|
copy(
|
||||||
agreeTrigleState = agreeTrigleState,
|
agreeTriggleState = agreeTriggleState,
|
||||||
selectionResult = Pair(agreeNegative, getReactions(this, newTriggle, null))
|
selectionResult = Pair(AGREE_NEGATIVE, getReactions(this, newTriggle, null))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +139,7 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
|||||||
val newTriggle = if (it.likeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
val newTriggle = if (it.likeTriggleState == TriggleState.FIRST) TriggleState.NONE else TriggleState.FIRST
|
||||||
copy(
|
copy(
|
||||||
likeTriggleState = newTriggle,
|
likeTriggleState = newTriggle,
|
||||||
selectionResult = Pair(likePositive, getReactions(this, null, newTriggle))
|
selectionResult = Pair(LIKE_POSITIVE, getReactions(this, null, newTriggle))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -78,7 +147,7 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
|||||||
val newTriggle = if (it.likeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
val newTriggle = if (it.likeTriggleState == TriggleState.SECOND) TriggleState.NONE else TriggleState.SECOND
|
||||||
copy(
|
copy(
|
||||||
likeTriggleState = newTriggle,
|
likeTriggleState = newTriggle,
|
||||||
selectionResult = Pair(likeNegative, getReactions(this, null, newTriggle))
|
selectionResult = Pair(LIKE_NEGATIVE, getReactions(this, null, newTriggle))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,64 +156,17 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
|
|||||||
private fun getReactions(state: QuickReactionState, newState1: TriggleState?, newState2: TriggleState?): List<String> {
|
private fun getReactions(state: QuickReactionState, newState1: TriggleState?, newState2: TriggleState?): List<String> {
|
||||||
return ArrayList<String>(4).apply {
|
return ArrayList<String>(4).apply {
|
||||||
when (newState2 ?: state.likeTriggleState) {
|
when (newState2 ?: state.likeTriggleState) {
|
||||||
TriggleState.FIRST -> add(likePositive)
|
TriggleState.FIRST -> add(LIKE_POSITIVE)
|
||||||
TriggleState.SECOND -> add(likeNegative)
|
TriggleState.SECOND -> add(LIKE_NEGATIVE)
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (newState1 ?: state.agreeTrigleState) {
|
when (newState1 ?: state.agreeTriggleState) {
|
||||||
TriggleState.FIRST -> add(agreePositive)
|
TriggleState.FIRST -> add(AGREE_POSITIVE)
|
||||||
TriggleState.SECOND -> add(agreeNegative)
|
TriggleState.SECOND -> add(AGREE_NEGATIVE)
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<QuickReactionViewModel, QuickReactionState> {
|
|
||||||
|
|
||||||
val agreePositive = "👍"
|
|
||||||
val agreeNegative = "👎"
|
|
||||||
val likePositive = "🙂"
|
|
||||||
val likeNegative = "😔"
|
|
||||||
|
|
||||||
fun getOpposite(reaction: String): String? {
|
|
||||||
return when (reaction) {
|
|
||||||
agreePositive -> agreeNegative
|
|
||||||
agreeNegative -> agreePositive
|
|
||||||
likePositive -> likeNegative
|
|
||||||
likeNegative -> likePositive
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun initialState(viewModelContext: ViewModelContext): QuickReactionState? {
|
|
||||||
// Args are accessible from the context.
|
|
||||||
// val foo = vieWModelContext.args<MyArgs>.foo
|
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
|
||||||
val parcel = viewModelContext.args as TimelineEventFragmentArgs
|
|
||||||
val event = currentSession.getRoom(parcel.roomId)?.getTimeLineEvent(parcel.eventId)
|
|
||||||
?: return null
|
|
||||||
var agreeTriggle: TriggleState = TriggleState.NONE
|
|
||||||
var likeTriggle: TriggleState = TriggleState.NONE
|
|
||||||
event.annotations?.reactionsSummary?.forEach {
|
|
||||||
//it.addedByMe
|
|
||||||
if (it.addedByMe) {
|
|
||||||
if (agreePositive == it.key) {
|
|
||||||
agreeTriggle = TriggleState.FIRST
|
|
||||||
} else if (agreeNegative == it.key) {
|
|
||||||
agreeTriggle = TriggleState.SECOND
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likePositive == it.key) {
|
|
||||||
likeTriggle = TriggleState.FIRST
|
|
||||||
} else if (likeNegative == it.key) {
|
|
||||||
likeTriggle = TriggleState.SECOND
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QuickReactionState(agreeTriggle, likeTriggle, null, event.root.eventId ?: "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -19,8 +19,9 @@ package im.vector.riotredesign.features.home.room.detail.timeline.factory
|
|||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem_
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DefaultItemFactory {
|
class DefaultItemFactory @Inject constructor(){
|
||||||
|
|
||||||
fun create(event: TimelineEvent, exception: Exception? = null): DefaultItem? {
|
fun create(event: TimelineEvent, exception: Exception? = null): DefaultItem? {
|
||||||
val text = if (exception == null) {
|
val text = if (exception == null) {
|
||||||
|
@ -30,9 +30,10 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAv
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
// This class handles timeline event who haven't been successfully decrypted
|
// This class handles timeline event who haven't been successfully decrypted
|
||||||
class EncryptedItemFactory(private val stringProvider: StringProvider) {
|
class EncryptedItemFactory @Inject constructor(private val stringProvider: StringProvider) {
|
||||||
|
|
||||||
fun create(timelineEvent: TimelineEvent): VectorEpoxyModel<*>? {
|
fun create(timelineEvent: TimelineEvent): VectorEpoxyModel<*>? {
|
||||||
return when {
|
return when {
|
||||||
|
@ -28,8 +28,9 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderNa
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class EncryptionItemFactory(private val stringProvider: StringProvider) {
|
class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent): NoticeItem? {
|
fun create(event: TimelineEvent): NoticeItem? {
|
||||||
val text = buildNoticeText(event.root, event.senderName) ?: return null
|
val text = buildNoticeText(event.root, event.senderName) ?: return null
|
||||||
|
@ -29,7 +29,14 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
|||||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.message.*
|
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageNoticeContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||||
import im.vector.matrix.android.api.session.room.send.SendState
|
import im.vector.matrix.android.api.session.room.send.SendState
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.EmojiCompatFontProvider
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
@ -44,13 +51,27 @@ import im.vector.riotredesign.features.home.getColorFromUserId
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.*
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.BlankItem_
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem_
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem_
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem_
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.ReactionInfoData
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem_
|
||||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||||
import me.gujun.android.span.span
|
import me.gujun.android.span.span
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MessageItemFactory(private val colorProvider: ColorProvider,
|
class MessageItemFactory @Inject constructor(
|
||||||
|
private val colorProvider: ColorProvider,
|
||||||
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter,
|
private val timelineDateFormatter: TimelineDateFormatter,
|
||||||
private val htmlRenderer: EventHtmlRenderer,
|
private val htmlRenderer: EventHtmlRenderer,
|
||||||
|
@ -24,8 +24,9 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderNa
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class NoticeItemFactory(private val eventFormatter: NoticeEventFormatter) {
|
class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEventFormatter) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent,
|
fun create(event: TimelineEvent,
|
||||||
callback: TimelineEventController.Callback?): NoticeItem? {
|
callback: TimelineEventController.Callback?): NoticeItem? {
|
||||||
|
@ -28,8 +28,9 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.Timeline
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
class TimelineItemFactory @Inject constructor(private val messageItemFactory: MessageItemFactory,
|
||||||
private val encryptionItemFactory: EncryptionItemFactory,
|
private val encryptionItemFactory: EncryptionItemFactory,
|
||||||
private val encryptedItemFactory: EncryptedItemFactory,
|
private val encryptedItemFactory: EncryptedItemFactory,
|
||||||
private val noticeItemFactory: NoticeItemFactory,
|
private val noticeItemFactory: NoticeItemFactory,
|
||||||
@ -65,7 +66,8 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
|||||||
if (TimelineDisplayableEvents.DEBUG_HIDDEN_EVENT) {
|
if (TimelineDisplayableEvents.DEBUG_HIDDEN_EVENT) {
|
||||||
val informationData = MessageInformationData(eventId = event.root.eventId
|
val informationData = MessageInformationData(eventId = event.root.eventId
|
||||||
?: "?",
|
?: "?",
|
||||||
senderId = event.root.sender ?: "",
|
senderId = event.root.sender
|
||||||
|
?: "",
|
||||||
sendState = event.sendState,
|
sendState = event.sendState,
|
||||||
time = "",
|
time = "",
|
||||||
avatarUrl = null,
|
avatarUrl = null,
|
||||||
|
@ -20,15 +20,21 @@ import android.text.TextUtils
|
|||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.*
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
||||||
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class NoticeEventFormatter(private val stringProvider: StringProvider) {
|
class NoticeEventFormatter @Inject constructor(private val stringProvider: StringProvider) {
|
||||||
|
|
||||||
fun format(timelineEvent: TimelineEvent): CharSequence? {
|
fun format(timelineEvent: TimelineEvent): CharSequence? {
|
||||||
return when (val type = timelineEvent.root.getClearType()) {
|
return when (val type = timelineEvent.root.getClearType()) {
|
||||||
|
@ -19,8 +19,10 @@ package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
|||||||
import im.vector.riotredesign.core.resources.LocaleProvider
|
import im.vector.riotredesign.core.resources.LocaleProvider
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimelineDateFormatter(private val localeProvider: LocaleProvider) {
|
|
||||||
|
class TimelineDateFormatter @Inject constructor (private val localeProvider: LocaleProvider) {
|
||||||
|
|
||||||
private val messageHourFormatter by lazy {
|
private val messageHourFormatter by lazy {
|
||||||
DateTimeFormatter.ofPattern("H:mm", localeProvider.current())
|
DateTimeFormatter.ofPattern("H:mm", localeProvider.current())
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
package im.vector.riotredesign.features.home.room.detail.timeline.helper
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimelineMediaSizeProvider {
|
class TimelineMediaSizeProvider @Inject constructor() {
|
||||||
|
|
||||||
lateinit var recyclerView: RecyclerView
|
lateinit var recyclerView: RecyclerView
|
||||||
private var cachedSize: Pair<Int, Int>? = null
|
private var cachedSize: Pair<Int, Int>? = null
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
package im.vector.riotredesign.features.home.room.list
|
package im.vector.riotredesign.features.home.room.list
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AlphabeticalRoomComparator
|
class AlphabeticalRoomComparator @Inject constructor() : Comparator<RoomSummary> {
|
||||||
: Comparator<RoomSummary> {
|
|
||||||
|
|
||||||
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
||||||
return when {
|
return when {
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
package im.vector.riotredesign.features.home.room.list
|
package im.vector.riotredesign.features.home.room.list
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ChronologicalRoomComparator : Comparator<RoomSummary> {
|
class ChronologicalRoomComparator @Inject constructor() : Comparator<RoomSummary> {
|
||||||
|
|
||||||
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
||||||
var rightTimestamp = 0L
|
var rightTimestamp = 0L
|
||||||
|
@ -23,7 +23,11 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.airbnb.mvrx.*
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Incomplete
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.args
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
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.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
@ -36,7 +40,7 @@ import im.vector.riotredesign.core.platform.VectorBaseFragment
|
|||||||
import im.vector.riotredesign.features.home.room.list.widget.FabMenuView
|
import im.vector.riotredesign.features.home.room.list.widget.FabMenuView
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
import kotlinx.android.synthetic.main.fragment_room_list.*
|
import kotlinx.android.synthetic.main.fragment_room_list.*
|
||||||
import org.koin.android.ext.android.inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class RoomListParams(
|
data class RoomListParams(
|
||||||
@ -61,7 +65,8 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val roomListParams: RoomListParams by args()
|
private val roomListParams: RoomListParams by args()
|
||||||
private val roomController by inject<RoomSummaryController>()
|
@Inject lateinit var roomController: RoomSummaryController
|
||||||
|
@Inject lateinit var roomListViewModelFactory: RoomListViewModel.Factory
|
||||||
private val roomListViewModel: RoomListViewModel by fragmentViewModel()
|
private val roomListViewModel: RoomListViewModel by fragmentViewModel()
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_room_list
|
override fun getLayoutResId() = R.layout.fragment_room_list
|
||||||
|
@ -19,9 +19,12 @@ package im.vector.riotredesign.features.home.room.list
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import com.jakewharton.rxrelay2.BehaviorRelay
|
import com.jakewharton.rxrelay2.BehaviorRelay
|
||||||
|
import com.squareup.inject.assisted.Assisted
|
||||||
|
import com.squareup.inject.assisted.AssistedInject
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
@ -29,26 +32,27 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
|||||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
|
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
|
||||||
import org.koin.android.ext.android.get
|
|
||||||
|
|
||||||
typealias RoomListFilterName = CharSequence
|
typealias RoomListFilterName = CharSequence
|
||||||
|
|
||||||
class RoomListViewModel(initialState: RoomListViewState,
|
class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val homeRoomListObservableSource: HomeRoomListObservableStore,
|
private val homeRoomListObservableSource: HomeRoomListObservableStore,
|
||||||
private val alphabeticalRoomComparator: AlphabeticalRoomComparator,
|
private val alphabeticalRoomComparator: AlphabeticalRoomComparator,
|
||||||
private val chronologicalRoomComparator: ChronologicalRoomComparator)
|
private val chronologicalRoomComparator: ChronologicalRoomComparator)
|
||||||
: VectorViewModel<RoomListViewState>(initialState) {
|
: VectorViewModel<RoomListViewState>(initialState) {
|
||||||
|
|
||||||
|
@AssistedInject.Factory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: RoomListViewState): RoomListViewModel
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<RoomListViewModel, RoomListViewState> {
|
companion object : MvRxViewModelFactory<RoomListViewModel, RoomListViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel? {
|
||||||
val currentSession = viewModelContext.activity.get<Session>()
|
val fragment: RoomListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
val homeRoomListObservableSource = viewModelContext.activity.get<HomeRoomListObservableStore>()
|
return fragment.roomListViewModelFactory.create(state)
|
||||||
val chronologicalRoomComparator = viewModelContext.activity.get<ChronologicalRoomComparator>()
|
|
||||||
val alphabeticalRoomComparator = viewModelContext.activity.get<AlphabeticalRoomComparator>()
|
|
||||||
return RoomListViewModel(state, currentSession, homeRoomListObservableSource, alphabeticalRoomComparator, chronologicalRoomComparator)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,9 @@ import im.vector.riotredesign.core.resources.DateProvider
|
|||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class RoomSummaryController(private val stringProvider: StringProvider,
|
class RoomSummaryController @Inject constructor(private val stringProvider: StringProvider,
|
||||||
private val eventFormatter: NoticeEventFormatter,
|
private val eventFormatter: NoticeEventFormatter,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter
|
private val timelineDateFormatter: TimelineDateFormatter
|
||||||
) : TypedEpoxyController<RoomListViewState>() {
|
) : TypedEpoxyController<RoomListViewState>() {
|
||||||
|
@ -19,11 +19,12 @@
|
|||||||
package im.vector.riotredesign.features.html
|
package im.vector.riotredesign.features.html
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.style.ClickableSpan
|
|
||||||
import android.text.style.URLSpan
|
import android.text.style.URLSpan
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import im.vector.matrix.android.api.permalinks.PermalinkData
|
import im.vector.matrix.android.api.permalinks.PermalinkData
|
||||||
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
import im.vector.riotredesign.core.glide.GlideRequests
|
import im.vector.riotredesign.core.glide.GlideRequests
|
||||||
import org.commonmark.node.BlockQuote
|
import org.commonmark.node.BlockQuote
|
||||||
import org.commonmark.node.HtmlBlock
|
import org.commonmark.node.HtmlBlock
|
||||||
@ -50,13 +51,12 @@ import ru.noties.markwon.html.tag.SubScriptHandler
|
|||||||
import ru.noties.markwon.html.tag.SuperScriptHandler
|
import ru.noties.markwon.html.tag.SuperScriptHandler
|
||||||
import ru.noties.markwon.html.tag.UnderlineHandler
|
import ru.noties.markwon.html.tag.UnderlineHandler
|
||||||
import java.util.Arrays.asList
|
import java.util.Arrays.asList
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class EventHtmlRenderer(glideRequests: GlideRequests,
|
class EventHtmlRenderer @Inject constructor(context: AppCompatActivity,
|
||||||
context: Context,
|
|
||||||
session: Session) {
|
session: Session) {
|
||||||
|
|
||||||
private val markwon = Markwon.builder(context)
|
private val markwon = Markwon.builder(context)
|
||||||
.usePlugin(MatrixPlugin.create(glideRequests, context, session))
|
.usePlugin(MatrixPlugin.create(GlideApp.with(context), context, session))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun render(text: String): CharSequence {
|
fun render(text: String): CharSequence {
|
||||||
|
@ -20,8 +20,9 @@ import android.app.Activity
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import im.vector.riotredesign.features.popup.PopupAlertManager
|
import im.vector.riotredesign.features.popup.PopupAlertManager
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class VectorActivityLifecycleCallbacks : Application.ActivityLifecycleCallbacks {
|
class VectorActivityLifecycleCallbacks @Inject constructor() : Application.ActivityLifecycleCallbacks {
|
||||||
override fun onActivityPaused(activity: Activity) {
|
override fun onActivityPaused(activity: Activity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
|
|||||||
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
|
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
|
||||||
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity
|
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity
|
||||||
import im.vector.riotredesign.features.settings.VectorSettingsActivity
|
import im.vector.riotredesign.features.settings.VectorSettingsActivity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DefaultNavigator : Navigator {
|
class DefaultNavigator @Inject constructor() : Navigator {
|
||||||
|
|
||||||
|
|
||||||
override fun openRoom(roomId: String, context: Context) {
|
override fun openRoom(roomId: String, context: Context) {
|
||||||
val args = RoomDetailArgs(roomId)
|
val args = RoomDetailArgs(roomId)
|
||||||
|
@ -22,16 +22,15 @@ import android.content.Intent
|
|||||||
import androidx.core.app.RemoteInput
|
import androidx.core.app.RemoteInput
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
import org.koin.standalone.KoinComponent
|
|
||||||
import org.koin.standalone.inject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives actions broadcast by notification (on click, on dismiss, inline replies, etc.)
|
* Receives actions broadcast by notification (on click, on dismiss, inline replies, etc.)
|
||||||
*/
|
*/
|
||||||
class NotificationBroadcastReceiver : BroadcastReceiver(), KoinComponent {
|
class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
private val notificationDrawerManager by inject<NotificationDrawerManager>()
|
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||||
|
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
if (intent == null || context == null) return
|
if (intent == null || context == null) return
|
||||||
|
@ -30,13 +30,17 @@ import timber.log.Timber
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The NotificationDrawerManager receives notification events as they arrived (from event stream or fcm) and
|
* The NotificationDrawerManager receives notification events as they arrived (from event stream or fcm) and
|
||||||
* organise them in order to display them in the notification drawer.
|
* organise them in order to display them in the notification drawer.
|
||||||
* Events can be grouped into the same notification, old (already read) events can be removed to do some cleaning.
|
* Events can be grouped into the same notification, old (already read) events can be removed to do some cleaning.
|
||||||
*/
|
*/
|
||||||
class NotificationDrawerManager(val context: Context) {
|
|
||||||
|
@Singleton
|
||||||
|
class NotificationDrawerManager @Inject constructor(val context: Context) {
|
||||||
|
|
||||||
//The first time the notification drawer is refreshed, we force re-render of all notifications
|
//The first time the notification drawer is refreshed, we force re-render of all notifications
|
||||||
private var firstTime = true
|
private var firstTime = true
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user