Skip to content

Commit

Permalink
Merge pull request #21 from Atwa/refactor/file_picker_processor
Browse files Browse the repository at this point in the history
Refactor/file picker processor
  • Loading branch information
Atwa authored Nov 15, 2023
2 parents c9814e1 + 2f130cc commit 7c852cb
Show file tree
Hide file tree
Showing 18 changed files with 311 additions and 490 deletions.
10 changes: 4 additions & 6 deletions filepicker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ plugins {
}

android {
compileSdk 33
compileSdk 34

defaultConfig {
minSdk 21
targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -65,11 +65,9 @@ afterEvaluate {
dependencies {

implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.atwa.filepicker.core

import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.atwa.filepicker.decoder.Decoder
import com.atwa.filepicker.decoder.UriDecoder
import java.lang.ref.WeakReference

class ActivityConfiguration(
private val activity: WeakReference<AppCompatActivity>,
) : PickerConfiguration {

private var callback: ((uri: Uri?) -> Unit)? = null
private val launcher = activity.get()
?.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
callback?.invoke(result?.data?.data)
}

override val lifecycle = activity.get()?.lifecycle
override val lifecycleScope = activity.get()?.lifecycleScope
override val decoder: Decoder by lazy {
UriDecoder(activity.get()?.applicationContext, Handler(Looper.getMainLooper()))
}

override fun Intent.onPick(callback: (uri: Uri?) -> Unit) {
this@ActivityConfiguration.callback = callback
launcher?.launch(this)
}

override fun clear() {
activity.clear()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.atwa.filepicker.core

import java.util.concurrent.Executor
import java.util.concurrent.Executors

object Executors {
val executor: Executor by lazy { Executors.newFixedThreadPool(4) }
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.atwa.filepicker.core

import android.graphics.Bitmap
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.atwa.filepicker.result.FileMeta
import com.atwa.filepicker.result.ImageMeta
import com.atwa.filepicker.result.VideoMeta
import java.io.File
import java.lang.ref.WeakReference

interface FilePicker {
Expand Down Expand Up @@ -69,10 +67,10 @@ interface FilePicker {
companion object {
@JvmStatic
fun getInstance(activity: AppCompatActivity): FilePicker =
ActivityFilePicker(WeakReference(activity))
FilePickerProcessor(ActivityConfiguration(WeakReference(activity)))

@JvmStatic
fun getInstance(fragment: Fragment): FilePicker =
FragmentFilePicker(WeakReference(fragment))
FilePickerProcessor(FragmentConfiguration(WeakReference(fragment)))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.atwa.filepicker.core

import android.provider.MediaStore
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.atwa.filepicker.core.PickIntent.captureIntent
import com.atwa.filepicker.core.PickIntent.fileIntent
import com.atwa.filepicker.core.PickIntent.imageIntent
import com.atwa.filepicker.core.PickIntent.pdfIntent
import com.atwa.filepicker.core.PickIntent.videoIntent
import com.atwa.filepicker.result.FileMeta
import com.atwa.filepicker.result.ImageMeta
import com.atwa.filepicker.result.VideoMeta

class FilePickerProcessor(private val configuration: PickerConfiguration) : FilePicker {

init {
observeLifeCycle()
}


private fun observeLifeCycle() {
configuration.lifecycle?.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (event == Lifecycle.Event.ON_DESTROY) {
configuration.lifecycle?.removeObserver(this)
configuration.clear()
}
}
})
}

override fun pickImage(onImagePicked: (ImageMeta?) -> Unit) {
with(configuration) {
imageIntent.onPick { uri ->
decoder.getStorageImage(uri, onImagePicked)
}
}
}

override fun captureCameraImage(onImagePicked: (ImageMeta?) -> Unit) {
with(configuration) {
val photoURI = decoder.createFile()
captureIntent.apply { putExtra(MediaStore.EXTRA_OUTPUT, photoURI) }.onPick {
decoder.getCameraImage(photoURI, onImagePicked)
}
}
}

override fun pickPdf(onPdfPicked: (FileMeta?) -> Unit) {
with(configuration) {
pdfIntent.onPick { uri ->
decoder.getStoragePDF(uri, onPdfPicked)
}
}
}

override fun pickVideo(onVideoPicked: (VideoMeta?) -> Unit) {
with(configuration) {
videoIntent.onPick { uri ->
decoder.getStorageVideo(uri, onVideoPicked)
}
}
}

override fun pickFile(onFilePicked: (FileMeta?) -> Unit) {
pickFile("", onFilePicked)
}

override fun pickFile(initialDirectoryPath: String, onFilePicked: (FileMeta?) -> Unit) {
with(configuration) {
fileIntent.apply {
if (initialDirectoryPath.isNotBlank())
data = initialDirectoryPath.toUri()
type = "*/*"
}.onPick { uri ->
decoder.getStorageFile(uri, onFilePicked)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.atwa.filepicker.core

import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.atwa.filepicker.decoder.Decoder
import com.atwa.filepicker.decoder.UriDecoder
import java.lang.ref.WeakReference

class FragmentConfiguration(private val fragment: WeakReference<Fragment>) :
PickerConfiguration {

var callback: ((uri: Uri?) -> Unit)? = null
private val launcher = fragment.get()
?.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
callback?.invoke(result?.data?.data)
}

override val lifecycle = fragment.get()?.lifecycle
override val lifecycleScope = fragment.get()?.lifecycleScope
override val decoder: Decoder by lazy {
UriDecoder(
fragment.get()?.requireActivity()?.applicationContext,
Handler(Looper.getMainLooper())
)
}

override fun Intent.onPick(callback: (uri: Uri?) -> Unit) {
this@FragmentConfiguration.callback = callback
launcher?.launch(this)
}

override fun clear() {
fragment.clear()
}
}
Loading

0 comments on commit 7c852cb

Please sign in to comment.