diff --git a/app/build.gradle b/app/build.gradle index fbf41f376..196bbd713 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -149,7 +149,7 @@ ext { work_version = "2.3.0-alpha02" koin_version = "2.1.0-alpha-1" lifecycle_version = "2.2.0-beta01" - coil_version = "0.7.0" + coil_version = "0.8.0" room_version = "2.2.0" } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java index 6b6f835f6..bd48e25cf 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java @@ -33,6 +33,7 @@ import android.widget.TextView; import androidx.emoji.widget.EmojiTextView; import butterknife.BindView; import butterknife.ButterKnife; +import coil.ImageLoader; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.interfaces.DraweeController; import com.facebook.drawee.view.SimpleDraweeView; diff --git a/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt index 2a7882fbc..d1196cbce 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt @@ -20,9 +20,13 @@ package com.nextcloud.talk.newarch.di.module +import android.app.Application import android.content.Context import android.text.TextUtils import android.util.Log +import coil.ImageLoader +import coil.decode.GifDecoder +import coil.decode.SvgDecoder import com.github.aurae.retrofit2.LoganSquareConverterFactory import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R @@ -80,6 +84,7 @@ val NetworkModule = module { single { createOkHttpClient(androidContext(), get(), get(), get(), get(), get(), get(), get()) } factory { createApiErrorHandler() } single { createNextcloudTalkRepository(get()) } + single { createImageLoader(androidApplication(), get()) } } @@ -237,9 +242,9 @@ fun createDispatcher(): Dispatcher { return dispatcher } -fun createCache(androidApplication: NextcloudTalkApplication): Cache { - val cacheSize = 128 * 1024 * 1024 // 128 MB - return Cache(androidApplication.cacheDir, cacheSize.toLong()) +fun createCache(androidApplication: Application): Cache { + //val cacheSize = 128 * 1024 * 1024 // 128 MB + return Cache(androidApplication.cacheDir, Long.MAX_VALUE) } fun createApiErrorHandler(): ApiErrorHandler { @@ -250,6 +255,22 @@ fun createService(retrofit: Retrofit): ApiService { return retrofit.create(ApiService::class.java) } +fun createImageLoader( + androidApplication: Application, + okHttpClient: OkHttpClient +): ImageLoader { + return ImageLoader(androidApplication) { + availableMemoryPercentage(0.5) + bitmapPoolPercentage(0.5) + crossfade(true) + okHttpClient(okHttpClient) + componentRegistry { + add(GifDecoder()) + add(SvgDecoder(androidApplication)) + } + } +} + fun createNextcloudTalkRepository(apiService: ApiService): NextcloudTalkRepository { return NextcloudTalkRepositoryImpl(apiService) } diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt index d3a5257fd..996dadb76 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt @@ -22,6 +22,7 @@ package com.nextcloud.talk.newarch.features.conversationsList import android.app.SearchManager import android.content.Context +import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.text.InputType @@ -38,6 +39,9 @@ import androidx.core.view.MenuItemCompat import androidx.lifecycle.Observer import androidx.recyclerview.widget.RecyclerView.ViewHolder import butterknife.OnClick +import coil.ImageLoader +import coil.target.Target +import coil.transform.CircleCropTransformation import com.afollestad.materialdialogs.LayoutMode.WRAP_CONTENT import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet @@ -53,10 +57,12 @@ import com.nextcloud.talk.controllers.SettingsController import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.newarch.conversationsList.mvp.BaseView import com.nextcloud.talk.newarch.mvvm.ext.initRecyclerView +import com.nextcloud.talk.newarch.utils.Images import com.nextcloud.talk.newarch.utils.ViewState.FAILED import com.nextcloud.talk.newarch.utils.ViewState.LOADED import com.nextcloud.talk.newarch.utils.ViewState.LOADED_EMPTY import com.nextcloud.talk.newarch.utils.ViewState.LOADING +import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ConductorRemapping import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.animations.SharedElementTransition @@ -66,6 +72,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter.OnItemClickListener import eu.davidea.flexibleadapter.FlexibleAdapter.OnItemLongClickListener import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.IFlexible +import kotlinx.android.synthetic.main.controller_conversations_rv.view.* import kotlinx.android.synthetic.main.controller_conversations_rv.view.dataStateView import kotlinx.android.synthetic.main.controller_conversations_rv.view.floatingActionButton import kotlinx.android.synthetic.main.controller_conversations_rv.view.recyclerView @@ -85,6 +92,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener, lateinit var viewModel: ConversationsListViewModel val factory: ConversationListViewModelFactory by inject() + val imageLoader: ImageLoader by inject() private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, true) @@ -120,7 +128,28 @@ class ConversationsListView : BaseView(), OnQueryTextListener, .toInt() } - iconSize?.let { viewModel.loadAvatar(it) } + iconSize?.let { + val target = object : Target { + override fun onSuccess(result: Drawable) { + super.onSuccess(result) + settingsItem?.icon = result + } + + override fun onError(error: Drawable?) { + super.onError(error) + settingsItem?.icon = context.getDrawable(R.drawable.ic_settings_white_24dp) + } + } + + viewModel.currentUserLiveData.value?.let { + val avatarRequest = Images().getRequestForUrl(imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels( + it.baseUrl, + it.userId, iconSize), it, target, this, CircleCropTransformation() + ) + + imageLoader.load(avatarRequest) + } + } } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt index afd713726..8645043dd 100644 --- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt @@ -28,6 +28,8 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.viewModelScope +import coil.request.LoadRequest +import coil.target.ViewTarget import com.facebook.common.executors.UiThreadImmediateExecutorService import com.facebook.common.references.CloseableReference import com.facebook.datasource.DataSource @@ -89,6 +91,7 @@ class ConversationsListViewModel constructor( viewModelScope.launch { setConversationUpdateStatus(conversation, true) } + leaveConversationUseCase.invoke(viewModelScope, parametersOf( currentUserLiveData.value, conversation @@ -196,36 +199,6 @@ class ConversationsListViewModel constructor( }) } - fun loadAvatar(avatarSize: Int) { - val imageRequest = DisplayUtils.getImageRequestForUrl( - ApiUtils.getUrlForAvatarWithNameAndPixels( - currentUserLiveData.value!!.baseUrl, - currentUserLiveData.value!!.userId, avatarSize - ), null - ) - - val imagePipeline = Fresco.getImagePipeline() - val dataSource = imagePipeline.fetchDecodedImage(imageRequest, viewModelScope) - dataSource.subscribe(object : BaseBitmapDataSubscriber() { - override fun onNewResultImpl(bitmap: Bitmap?) { - if (bitmap != null) { - val roundedBitmapDrawable = RoundedBitmapDrawableFactory.create( - context.resources, - bitmap - ) - roundedBitmapDrawable.isCircular = true - roundedBitmapDrawable.setAntiAlias(true) - currentUserAvatar.value = roundedBitmapDrawable - } - } - - override fun onFailureImpl(dataSource: DataSource>) { - currentUserAvatar.value = context.getDrawable(R.drawable.ic_settings_white_24dp) - } - }, UiThreadImmediateExecutorService.getInstance()) - - } - fun getShareIntentForConversation(conversation: Conversation): Intent { val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt new file mode 100644 index 000000000..9b6994bac --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt @@ -0,0 +1,61 @@ +/* + * Nextcloud Talk application + * + * @author Mario Danic + * Copyright (C) 2017-2019 Mario Danic + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.newarch.utils + +import android.content.Context +import androidx.lifecycle.LifecycleOwner +import coil.ImageLoader +import coil.request.LoadRequest +import coil.target.Target +import coil.transform.Transformation +import com.nextcloud.talk.models.database.UserEntity + +class Images { + fun getRequestForUrl( + imageLoader: ImageLoader, + context: Context, + url: String, + userEntity: + UserEntity, + target: Target?, + lifecycleOwner: LifecycleOwner?, + vararg transformations: Transformation + ): LoadRequest { + return LoadRequest(context, imageLoader.defaults) { + data(url) + transformations(*transformations) + lifecycleOwner?.let { + lifecycle(lifecycleOwner) + } + + target?.let { + target(target) + } + + if (url.startsWith(userEntity.baseUrl) && url.contains( + "index.php/core/preview?fileId=" + ) + ) { + addHeader("Authorization", userEntity.getCredentials()) + } + } + } +} \ No newline at end of file