Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kuring-101 피드백 보내기 화면 2.0 디자인 적용 #85

Merged
merged 15 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import com.ku_stacks.ku_ring.designsystem.R

private val KuringGreen: Color
val KuringGreen: Color
@Composable get() = colorResource(R.color.kus_green)
private val KuringGreen50: Color
val KuringGreen50: Color
@Composable get() = colorResource(R.color.kus_green_50)
private val KuringSecondaryGreen: Color
val KuringSecondaryGreen: Color
@Composable get() = colorResource(R.color.kus_secondary_green)
val KuringSub: Color
@Composable get() = Color(0xFFECF9F3)
Expand All @@ -33,4 +33,4 @@ val darkColorPalette: Colors
primary = KuringGreen,
primaryVariant = KuringGreen50,
secondary = KuringSecondaryGreen,
)
)
6 changes: 4 additions & 2 deletions common/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@
<string name="feedback_send_content">피드백 보내기</string>
<string name="feedback_title">피드백을 남겨서 앱이 성장하는데에 \n큰 기여를 해주세요 🙂</string>
<string name="feedback_hint">피드백을 남겨주세요…</string>
<string name="feedback_guide">피드백을 보내주시면 \n앱 성장에 많은 도움이 됩니다 :)</string>
<string name="feedback_too_short">글자 수는 5글자 이상이어야 합니다.</string>
<string name="feedback_too_long">글자 수는 256글자 이하여야 합니다.</string>
<string name="feedback_success">피드백이 정상적으로 전송되었습니다</string>
<string name="feedback_write_more_character">5글자 이상 입력해주세요</string>
<string name="feedback_write_more_character">최소 5글자 이상 작성해주세요</string>
<string name="feedback_write_more">5글자 이상 작성해주세요</string>
<string name="feedback_size_of_character">글자수 : %s/256</string>
<string name="feedback_cannot_send">피드백을 보낼 수 없습니다. fcm 토큰을 확인해주세요</string>

Expand Down Expand Up @@ -163,4 +165,4 @@

<!-- common-advertise -->
<string name="admob_test_banner_id">ca-app-pub-3940256099942544/6300978111</string>
</resources>
</resources>
3 changes: 2 additions & 1 deletion feature/feedback/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ android {

dependencies {
implementation project(":common:util")
implementation project(":common:designsystem")
testImplementation testFixtures(project(":common:util"))
implementation project(":common:ui_util")
implementation project(":common:thirdparty")
Expand Down Expand Up @@ -93,4 +94,4 @@ dependencies {

// soft keyboard listener
implementation libs.keyboardvisibilityevent
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,41 @@ package com.ku_stacks.ku_ring.feedback.feedback
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.ku_stacks.ku_ring.designsystem.theme.KuringTheme
import com.ku_stacks.ku_ring.feedback.R
import com.ku_stacks.ku_ring.feedback.databinding.ActivityFeedbackBinding
import com.ku_stacks.ku_ring.ui_util.modified_external_library.AppearanceAnimator
import com.ku_stacks.ku_ring.feedback.feedback.compose.FeedbackScreen
import com.ku_stacks.ku_ring.ui_util.showToast
import dagger.hilt.android.AndroidEntryPoint
import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent

@AndroidEntryPoint
class FeedbackActivity : AppCompatActivity() {

private lateinit var binding: ActivityFeedbackBinding
private val viewModel by viewModels<FeedbackViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setupBinding()
setupKeyboardListener()
setupEditText()
observeData()
setupView()
observeViewModel()
}

private fun setupBinding() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_feedback)
binding.lifecycleOwner = this
binding.viewModel = viewModel
private fun setupView() {
setContent {
KuringTheme {
FeedbackScreen(
viewModel = viewModel,
modifier = Modifier.fillMaxSize(),
)
}
}
}

private fun observeData() {
private fun observeViewModel() {
viewModel.quit.observe(this) {
finish()
}
Expand All @@ -48,54 +49,16 @@ class FeedbackActivity : AppCompatActivity() {
}
}

private fun setupKeyboardListener() {
KeyboardVisibilityEvent.setEventListener(this, this) { isOpen ->
if (isOpen) {
AppearanceAnimator.collapse(binding.feedbackChatImg)
AppearanceAnimator.collapse(binding.feedbackTitleTxt)
} else {
val initialHeightOfFeedbackImg = 110
AppearanceAnimator.expand(binding.feedbackChatImg, initialHeightOfFeedbackImg)
AppearanceAnimator.expand(binding.feedbackTitleTxt)
}
}
}

private fun setupEditText() {
binding.feedbackEt.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable?) {
val strLength = s.toString().length
binding.feedbackAdviceTxt.text = when {
strLength < 5 -> {
viewModel.canSendFeedback.postValue(false)
getString(R.string.feedback_write_more_character)
}

strLength > 256 -> {
viewModel.canSendFeedback.postValue(false)
String.format(getString(R.string.feedback_size_of_character), strLength)
}

else -> {
viewModel.canSendFeedback.postValue(true)
String.format(getString(R.string.feedback_size_of_character), strLength)
}
}
}
})
}

override fun onBackPressed() {
super.onBackPressed()
override fun finish() {
super.finish()
overridePendingTransition(R.anim.anim_slide_left_enter, R.anim.anim_slide_left_exit)
}

companion object {
fun start(activity: Activity) {
val intent = Intent(activity, FeedbackActivity::class.java)
activity.startActivity(intent)
activity.overridePendingTransition(R.anim.anim_slide_right_enter, R.anim.anim_stay_exit)
mwy3055 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ku_stacks.ku_ring.feedback.feedback

enum class FeedbackTextStatus {
INITIAL,
TOO_SHORT,
TOO_LONG,
NORMAL,
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.ku_stacks.ku_ring.feedback.feedback

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.messaging.FirebaseMessaging
import com.ku_stacks.ku_ring.feedback.R
import com.ku_stacks.ku_ring.thirdparty.firebase.analytics.EventAnalytics
Expand All @@ -12,6 +12,11 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import timber.log.Timber
import javax.inject.Inject

Expand All @@ -24,8 +29,21 @@ class FeedbackViewModel @Inject constructor(

private val disposable = CompositeDisposable()

val feedbackContent = MutableLiveData("")
val canSendFeedback = MutableLiveData(false)
private val _feedbackContent = MutableStateFlow("")
val feedbackContent = _feedbackContent.asStateFlow()

val textStatus = feedbackContent.map {
when (it.length) {
0 -> FeedbackTextStatus.INITIAL
in 1..MIN_FEEDBACK_CONTENT_LENGTH -> FeedbackTextStatus.TOO_SHORT
in MIN_FEEDBACK_CONTENT_LENGTH + 1..MAX_FEEDBACK_CONTENT_LENGTH -> FeedbackTextStatus.NORMAL
else -> FeedbackTextStatus.TOO_LONG
}
}.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = FeedbackTextStatus.INITIAL
)

private val _quit = SingleLiveEvent<Unit>()
val quit: LiveData<Unit>
Expand Down Expand Up @@ -60,15 +78,15 @@ class FeedbackViewModel @Inject constructor(
return@addOnCompleteListener
}

val content = feedbackContent.value ?: ""
if (content.length < 5) {
if (textStatus.value == FeedbackTextStatus.TOO_SHORT) {
_toastByResource.value = R.string.feedback_too_short
return@addOnCompleteListener
} else if (content.length > 256) {
} else if (textStatus.value == FeedbackTextStatus.TOO_LONG) {
_toastByResource.value = R.string.feedback_too_long
return@addOnCompleteListener
}

val content = feedbackContent.value
userRepository.sendFeedback(content)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
Expand All @@ -89,6 +107,10 @@ class FeedbackViewModel @Inject constructor(
}
}

fun updateFeedbackContent(text: String) {
_feedbackContent.value = text
}

fun closeFeedback() {
analytics.click("close feedback button", "FeedbackActivity")
_quit.call()
Expand All @@ -104,5 +126,8 @@ class FeedbackViewModel @Inject constructor(

companion object {
private val className: String = FeedbackViewModel::class.java.simpleName

const val MIN_FEEDBACK_CONTENT_LENGTH = 4
const val MAX_FEEDBACK_CONTENT_LENGTH = 256
}
}
}
Loading
Loading