/* * Copyright (c) Kuba SzczodrzyƄski 2021-3-23. */ package pl.szczodrzynski.edziennik import android.app.Activity import android.content.Intent import android.net.Uri import android.provider.OpenableColumns import com.canhub.cropper.CropImage import com.canhub.cropper.CropImageView import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity import java.io.File import java.io.FileOutputStream class MainActivityRequestHandler(val activity: MainActivity) { companion object { private const val REQUEST_LOGIN_ACTIVITY = 2000 private const val REQUEST_FILE_HEADER_BACKGROUND = 3000 private const val REQUEST_FILE_APP_BACKGROUND = 4000 private const val REQUEST_FILE_PROFILE_IMAGE = 5000 private const val REQUEST_CROP_HEADER_BACKGROUND = 3100 private const val REQUEST_CROP_APP_BACKGROUND = 4100 private const val REQUEST_CROP_PROFILE_IMAGE = 5100 } private val app = activity.app private val requestData = mutableMapOf() private val listeners = mutableMapOf Unit>() private val manager get() = app.permissionManager fun requestLogin() = activity.startActivityForResult( Intent(activity, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY ) fun requestHeaderBackground(listener: (Any?) -> Unit) = manager.requestCameraPermission( activity, 0, isRequired = false ) { listeners[REQUEST_FILE_HEADER_BACKGROUND] = listener activity.startActivityForResult( CropImage.getPickImageChooserIntent( activity, activity.getString(R.string.pick_image_intent_chooser_title), true, true ), REQUEST_FILE_HEADER_BACKGROUND ) } fun requestAppBackground(listener: (Any?) -> Unit) = manager.requestCameraPermission( activity, 0, isRequired = false ) { listeners[REQUEST_FILE_APP_BACKGROUND] = listener activity.startActivityForResult( CropImage.getPickImageChooserIntent( activity, activity.getString(R.string.pick_image_intent_chooser_title), true, true ), REQUEST_FILE_APP_BACKGROUND ) } fun requestProfileImage(profile: Profile, listener: (Any?) -> Unit) = manager.requestCameraPermission( activity, 0, isRequired = false ) { listeners[REQUEST_FILE_PROFILE_IMAGE] = listener requestData[REQUEST_FILE_PROFILE_IMAGE] = profile activity.startActivityForResult( CropImage.getPickImageChooserIntent( activity, activity.getString(R.string.pick_image_intent_chooser_title), true, true ), REQUEST_FILE_PROFILE_IMAGE ) } private fun getFileInfo(uri: Uri): Pair { if (uri.scheme == "file") { return (uri.lastPathSegment ?: "unknown") to null } val cursor = activity.contentResolver.query( uri, null, null, null, null, null ) return cursor?.use { if (it.moveToFirst()) { val name = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) val mimeIndex = it.getColumnIndex("mime_type") val mimeType = if (mimeIndex != -1) it.getString(mimeIndex) else null name to mimeType } else null } ?: "unknown" to null } private fun shouldCrop(uri: Uri): Boolean { val (filename, mimeType) = getFileInfo(uri) return !filename.endsWith(".gif") && mimeType?.endsWith("/gif") != true } private fun saveFile(uri: Uri, name: String): String { val (filename, _) = getFileInfo(uri) val extension = filename.substringAfterLast('.') val file = File(activity.filesDir, "$name.$extension") activity.contentResolver.openInputStream(uri)?.use { input -> FileOutputStream(file).use { output -> input.copyTo(output) } } return file.absolutePath } fun handleResult(requestCode: Int, resultCode: Int, data: Intent?) { if (resultCode != Activity.RESULT_OK) return var uri = CropImage.getPickImageResultUri(activity, data) when (requestCode) { REQUEST_LOGIN_ACTIVITY -> { if (!app.config.loginFinished) activity.finish() else { activity.handleIntent(data?.extras) } } REQUEST_FILE_HEADER_BACKGROUND -> { if (uri == null) return // TODO: 2021-03-24 if the app returns no data if (shouldCrop(uri)) { val intent = CropImage.activity(uri) .setAspectRatio(512, 288) .setGuidelines(CropImageView.Guidelines.ON_TOUCH) .setAllowFlipping(true) .setAllowRotation(true) .setRequestedSize(512, 288) .getIntent(activity) activity.startActivityForResult(intent, REQUEST_CROP_HEADER_BACKGROUND) } else { val path = saveFile(uri, "header") app.config.ui.headerBackground = path listeners.remove(REQUEST_FILE_HEADER_BACKGROUND)?.invoke(path) } } REQUEST_FILE_APP_BACKGROUND -> { if (uri == null) return if (shouldCrop(uri)) { val intent = CropImage.activity(uri) .setGuidelines(CropImageView.Guidelines.ON_TOUCH) .setAllowFlipping(true) .setAllowRotation(true) .getIntent(activity) activity.startActivityForResult(intent, REQUEST_CROP_APP_BACKGROUND) } else { val path = saveFile(uri, "background") app.config.ui.appBackground = path listeners.remove(REQUEST_FILE_APP_BACKGROUND)?.invoke(path) } } REQUEST_FILE_PROFILE_IMAGE -> { if (uri == null) return if (shouldCrop(uri)) { val intent = CropImage.activity(uri) .setAspectRatio(1, 1) .setCropShape(CropImageView.CropShape.OVAL) .setGuidelines(CropImageView.Guidelines.ON_TOUCH) .setAllowFlipping(true) .setAllowRotation(true) .setRequestedSize(512, 512) .getIntent(activity) activity.startActivityForResult(intent, REQUEST_CROP_PROFILE_IMAGE) } else { val profile = requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return val path = saveFile(uri, "profile${profile.id}") profile.image = path listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile) } } REQUEST_CROP_HEADER_BACKGROUND -> { uri = CropImage.getActivityResult(data)?.uri ?: return val path = saveFile(uri, "header") app.config.ui.headerBackground = path listeners.remove(REQUEST_FILE_HEADER_BACKGROUND)?.invoke(path) } REQUEST_CROP_APP_BACKGROUND -> { uri = CropImage.getActivityResult(data)?.uri ?: return val path = saveFile(uri, "background") app.config.ui.appBackground = path listeners.remove(REQUEST_FILE_APP_BACKGROUND)?.invoke(path) } REQUEST_CROP_PROFILE_IMAGE -> { uri = CropImage.getActivityResult(data)?.uri ?: return val profile = requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return val path = saveFile(uri, "profile${profile.id}") profile.image = path listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile) } } } }