From 481cad1a46c7139c31836d7bb81c34d55a7d1660 Mon Sep 17 00:00:00 2001 From: klaus Date: Mon, 25 Dec 2023 04:09:25 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 2 + .../explorer/profile/UserProfileActivity.kt | 6 +- .../creator_community/CreatorCommunityApi.kt | 12 + .../CreatorCommunityRepository.kt | 12 + .../write/CreateCommunityPostRequest.kt | 9 + .../write/CreatorCommunityWriteActivity.kt | 248 +++++++++++++ .../write/CreatorCommunityWriteViewModel.kt | 136 +++++++ app/src/main/res/drawable-xxhdpi/ic_logo2.png | Bin 0 -> 11299 bytes .../drawable/bg_round_corner_33_3_3bb9f1.xml | 8 + .../drawable/bg_round_corner_6_7_13181b.xml | 8 + .../bg_round_corner_6_7_13181b_3bb9f1.xml | 8 + .../drawable/bg_round_corner_6_7_3bb9f1.xml | 8 + .../activity_creator_community_write.xml | 346 ++++++++++++++++++ 14 files changed, 803 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreateCommunityPostRequest.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteActivity.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteViewModel.kt create mode 100644 app/src/main/res/drawable-xxhdpi/ic_logo2.png create mode 100644 app/src/main/res/drawable/bg_round_corner_33_3_3bb9f1.xml create mode 100644 app/src/main/res/drawable/bg_round_corner_6_7_13181b.xml create mode 100644 app/src/main/res/drawable/bg_round_corner_6_7_13181b_3bb9f1.xml create mode 100644 app/src/main/res/drawable/bg_round_corner_6_7_3bb9f1.xml create mode 100644 app/src/main/res/layout/activity_creator_community_write.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 042874c..2942fa8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -97,6 +97,7 @@ + diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt index cd468ac..1ab76d6 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt @@ -34,6 +34,7 @@ import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommun import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllViewModel import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreatorCommunityCommentListViewModel +import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteViewModel import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewModel import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewModel import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListViewModel @@ -219,6 +220,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) { viewModel { RouletteSettingsViewModel(get()) } viewModel { CreatorCommunityAllViewModel(get()) } viewModel { CreatorCommunityCommentListViewModel(get()) } + viewModel { CreatorCommunityWriteViewModel(get()) } } private val repositoryModule = module { diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt index 959b29e..3faddb8 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt @@ -37,6 +37,7 @@ import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity +import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteActivity import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAdapter import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity @@ -474,7 +475,9 @@ class UserProfileActivity : BaseActivity( } private fun setupCreatorCommunityView() { - binding.layoutCreatorCommunityPost.ivWrite.setOnClickListener { } + binding.layoutCreatorCommunityPost.ivWrite.setOnClickListener { + startActivity(Intent(applicationContext, CreatorCommunityWriteActivity::class.java)) + } binding.layoutCreatorCommunityPost.llAll.setOnClickListener { startActivity( Intent(applicationContext, CreatorCommunityAllActivity::class.java).apply { @@ -706,6 +709,7 @@ class UserProfileActivity : BaseActivity( binding.layoutCreatorCommunityPost.ivWrite.visibility = View.GONE } + binding.layoutCreatorCommunityPost.llContainer.removeAllViews() communityPostList.forEachIndexed { index, item -> val layout = ItemCreatorCommunityBinding.inflate( LayoutInflater.from(this@UserProfileActivity), diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt index 4c0043a..40ea926 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityApi.kt @@ -5,15 +5,27 @@ import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest +import okhttp3.MultipartBody +import okhttp3.RequestBody import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.Header +import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.PUT +import retrofit2.http.Part import retrofit2.http.Path import retrofit2.http.Query interface CreatorCommunityApi { + @POST("/creator-community") + @Multipart + fun createCommunityPost( + @Part postImage: MultipartBody.Part?, + @Part("request") request: RequestBody, + @Header("Authorization") authHeader: String + ): Single> + @GET("/creator-community") fun getCommunityPostList( @Query("creatorId") creatorId: Long, diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt index 27db775..e192173 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/CreatorCommunityRepository.kt @@ -3,6 +3,8 @@ package kr.co.vividnext.sodalive.explorer.profile.creator_community import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest +import okhttp3.MultipartBody +import okhttp3.RequestBody import java.util.TimeZone class CreatorCommunityRepository(private val api: CreatorCommunityApi) { @@ -70,4 +72,14 @@ class CreatorCommunityRepository(private val api: CreatorCommunityApi) { timezone = TimeZone.getDefault().id, authHeader = token ) + + fun createCommunityPost( + postImage: MultipartBody.Part?, + request: RequestBody, + token: String + ) = api.createCommunityPost( + postImage = postImage, + request = request, + authHeader = token + ) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreateCommunityPostRequest.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreateCommunityPostRequest.kt new file mode 100644 index 0000000..0ad6361 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreateCommunityPostRequest.kt @@ -0,0 +1,9 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community.write + +import com.google.gson.annotations.SerializedName + +data class CreateCommunityPostRequest( + @SerializedName("content") val content: String, + @SerializedName("isAdult") val isAdult: Boolean, + @SerializedName("isCommentAvailable") val isCommentAvailable: Boolean +) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteActivity.kt new file mode 100644 index 0000000..5748420 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteActivity.kt @@ -0,0 +1,248 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community.write + +import android.Manifest +import android.annotation.SuppressLint +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.github.dhaval2404.imagepicker.ImagePicker +import com.gun0912.tedpermission.PermissionListener +import com.gun0912.tedpermission.normal.TedPermission +import com.jakewharton.rxbinding4.widget.textChanges +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.schedulers.Schedulers +import kr.co.vividnext.sodalive.R +import kr.co.vividnext.sodalive.base.BaseActivity +import kr.co.vividnext.sodalive.common.LoadingDialog +import kr.co.vividnext.sodalive.common.RealPathUtil +import kr.co.vividnext.sodalive.common.SharedPreferenceManager +import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityWriteBinding +import kr.co.vividnext.sodalive.extensions.dpToPx +import org.koin.android.ext.android.inject + +class CreatorCommunityWriteActivity : BaseActivity( + ActivityCreatorCommunityWriteBinding::inflate +) { + + private val viewModel: CreatorCommunityWriteViewModel by inject() + + private lateinit var loadingDialog: LoadingDialog + + private val imageResult = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { result -> + val resultCode = result.resultCode + val data = result.data + + if (resultCode == RESULT_OK) { + val fileUri = data?.data + + if (fileUri != null) { + binding.ivContent.background = null + binding.ivContent.load(fileUri) { + crossfade(true) + placeholder(R.drawable.ic_place_holder) + transformations(RoundedCornersTransformation(8f.dpToPx())) + } + viewModel.imageUri = fileUri + } else { + Toast.makeText( + this, + "잘못된 파일입니다.\n다시 선택해 주세요.", + Toast.LENGTH_SHORT + ).show() + } + } else if (resultCode == ImagePicker.RESULT_ERROR) { + Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + checkPermissions() + + viewModel.getRealPathFromURI = { + RealPathUtil.getRealPath(applicationContext, it) + } + + bindData() + } + + override fun setupView() { + loadingDialog = LoadingDialog(this, layoutInflater) + + binding.toolbar.tvBack.text = "게시글 등록" + binding.toolbar.tvBack.setOnClickListener { finish() } + + binding.ivPhotoPicker.setOnClickListener { + ImagePicker.with(this) + .crop() + .galleryOnly() + .galleryMimeTypes( // Exclude gif images + mimeTypes = arrayOf( + "image/png", + "image/jpg", + "image/jpeg" + ) + ) + .createIntent { imageResult.launch(it) } + } + + if (SharedPreferenceManager.isAuth) { + binding.llSetAdult.visibility = View.VISIBLE + } else { + binding.llSetAdult.visibility = View.GONE + } + + binding.llCommentNo.setOnClickListener { viewModel.setAvailableComment(false) } + binding.llCommentYes.setOnClickListener { viewModel.setAvailableComment(true) } + binding.tvCancel.setOnClickListener { finish() } + binding.tvUpload.setOnClickListener { + viewModel.createCommunityPost { finish() } + } + } + + private fun checkPermissions() { + val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + listOf(Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_IMAGES) + } else { + listOf(Manifest.permission.READ_EXTERNAL_STORAGE) + } + + TedPermission.create() + .setPermissionListener(object : PermissionListener { + override fun onPermissionGranted() { + } + + override fun onPermissionDenied(deniedPermissions: MutableList?) { + finish() + } + }) + .setDeniedMessage(R.string.read_storage_permission_denied_message) + .setPermissions(*permissions.toTypedArray()) + .check() + } + + @SuppressLint("SetTextI18n") + private fun bindData() { + compositeDisposable.add( + binding.etContent.textChanges().skip(1) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + binding.tvNumberOfCharacters.text = "${it.length}자" + viewModel.content = it.toString() + } + ) + + viewModel.toastLiveData.observe(this) { + it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() } + } + + viewModel.isLoading.observe(this) { + if (it) { + loadingDialog.show(screenWidth) + } else { + loadingDialog.dismiss() + } + } + + viewModel.isAvailableCommentLiveData.observe(this) { + if (it) { + binding.ivCommentYes.visibility = View.VISIBLE + binding.tvCommentYes.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.white + ) + ) + binding.llCommentYes.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1) + + binding.ivCommentNo.visibility = View.GONE + binding.tvCommentNo.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.color_80d8ff + ) + ) + binding.llCommentNo.setBackgroundResource( + R.drawable.bg_round_corner_6_7_13181b + ) + } else { + binding.ivCommentNo.visibility = View.VISIBLE + binding.tvCommentNo.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.white + ) + ) + binding.llCommentNo.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1) + + binding.ivCommentYes.visibility = View.GONE + binding.tvCommentYes.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.color_80d8ff + ) + ) + binding.llCommentYes + .setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b) + } + } + + if (SharedPreferenceManager.isAuth) { + binding.llAgeAll.setOnClickListener { + viewModel.setAdult(false) + } + + binding.llAge19.setOnClickListener { + viewModel.setAdult(true) + } + + viewModel.isAdultLiveData.observe(this) { + if (it) { + binding.ivAgeAll.visibility = View.GONE + binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b) + binding.tvAgeAll.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.color_80d8ff + ) + ) + + binding.ivAge19.visibility = View.VISIBLE + binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1) + binding.tvAge19.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.white + ) + ) + } else { + binding.ivAge19.visibility = View.GONE + binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b) + binding.tvAge19.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.color_80d8ff + ) + ) + + binding.ivAgeAll.visibility = View.VISIBLE + binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1) + binding.tvAgeAll.setTextColor( + ContextCompat.getColor( + applicationContext, + R.color.white + ) + ) + } + } + } + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteViewModel.kt new file mode 100644 index 0000000..df1deaf --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/write/CreatorCommunityWriteViewModel.kt @@ -0,0 +1,136 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community.write + +import android.net.Uri +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.google.gson.Gson +import com.orhanobut.logger.Logger +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.schedulers.Schedulers +import kr.co.vividnext.sodalive.base.BaseViewModel +import kr.co.vividnext.sodalive.common.SharedPreferenceManager +import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository +import okhttp3.MediaType +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MultipartBody +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okio.BufferedSink +import java.io.File + +class CreatorCommunityWriteViewModel(private val repository: CreatorCommunityRepository +): BaseViewModel() { + private val _toastLiveData = MutableLiveData() + val toastLiveData: LiveData + get() = _toastLiveData + + private var _isLoading = MutableLiveData(false) + val isLoading: LiveData + get() = _isLoading + + private val _isAdultLiveData = MutableLiveData(false) + val isAdultLiveData: LiveData + get() = _isAdultLiveData + + private val _isAvailableCommentLiveData = MutableLiveData(true) + val isAvailableCommentLiveData: LiveData + get() = _isAvailableCommentLiveData + + lateinit var getRealPathFromURI: (Uri) -> String? + + var content = "" + var imageUri: Uri? = null + + fun setAdult(isAdult: Boolean) { + _isAdultLiveData.postValue(isAdult) + } + + fun setAvailableComment(isAvailableComment: Boolean) { + _isAvailableCommentLiveData.postValue(isAvailableComment) + } + + fun createCommunityPost(onSuccess: () -> Unit) { + if (!_isLoading.value!! && validateData()) { + _isLoading.postValue(true) + + val request = CreateCommunityPostRequest( + content = content, + isAdult = _isAdultLiveData.value!!, + isCommentAvailable = _isAvailableCommentLiveData.value!! + ) + + val requestJson = Gson().toJson(request) + + val postImage = if (imageUri != null) { + val file = File(getRealPathFromURI(imageUri!!)) + MultipartBody.Part.createFormData( + "postImage", + file.name, + body = object : RequestBody() { + override fun contentType(): MediaType { + return "image/*".toMediaType() + } + + override fun writeTo(sink: BufferedSink) { + file.inputStream().use { inputStream -> + val buffer = ByteArray(1024) + var bytesRead: Int + while (inputStream.read(buffer).also { bytesRead = it } != -1) { + sink.write(buffer, 0, bytesRead) + } + } + } + + override fun contentLength(): Long { + return file.length() + } + } + ) + } else { + null + } + + compositeDisposable.add( + repository.createCommunityPost( + postImage = postImage, + request = requestJson.toRequestBody("text/plain".toMediaType()), + token = "Bearer ${SharedPreferenceManager.token}" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + if (it.success && it.data != null) { + onSuccess() + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + _isLoading.postValue(false) + }, + { + _isLoading.postValue(false) + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + ) + ) + } + } + + private fun validateData(): Boolean { + if (content.isBlank() || content.length < 5) { + _toastLiveData.postValue("내용을 5자 이상 입력해 주세요.") + return false + } + + return true + } +} diff --git a/app/src/main/res/drawable-xxhdpi/ic_logo2.png b/app/src/main/res/drawable-xxhdpi/ic_logo2.png new file mode 100644 index 0000000000000000000000000000000000000000..c13cfe660fda503359112788ea8c94c3c87a5741 GIT binary patch literal 11299 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 + + + + + diff --git a/app/src/main/res/drawable/bg_round_corner_6_7_13181b.xml b/app/src/main/res/drawable/bg_round_corner_6_7_13181b.xml new file mode 100644 index 0000000..12bdf0f --- /dev/null +++ b/app/src/main/res/drawable/bg_round_corner_6_7_13181b.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_round_corner_6_7_13181b_3bb9f1.xml b/app/src/main/res/drawable/bg_round_corner_6_7_13181b_3bb9f1.xml new file mode 100644 index 0000000..282e552 --- /dev/null +++ b/app/src/main/res/drawable/bg_round_corner_6_7_13181b_3bb9f1.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_round_corner_6_7_3bb9f1.xml b/app/src/main/res/drawable/bg_round_corner_6_7_3bb9f1.xml new file mode 100644 index 0000000..fb1d9cf --- /dev/null +++ b/app/src/main/res/drawable/bg_round_corner_6_7_3bb9f1.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_creator_community_write.xml b/app/src/main/res/layout/activity_creator_community_write.xml new file mode 100644 index 0000000..9353ca4 --- /dev/null +++ b/app/src/main/res/layout/activity_creator_community_write.xml @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +