From e4012a1301e9688ffdc228d03a8628799ca03ee2 Mon Sep 17 00:00:00 2001 From: klaus Date: Thu, 3 Jul 2025 13:15:01 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EA=B8=80=EC=93=B0=EA=B8=B0/=EC=88=98=EC=A0=95=20-=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20gif=20=EB=93=B1=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/codeStyles/Project.xml | 35 ++++ app/build.gradle | 1 + .../modify/CreatorCommunityModifyActivity.kt | 178 ++++++++++++++---- .../write/CreatorCommunityWriteActivity.kt | 168 +++++++++++++---- .../activity_creator_community_modify.xml | 28 ++- .../activity_creator_community_write.xml | 32 +++- 6 files changed, 357 insertions(+), 85 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 7643783a..7f70f7ef 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,40 @@ + + + diff --git a/app/build.gradle b/app/build.gradle index 8d2aef10..4999b0a9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -149,6 +149,7 @@ dependencies { implementation "io.github.ParkSangGwon:tedpermission-normal:3.3.0" implementation 'com.github.dhaval2404:imagepicker:2.1' + implementation 'com.github.yalantis:ucrop:2.2.10' implementation 'com.github.zhpanvip:bannerviewpager:3.5.7' implementation 'com.google.android.gms:play-services-oss-licenses:17.1.0' diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/modify/CreatorCommunityModifyActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/modify/CreatorCommunityModifyActivity.kt index 5c944dbf..f0bcd702 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/modify/CreatorCommunityModifyActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/modify/CreatorCommunityModifyActivity.kt @@ -2,18 +2,24 @@ package kr.co.vividnext.sodalive.explorer.profile.creator_community.modify import android.Manifest import android.annotation.SuppressLint +import android.content.Intent +import android.net.Uri import android.os.Build import android.os.Bundle import android.view.View import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat -import coil.load import coil.transform.RoundedCornersTransformation +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions import com.github.dhaval2404.imagepicker.ImagePicker import com.gun0912.tedpermission.PermissionListener import com.gun0912.tedpermission.normal.TedPermission import com.jakewharton.rxbinding4.widget.textChanges +import com.orhanobut.logger.Logger +import com.yalantis.ucrop.UCrop import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.schedulers.Schedulers import kr.co.vividnext.sodalive.R @@ -26,6 +32,7 @@ import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityModifyBindin import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.loadUrl import org.koin.android.ext.android.inject +import java.io.File class CreatorCommunityModifyActivity : BaseActivity( ActivityCreatorCommunityModifyBinding::inflate @@ -34,8 +41,9 @@ class CreatorCommunityModifyActivity : BaseActivity val resultCode = result.resultCode @@ -45,25 +53,116 @@ class CreatorCommunityModifyActivity : BaseActivity + val resultCode = result.resultCode + val data = result.data + + if (resultCode == RESULT_OK) { + val fileUri = data?.data + + if (fileUri != null) { + val mime = contentResolver.getType(fileUri) + + if (mime.equals("image/gif", ignoreCase = true)) { + handleGifImage(fileUri) + } else { + launchCrop(fileUri) + } + } else { + showWrongImageFile() + } + } else if (resultCode == ImagePicker.RESULT_ERROR) { + showImagePickerError(data = data) + } + } + + private fun launchImagePicker() { + ImagePicker.with(this) + .galleryOnly() + .createIntent { imageSelectResult.launch(it) } + } + + private fun launchCrop(fileUri: Uri) { + croppedTempFile = File.createTempFile("cropped_", ".jpg", cacheDir) + + val destinationUri = Uri.fromFile(croppedTempFile) + + val options = UCrop.Options().apply { + setFreeStyleCropEnabled(true) + setToolbarTitle("이미지 자르기") + } + + val uCrop = UCrop.of(fileUri, destinationUri) + .withOptions(options) + .withMaxResultSize(1080, 1080) + + imageCropResult.launch(uCrop.getIntent(this)) + } + + private fun handleGifImage(fileUri: Uri) { + binding.ivContent.background = null + + Glide.with(this) + .asGif() + .load(fileUri) + .placeholder(R.drawable.ic_place_holder) + .apply( + RequestOptions().transform( + RoundedCorners( + 8f.dpToPx().toInt() + ) + ) + ) + .into(binding.ivContent) + + viewModel.imageUri = fileUri + } + + private fun handleCroppedImage(fileUri: Uri) { + binding.ivContent.background = null + + Glide.with(this) + .load(fileUri) + .placeholder(R.drawable.ic_place_holder) + .apply( + RequestOptions().transform( + RoundedCorners( + 8f.dpToPx().toInt() + ) + ) + ) + .into(binding.ivContent) + + viewModel.imageUri = fileUri + } + + private fun showWrongImageFile() { + Toast.makeText( + this, + "잘못된 파일입니다.\n다시 선택해 주세요.", + Toast.LENGTH_SHORT + ).show() + } + + private fun showImagePickerError(data: Intent?) { + Toast.makeText( + this, + ImagePicker.getError(data), + Toast.LENGTH_SHORT + ).show() + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) checkPermissions() @@ -89,25 +188,32 @@ class CreatorCommunityModifyActivity : BaseActivity val resultCode = result.resultCode @@ -44,30 +50,120 @@ class CreatorCommunityWriteActivity : BaseActivity + val resultCode = result.resultCode + val data = result.data + + if (resultCode == RESULT_OK) { + val fileUri = data?.data + + if (fileUri != null) { + val mime = contentResolver.getType(fileUri) + + if (mime.equals("image/gif", ignoreCase = true)) { + handleGifImage(fileUri) + } else { + launchCrop(fileUri) + } + } else { + showWrongImageFile() + } + } else if (resultCode == ImagePicker.RESULT_ERROR) { + showImagePickerError(data = data) + } + } + + private fun launchImagePicker() { + ImagePicker.with(this) + .galleryOnly() + .createIntent { imageSelectResult.launch(it) } + } + + private fun launchCrop(fileUri: Uri) { + croppedTempFile = File.createTempFile("cropped_", ".jpg", cacheDir) + + val destinationUri = Uri.fromFile(croppedTempFile) + + val options = UCrop.Options().apply { + setFreeStyleCropEnabled(true) + setToolbarTitle("이미지 자르기") + } + + val uCrop = UCrop.of(fileUri, destinationUri) + .withOptions(options) + .withMaxResultSize(1080, 1080) + + imageCropResult.launch(uCrop.getIntent(this)) + } + + private fun handleGifImage(fileUri: Uri) { + binding.llRecordAudio.visibility = View.VISIBLE + binding.ivContent.background = null + + Glide.with(this) + .asGif() + .load(fileUri) + .placeholder(R.drawable.ic_place_holder) + .apply( + RequestOptions().transform( + RoundedCorners( + 8f.dpToPx().toInt() + ) + ) + ) + .into(binding.ivContent) + + viewModel.setImageUri(fileUri) + } + + private fun handleCroppedImage(fileUri: Uri) { + binding.llRecordAudio.visibility = View.VISIBLE + binding.ivContent.background = null + + Glide.with(this) + .load(fileUri) + .placeholder(R.drawable.ic_place_holder) + .apply( + RequestOptions().transform( + RoundedCorners( + 8f.dpToPx().toInt() + ) + ) + ) + .into(binding.ivContent) + + viewModel.setImageUri(fileUri) + } + + private fun showWrongImageFile() { + binding.llRecordAudio.visibility = View.GONE + Toast.makeText( + this, + "잘못된 파일입니다.\n다시 선택해 주세요.", + Toast.LENGTH_SHORT + ).show() + } + + private fun showImagePickerError(data: Intent?) { + binding.llRecordAudio.visibility = View.GONE + Toast.makeText( + this, + ImagePicker.getError(data), + Toast.LENGTH_SHORT + ).show() + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) checkPermissions() @@ -81,6 +177,9 @@ class CreatorCommunityWriteActivity : BaseActivity - + android:src="@drawable/ic_logo2" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - + android:src="@drawable/ic_camera" + app:layout_constraintBottom_toBottomOf="@+id/iv_content" + app:layout_constraintStart_toEndOf="@+id/iv_content" /> + + - + android:src="@drawable/ic_logo2" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - + android:src="@drawable/ic_camera" + app:layout_constraintBottom_toBottomOf="@+id/iv_content" + app:layout_constraintStart_toEndOf="@+id/iv_content" /> + + @@ -129,8 +141,8 @@