Skip to content

Commit

Permalink
[FIX] Change gallery picker use case
Browse files Browse the repository at this point in the history
Remove gallery picker due to bug in Android 10 up.
Change to activity contract get content
  • Loading branch information
forceporquillo committed Nov 9, 2021
1 parent 20db6db commit e1fce6c
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 90 deletions.
1 change: 0 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ dependencies {

implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
implementation "com.zhihu.android:matisse:0.5.3-beta3"

implementation "androidx.recyclerview:recyclerview:1.3.0-alpha01"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class AddDriverViewModel @Inject constructor(
email = _emailSf.value,
password = _passwordSf.value,
contact = _contactSf.value,
isActive = true,
isActive = driverUri?.isActive ?: true,
profile = profileInBytes,
assignedAdminId = signInViewModelDelegate.userIdValue!!
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts.GetContent
import androidx.fragment.app.viewModels
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.firebase.auth.FirebaseAuth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.forcecodes.truckme.base.UiActionEvent
import dev.forcecodes.truckme.core.domain.settings.*
import dev.forcecodes.truckme.core.util.Result
import dev.forcecodes.truckme.core.util.isDriver
import dev.forcecodes.truckme.core.util.successOr
import dev.forcecodes.truckme.ui.auth.CommonCredentialsViewModel
import dev.forcecodes.truckme.ui.auth.signin.SignInViewModelDelegate
Expand Down Expand Up @@ -78,7 +79,7 @@ class AccountSettingsViewModel @Inject constructor(
if (driverId.isNullOrEmpty()) {
return@flow
}
if (photoUri == null) {
if (isDriver) {
getDriverProfileUseCase(driverId).collect { profileUrl ->
Timber.e(profileUrl.toString())
emit(Uri.parse(profileUrl.successOr("")))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
package dev.forcecodes.truckme.ui.gallery

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.Point
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts.GetContent
import androidx.annotation.LayoutRes
import androidx.cardview.widget.CardView
import androidx.core.view.isGone
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.MimeType
import com.zhihu.matisse.engine.impl.GlideEngine
import com.zhihu.matisse.filter.Filter
import com.zhihu.matisse.internal.entity.IncapableCause
import com.zhihu.matisse.internal.entity.Item
import com.zhihu.matisse.internal.utils.PhotoMetadataUtils
import dev.forcecodes.truckme.R
import dev.forcecodes.truckme.R.string
import dev.forcecodes.truckme.extensions.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber

private const val REQUEST_CODE_CHOOSE = 0x1377

abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(contentLayoutId) {

private val galleryViewModel by viewModels<GalleryViewModel>()
Expand All @@ -41,12 +26,21 @@ abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
abstract fun onProfileChange(profileInBytes: ByteArray)
abstract fun requireGalleryViews(): GalleryViews

private var getContent: ActivityResultLauncher<String>? = null

data class GalleryViews(
val profileIcon: ImageView,
val avatar: ImageView,
val button: CardView
)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
galleryViewModel.setImageUri(uri ?: return@registerForActivityResult)
}
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
Expand All @@ -63,7 +57,7 @@ abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
override fun onStart() {
super.onStart()
imageButton?.setOnClickListener {
launchGallery()
getContent?.launch("image/*")
}
}

Expand All @@ -76,37 +70,17 @@ abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
}
}

override fun onDestroy() {
super.onDestroy()
galleryViewModel.setImageUri(null)
}

private fun <T> bindProfile(urlOrUri: T) {
bindProfileIcon(urlOrUri, true) { profileInBytes ->
onProfileChange(profileInBytes)
}
}

@Suppress("deprecation")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_CHOOSE && resultCode == Activity.RESULT_OK) {
val imageUri = Matisse.obtainResult(data)
galleryViewModel.setImageUri(imageUri[0])
}
}

private fun launchGallery() {
Matisse.from(this)
.choose(MimeType.ofAll())
.addFilter(GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
.gridExpectedSize(resources.getDimensionPixelSize(R.dimen.grid_expected_size))
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
.thumbnailScale(0.85f)
.imageEngine(GlideEngine())
.showPreview(true) // Default is `true`
.maxOriginalSize(10)
.originalEnable(true)
.theme(R.style.PickerGalleryStyle)
.autoHideToolbarOnSingleTap(true)
.forResult(REQUEST_CODE_CHOOSE)
}

abstract fun onImageSelectedResult(imageUri: Uri)

protected fun <T> bindProfileIcon(
Expand All @@ -125,6 +99,7 @@ abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
}

if (dispatch) {
Timber.e("saving...")
// save profile bitmap everytime glide returns true
saveCompressedBitmap { profileInBytes ->
block?.invoke(profileInBytes)
Expand All @@ -149,36 +124,6 @@ abstract class GalleryFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
avatar = null
imageButton = null
}

internal class GifSizeFilter(
private val mMinWidth: Int,
private val mMinHeight: Int,
private val mMaxSize: Int
) : Filter() {
public override fun constraintTypes(): HashSet<MimeType?> {
return object : HashSet<MimeType?>() {
init {
add(MimeType.GIF)
}
}
}

override fun filter(context: Context, item: Item): IncapableCause? {
if (!needFiltering(context, item)) return null
val size: Point =
PhotoMetadataUtils.getBitmapBound(context.contentResolver, item.contentUri)
return if (size.x < mMinWidth || size.y < mMinHeight || item.size > mMaxSize) {
IncapableCause(
IncapableCause.DIALOG,
context.getString(
string.error_gif,
mMinWidth,
PhotoMetadataUtils.getSizeInMB(mMaxSize.toLong()).toString()
)
)
} else null
}
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GalleryViewModel : ViewModel() {
_image.value = image
}

fun setImageUri(uri: Uri) {
fun setImageUri(uri: Uri?) {
_imageUri.value = uri
}
}
2 changes: 0 additions & 2 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,4 @@

<!-- inter spacing between RecyclerView's Item-->
<dimen name="gallery_list_spacing">4dp</dimen>

<dimen name="grid_expected_size">120dp</dimen>
</resources>
4 changes: 1 addition & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,5 @@
<string name="delete">Delete</string>
<string name="set_state">Set as %1$s</string>
<string name="no_available_drivers">No Available Drivers</string>

<string name="error_gif">x or y bound size should be at least %1$dpx and file size should be no more than %2$sM</string>

<string name="no_available_vehicles">No Available Vehicles</string>
</resources>
6 changes: 0 additions & 6 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,4 @@
<item name="textAllCaps">false</item>
<item name="android:letterSpacing">0</item>
</style>

<style name="PickerGalleryStyle" parent="Matisse.Zhihu">
<item name="colorPrimary">@color/teal_700</item>
<item name="colorPrimaryDark">@color/teal_700</item>
<item name="bottomToolbar.apply.textColor">@color/black</item>
</style>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import dev.forcecodes.truckme.core.data.auth.FirebaseAuthStateDataSource
import dev.forcecodes.truckme.core.data.driver.RegisteredDriverDataSource
import dev.forcecodes.truckme.core.data.fleets.*
import dev.forcecodes.truckme.core.data.fleets.FleetUiModel.DriverUri
import dev.forcecodes.truckme.core.di.ApplicationScope
import dev.forcecodes.truckme.core.di.IoDispatcher
import dev.forcecodes.truckme.core.domain.FlowUseCase
import dev.forcecodes.truckme.core.util.*
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -21,7 +25,8 @@ class AddDriverUseCase @Inject constructor(
private val authStateDataSource: FirebaseAuthStateDataSource,
private val registeredUserDataSource: RegisteredDriverDataSource,
private val driverDomainMapper: DriverDomainMapper,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
@ApplicationScope private val externalScope: CoroutineScope
) : FlowUseCase<DriverByteArray, DriverResult>(ioDispatcher) {

override fun execute(parameters: DriverByteArray): Flow<Result<DriverResult>> {
Expand Down Expand Up @@ -55,14 +60,22 @@ class AddDriverUseCase @Inject constructor(
// Step #4. Save to NoSQL DB as collection reference. Otherwise, ignore.
vehicleMapper ?: driverDomainMapper.invoke(parameters, null)
).triggerOneShotListener(vehicleAddResult)

register(parameters.id)

emit(Result.Success(vehicleAddResult))
}
}

private fun register(userId: String) {
registeredUserDataSource.register(userId)
Timber.e("User ID $userId")
externalScope.launch(ioDispatcher) {
registeredUserDataSource.isDriverRegistered(userId).collect { result ->
if (result.successOr(false) == false) {
registeredUserDataSource.register(userId)
}
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.first
import timber.log.Timber
import timber.log.Timber.Forest
import javax.inject.Inject
import javax.inject.Singleton

Expand Down

0 comments on commit e1fce6c

Please sign in to comment.