diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/BindingAdapters.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/BindingAdapters.kt deleted file mode 100644 index 835f4eae..00000000 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/BindingAdapters.kt +++ /dev/null @@ -1,610 +0,0 @@ -package com.on.staccato.presentation - -import android.graphics.drawable.Drawable -import android.net.Uri -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.NumberPicker -import android.widget.ProgressBar -import android.widget.ScrollView -import android.widget.TextView -import androidx.core.view.isGone -import androidx.core.view.isInvisible -import androidx.databinding.BindingAdapter -import coil.load -import coil.transform.RoundedCornersTransformation -import com.airbnb.lottie.LottieAnimationView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.google.android.material.button.MaterialButton -import com.on.staccato.R -import com.on.staccato.domain.model.MemoryCandidate -import com.on.staccato.domain.model.MemoryCandidates -import com.on.staccato.presentation.momentcreation.model.AttachedPhotosUiModel -import com.on.staccato.presentation.timeline.model.TimelineUiModel -import okhttp3.internal.format -import java.time.LocalDate -import java.time.LocalDateTime - -@BindingAdapter( - value = ["coilImageUrl", "coilPlaceHolder"], -) -fun ImageView.loadImageWithCoil( - url: String?, - placeHolder: Drawable? = null, -) { - load(url) { - placeholder(placeHolder) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["coilImageUri", "coilPlaceHolder"], -) -fun ImageView.loadImageByUriWithCoil( - uri: Uri?, - placeHolder: Drawable? = null, -) { - load(uri) { - placeholder(placeHolder) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["coilCircleImageUrl", "coilPlaceHolder"], -) -fun ImageView.setCircleImageWithCoil( - url: String?, - placeHolder: Drawable? = null, -) { - load(url) { - placeholder(placeHolder) - transformations(RoundedCornersTransformation(1000f)) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["coilRoundedCornerImageUrl", "coilPlaceHolder", "coilRoundingRadius"], -) -fun ImageView.setRoundedCornerImageWithCoil( - url: String?, - placeHolder: Drawable? = null, - roundingRadius: Float, -) { - load(url) { - placeholder(placeHolder) - transformations(RoundedCornersTransformation(roundingRadius)) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["coilUriRoundedCorner", "coilUriPlaceHolder", "coilUriRoundingRadius"], -) -fun ImageView.setRoundedCornerUriWithCoil( - uri: Uri?, - placeHolder: Drawable? = null, - roundingRadius: Float, -) { - load(uri) { - placeholder(placeHolder) - transformations(RoundedCornersTransformation(roundingRadius)) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["coilImageUrl", "coilImageUri", "coilPlaceHolder", "coilRoundingRadius"], -) -fun ImageView.setRoundedCornerUpdateImageWithCoil( - url: String?, - uri: Uri?, - placeHolder: Drawable? = null, - roundingRadius: Float, -) { - val image = uri ?: url - load(image) { - placeholder(placeHolder) - transformations(RoundedCornersTransformation(roundingRadius)) - error(placeHolder) - } -} - -@BindingAdapter( - value = ["glideImageUrl", "glidePlaceHolder"], -) -fun ImageView.loadImageWithGlide( - url: String?, - placeHolder: Drawable? = null, -) { - Glide.with(context) - .load(url) - .placeholder(placeHolder) - .centerCrop() - .error(placeHolder) - .into(this) -} - -@BindingAdapter( - value = ["glideCircleImageUrl", "glidePlaceHolder"], -) -fun ImageView.setCircleImageWithGlide( - url: String?, - placeHolder: Drawable? = null, -) { - Glide.with(context) - .load(url) - .placeholder(placeHolder) - .circleCrop() - .error(placeHolder) - .into(this) -} - -@BindingAdapter( - value = ["glideRoundedCornerImageUrl", "glidePlaceHolder", "glideRoundingRadius"], -) -fun ImageView.setRoundedCornerImageWithGlide( - url: String?, - placeHolder: Drawable? = null, - roundingRadius: Int, -) { - Glide.with(context) - .load(url) - .placeholder(placeHolder) - .centerCrop() - .apply(RequestOptions.bitmapTransform(RoundedCorners(roundingRadius))) - .error(placeHolder) - .into(this) -} - -@BindingAdapter(value = ["glideUriRoundedCornerImageUri", "glideUriPlaceHolder", "glideUriRoundingRadius"]) -fun ImageView.setRoundedCornerImageByUriWithGlide( - uri: Uri?, - placeHolder: Drawable? = null, - roundingRadius: Int, -) { - Glide.with(context) - .load(uri) - .centerCrop() - .apply(RequestOptions.bitmapTransform(RoundedCorners(roundingRadius))) - .error(placeHolder) - .into(this) -} - -@BindingAdapter( - value = ["memoryTitle", "startDate", "endDate", "isPeriodActive", "isPhotoPosting"], -) -fun Button.setMemorySaveButtonActive( - title: String?, - startDate: LocalDate?, - endDate: LocalDate?, - isPeriodActive: Boolean, - isPhotoPosting: Boolean?, -) { - val isPeriodNotExistent = (startDate == null) || (endDate == null) - val isPeriodRequirementsInvalid = isPeriodActive && isPeriodNotExistent - isEnabled = - if (title.isNullOrBlank() || isPhotoPosting == true || isPeriodRequirementsInvalid) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter( - value = ["staccatoTitle", "address", "visitedAt", "photos", "selectedMemory"], -) -fun Button.setStaccatoCreationButtonActive( - title: String?, - address: String?, - visitedAt: LocalDateTime?, - photos: AttachedPhotosUiModel?, - selectedMemory: MemoryCandidate?, -) { - isEnabled = - if (title.isNullOrBlank() || address == null || selectedMemory == null || visitedAt == null || photos?.isLoading() == true) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter(value = ["setSelectedMemory", "setMemoryCandidates"]) -fun TextView.setSelectedMemory( - selectedMemory: MemoryCandidate?, - memoryCandidates: MemoryCandidates?, -) { - if (memoryCandidates?.memoryCandidate?.isEmpty() == true) { - text = resources.getString(R.string.visit_creation_no_memory_hint) - setTextColor(resources.getColor(R.color.gray3, null)) - isClickable = false - isFocusable = false - } else if (selectedMemory == null) { - text = resources.getString(R.string.visit_creation_memory_selection_hint) - setTextColor(resources.getColor(R.color.gray3, null)) - isClickable = true - isFocusable = true - } else { - text = selectedMemory.memoryTitle - setTextColor(resources.getColor(R.color.staccato_black, null)) - } -} - -@BindingAdapter(value = ["setDateTimeWithAmPm", "setMemoryCandidates"]) -fun TextView.setDateTimeWithAmPm( - setNowDateTime: LocalDateTime?, - memoryCandidates: MemoryCandidates?, -) { - if (memoryCandidates?.memoryCandidate?.isEmpty() == true) { - text = resources.getString(R.string.visit_creation_memory_selection_hint) - setTextColor(resources.getColor(R.color.gray3, null)) - isClickable = false - isFocusable = false - } else { - text = setNowDateTime?.let(::getFormattedLocalDateTime) ?: "" - setTextColor(resources.getColor(R.color.staccato_black, null)) - isClickable = true - isFocusable = true - } -} - -@BindingAdapter("setDateTimeWithAmPm") -fun TextView.setDateTimeWithAmPm(setNowDateTime: LocalDateTime?) { - text = setNowDateTime?.let(::getFormattedLocalDateTime) ?: "" -} - -@BindingAdapter( - value = ["startDate", "endDate"], -) -fun TextView.setMemoryPeriod( - startDate: LocalDate?, - endDate: LocalDate?, -) { - if (startDate == null || endDate == null) { - text = resources.getString(R.string.memory_creation_period_hint) - setTextColor(resources.getColor(R.color.gray3, null)) - } else { - text = - resources.getString(R.string.memory_creation_selected_period) - .format(startDate, endDate) - setTextColor(resources.getColor(R.color.staccato_black, null)) - } -} - -@BindingAdapter("visitedAtConfirmButtonActive") -fun Button.setVisitedAtConfirmButtonActive(items: List?) { - isEnabled = - if (items.isNullOrEmpty()) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter("memoryVisitedAtConfirmButtonActive") -fun Button.setMemoryVisitedAtConfirmButtonActive(items: List?) { - isEnabled = - if (items.isNullOrEmpty()) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter("visitedAtNumberPickerItems") -fun NumberPicker.setVisitedAtNumberPickerItems(items: List?) { - items?.map { it.toLocalDate() } - if (items.isNullOrEmpty()) { - isGone = true - } else { - displayedValues = items.map(::getFormattedLocalDateTime).toTypedArray() - } -} - -@BindingAdapter("localDateNumberPickerItems") -fun NumberPicker.setLocalDateNumberPickerItems(items: List?) { - if (items.isNullOrEmpty()) { - isGone = true - } else { - displayedValues = items.map(::getFormattedLocalDate).toTypedArray() - } -} - -private fun View.getFormattedLocalDate(setNowDate: LocalDate) = - setNowDate.let { - val year = setNowDate.year - val month = setNowDate.monthValue - val day = setNowDate.dayOfMonth - resources.getString(R.string.all_date_kr_format) - .format(year, month, day) - } - -private fun View.getFormattedLocalDateTime(setNowDateTime: LocalDateTime) = - setNowDateTime.let { - val year = setNowDateTime.year - val month = setNowDateTime.monthValue - val day = setNowDateTime.dayOfMonth - val hour = if (setNowDateTime.hour % 12 == 0) 12 else setNowDateTime.hour % 12 - val noonText = if (setNowDateTime.hour < 12) "오전" else "오후" - resources.getString(R.string.all_date_time_am_pm_kr_format) - .format(year, month, day, noonText, hour) - } - -@BindingAdapter("memoryIsEmptyVisibility") -fun TextView.setMemoryIsEmptyVisibility(memoryCandidates: MemoryCandidates?) { - isGone = !memoryCandidates?.memoryCandidate.isNullOrEmpty() -} - -@BindingAdapter("visitedAtIsEmptyVisibility") -fun TextView.setVisitedAtIsEmptyVisibility(items: List?) { - isGone = !items.isNullOrEmpty() -} - -@BindingAdapter("visitedAt") -fun TextView.combineVisitedAt(visitedAt: LocalDateTime?) { - text = - if (visitedAt != null) { - val hour = if (visitedAt.hour % 12 == 0) 12 else visitedAt.hour % 12 - val noonText = if (visitedAt.hour < 12) "오전" else "오후" - format( - resources.getString(R.string.visit_history), - visitedAt.year, - visitedAt.monthValue, - visitedAt.dayOfMonth, - noonText, - hour, - ) - } else { - "" - } -} - -@BindingAdapter( - value = ["startAt", "endAt"], -) -fun TextView.convertLocalDateToDatePeriodString( - startAt: LocalDate?, - endAt: LocalDate?, -) { - val periodFormatString = resources.getString(R.string.memory_period_dot) - text = - if (startAt != null && endAt != null) { - visibility = View.VISIBLE - format( - periodFormatString, - startAt.year, - startAt.monthValue, - startAt.dayOfMonth, - endAt.year, - endAt.monthValue, - endAt.dayOfMonth, - ) - } else { - visibility = View.INVISIBLE - null - } -} - -@BindingAdapter( - value = ["memoryStartAt", "memoryEndAt"], -) -fun TextView.convertLocalDateToDatePeriodStringInMemory( - startAt: LocalDate?, - endAt: LocalDate?, -) { - val periodFormatString = resources.getString(R.string.memory_period_dot) - text = - if (startAt != null && endAt != null) { - visibility = View.VISIBLE - format( - periodFormatString, - startAt.year, - startAt.monthValue, - startAt.dayOfMonth, - endAt.year, - endAt.monthValue, - endAt.dayOfMonth, - ) - } else { - visibility = View.GONE - null - } -} - -@BindingAdapter("setAttachedPhotoVisibility") -fun ImageView.setAttachedPhotoVisibility(items: Array?) { - if (items.isNullOrEmpty()) { - visibility = View.GONE - } else { - visibility = View.VISIBLE - Glide.with(context) - .load(items[0]) - .centerCrop() - .into(this) - } -} - -@BindingAdapter("setAttachedPhotoVisibility") -fun FrameLayout.setAttachedPhotoVisibility(items: Array?) { - isInvisible = !items.isNullOrEmpty() -} - -@BindingAdapter("setEnabled") -fun Button.setEnabled(isUpdateCompleted: Boolean?) { - isEnabled = !(isUpdateCompleted ?: true) -} - -@BindingAdapter("loginEnabled") -fun Button.setLoginEnabled(nickName: String?) { - isEnabled = - if (nickName.isNullOrBlank()) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter(value = ["currentPhotoNumbers", "maxPhotoNumbers"]) -fun TextView.setPhotoNumbers( - currentPhotoNumbers: Int, - maxPhotoNumbers: Int, -) { - text = - resources.getString(R.string.all_photo_number).format(currentPhotoNumbers, maxPhotoNumbers) -} - -@BindingAdapter("photoDragHintVisibility") -fun TextView.setPhotoDragHintVisibility(currentPhotoNumbers: Int) { - isGone = currentPhotoNumbers < 2 -} - -@BindingAdapter("setSelected") -fun ImageView.setSelectedState(selected: Boolean) { - isSelected = selected -} - -@BindingAdapter( - value = [ - "colorImageResource", - "grayImageResource", - ], -) -fun ImageView.setImageResourceWithId( - colorResId: Int, - grayResId: Int, -) { - setImageResource( - if (isSelected) { - colorResId - } else { - grayResId - }, - ) -} - -@BindingAdapter("setAddress") -fun TextView.setAddress(address: String?) { - text = address ?: context.getString(R.string.visit_creation_empty_address) -} - -@BindingAdapter("sendEnabled") -fun ImageView.setSendEnabled(comment: String?) { - isEnabled = !comment.isNullOrBlank() -} - -@BindingAdapter("setLoadingLottieVisibility") -fun LottieAnimationView.setLoadingLottieVisibility(isLoading: Boolean?) { - if (isLoading == true) { - visibility = View.VISIBLE - } else { - visibility = View.GONE - } -} - -@BindingAdapter("setCurrentLocationButtonLoading") -fun MaterialButton.setCurrentLocationButtonLoading(isLoading: Boolean?) { - isClickable = isLoading == false - if (isLoading == true) { - setText(R.string.all_empty) - setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) - } else { - setText(R.string.visit_creation_load_current_location) - } -} - -@BindingAdapter(value = ["thumbnailUri", "thumbnailUrl"]) -fun ProgressBar.setThumbnailLoadingProgressBar( - thumbnailUri: Uri?, - thumbnailUrl: String?, -) { - visibility = - if (thumbnailUri != null && thumbnailUrl == null) { - View.VISIBLE - } else { - View.GONE - } -} - -@BindingAdapter(value = ["thumbnailUri", "thumbnailUrl"]) -fun View.setThumbnail( - thumbnailUri: Uri?, - thumbnailUrl: String?, -) { - visibility = - if (thumbnailUri == null && thumbnailUrl == null) { - View.VISIBLE - } else { - View.GONE - } -} - -@BindingAdapter("periodSelectionVisibility") -fun TextView.setPeriodSelectionVisibility(isChecked: Boolean) { - isGone = !isChecked -} - -@BindingAdapter("recoveryEnabled") -fun Button.setRecoveryEnabled(recoveryCode: String?) { - isEnabled = - if (recoveryCode.isNullOrBlank() || recoveryCode.length < 36) { - setTextColor(resources.getColor(R.color.gray4, null)) - false - } else { - setTextColor(resources.getColor(R.color.white, null)) - true - } -} - -@BindingAdapter("scrollToBottom") -fun ScrollView.scrollToBottom(isPeriodActive: Boolean) { - if (isPeriodActive) { - post { fullScroll(ScrollView.FOCUS_DOWN) } - } -} - -@BindingAdapter( - value = ["visibilityByTimeline", "visibilityByLoading"], -) -fun View.setTimelineEmptyViewVisible( - timeLine: List? = null, - isTimelineLoading: Boolean, -) { - visibility = - if (timeLine.isNullOrEmpty() && isTimelineLoading.not()) { - View.VISIBLE - } else { - View.GONE - } -} - -@BindingAdapter( - value = ["visibilityByTimeline", "visibilityByLoading"], -) -fun ViewGroup.setMemoryAddButtonVisible( - timeLine: List? = null, - isTimelineLoading: Boolean, -) { - visibility = - if (timeLine.isNullOrEmpty() && isTimelineLoading.not()) { - View.GONE - } else { - View.VISIBLE - } -} diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/BindingAdapters.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/BindingAdapters.kt new file mode 100644 index 00000000..ba3dd9f0 --- /dev/null +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/BindingAdapters.kt @@ -0,0 +1,77 @@ +package com.on.staccato.presentation.bindingadapter + +import android.net.Uri +import android.view.View +import android.view.ViewGroup +import android.widget.ProgressBar +import android.widget.ScrollView +import androidx.databinding.BindingAdapter +import com.on.staccato.presentation.timeline.model.TimelineUiModel + +@BindingAdapter("visibleOrGone") +fun View.setVisibility(isVisible: Boolean?) { + visibility = + if (isVisible == true) { + View.VISIBLE + } else { + View.GONE + } +} + +@BindingAdapter("scrollToBottom") +fun ScrollView.setScrollToBottom(isScrollable: Boolean) { + if (isScrollable) { + post { fullScroll(ScrollView.FOCUS_DOWN) } + } +} + +@BindingAdapter(value = ["visibilityByThumbnailUri", "visibilityByThumbnailUrl"]) +fun View.setThumbnail( + thumbnailUri: Uri?, + thumbnailUrl: String?, +) { + visibility = + if (thumbnailUri == null && thumbnailUrl == null) { + View.VISIBLE + } else { + View.GONE + } +} + +@BindingAdapter(value = ["visibilityByThumbnailUri", "visibilityByThumbnailUrl"]) +fun ProgressBar.setThumbnailLoadingProgressBar( + thumbnailUri: Uri?, + thumbnailUrl: String?, +) { + visibility = + if (thumbnailUri != null && thumbnailUrl == null) { + View.VISIBLE + } else { + View.GONE + } +} + +@BindingAdapter( + value = ["visibilityByTimeline", "visibilityByLoading"], +) +fun View.setTimelineEmptyViewVisible( + timeLine: List? = null, + isTimelineLoading: Boolean, +) { + visibility = if (isTimeLineEmpty(timeLine, isTimelineLoading)) View.VISIBLE else View.GONE +} + +@BindingAdapter( + value = ["visibilityByTimeline", "visibilityByLoading"], +) +fun ViewGroup.setMemoryAddButtonVisible( + timeLine: List? = null, + isTimelineLoading: Boolean, +) { + visibility = if (isTimeLineEmpty(timeLine, isTimelineLoading)) View.GONE else View.VISIBLE +} + +private fun isTimeLineEmpty( + timeLine: List?, + isTimelineLoading: Boolean, +) = timeLine.isNullOrEmpty() && isTimelineLoading.not() diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ButtonBindingAdapter.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ButtonBindingAdapter.kt new file mode 100644 index 00000000..e85d110f --- /dev/null +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ButtonBindingAdapter.kt @@ -0,0 +1,112 @@ +package com.on.staccato.presentation.bindingadapter + +import android.widget.Button +import android.widget.ImageButton +import androidx.databinding.BindingAdapter +import com.google.android.material.button.MaterialButton +import com.on.staccato.R +import com.on.staccato.domain.model.MemoryCandidate +import com.on.staccato.presentation.momentcreation.model.AttachedPhotosUiModel +import java.time.LocalDate +import java.time.LocalDateTime + +@BindingAdapter("loginButtonEnabled") +fun Button.setLoginButtonEnabled(nickName: String?) { + isEnabled = + if (nickName.isNullOrBlank()) { + setTextColor(resources.getColor(R.color.gray4, null)) + false + } else { + setTextColor(resources.getColor(R.color.white, null)) + true + } +} + +@BindingAdapter( + value = ["staccatoTitle", "staccatoAddress", "staccatoVisitedAt", "staccatoPhotos", "staccatoMemory"], +) +fun Button.setStaccatoSaveButtonEnabled( + staccatoTitle: String?, + staccatoAddress: String?, + staccatoVisitedAt: LocalDateTime?, + staccatoPhotos: AttachedPhotosUiModel?, + staccatoMemory: MemoryCandidate?, +) { + isEnabled = + if (staccatoTitle.isNullOrBlank() || + staccatoAddress == null || + staccatoMemory == null || + staccatoVisitedAt == null || + staccatoPhotos?.isLoading() == true + ) { + setTextColor(resources.getColor(R.color.gray4, null)) + false + } else { + setTextColor(resources.getColor(R.color.white, null)) + true + } +} + +@BindingAdapter( + value = ["memoryTitle", "memoryStartDate", "memoryEndDate", "isPeriodActive", "isPhotoUploading"], +) +fun Button.setMemorySaveButtonEnabled( + memoryTitle: String?, + memoryStartDate: LocalDate?, + memoryEndDate: LocalDate?, + isPeriodActive: Boolean, + isPhotoUploading: Boolean?, +) { + val isPeriodNotExistent = (memoryStartDate == null) || (memoryEndDate == null) + val isPeriodRequirementsInvalid = isPeriodActive && isPeriodNotExistent + isEnabled = + if (memoryTitle.isNullOrBlank() || isPhotoUploading == true || isPeriodRequirementsInvalid) { + setTextColor(resources.getColor(R.color.gray4, null)) + false + } else { + setTextColor(resources.getColor(R.color.white, null)) + true + } +} + +@BindingAdapter("visitedAtSelectButtonEnabled") +fun Button.setVisitedAtSelectButtonEnabled(years: List?) { + isEnabled = + if (years.isNullOrEmpty()) { + setTextColor(resources.getColor(R.color.gray4, null)) + false + } else { + setTextColor(resources.getColor(R.color.white, null)) + true + } +} + +@BindingAdapter("recoveryButtonEnabled") +fun Button.setRecoveryButtonEnabled(recoveryCode: String?) { + isEnabled = + if (recoveryCode.isNullOrBlank() || recoveryCode.length < MAX_RECOVERY_CODE) { + setTextColor(resources.getColor(R.color.gray4, null)) + false + } else { + setTextColor(resources.getColor(R.color.white, null)) + true + } +} + +@BindingAdapter("currentLocationButtonLoading") +fun MaterialButton.setCurrentLocationButtonLoading(isLoading: Boolean?) { + isClickable = isLoading == false + if (isLoading == true) { + setText(R.string.all_empty) + setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + } else { + setText(R.string.visit_creation_load_current_location) + } +} + +@BindingAdapter("sendButtonEnabled") +fun ImageButton.setSendButtonEnabled(value: String?) { + isEnabled = !value.isNullOrBlank() +} + +private const val MAX_RECOVERY_CODE = 36 diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ImageBindingAdapter.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ImageBindingAdapter.kt new file mode 100644 index 00000000..8898a77d --- /dev/null +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/ImageBindingAdapter.kt @@ -0,0 +1,91 @@ +package com.on.staccato.presentation.bindingadapter + +import android.graphics.drawable.Drawable +import android.net.Uri +import android.widget.ImageView +import androidx.databinding.BindingAdapter +import coil.load +import coil.transform.RoundedCornersTransformation + +@BindingAdapter("selected") +fun ImageView.setSelected(selected: Boolean) { + isSelected = selected +} + +@BindingAdapter( + value = ["coilImageUrl", "coilPlaceHolder"], +) +fun ImageView.loadCoilImage( + url: String?, + placeHolder: Drawable? = null, +) { + load(url) { + placeholder(placeHolder) + error(placeHolder) + } +} + +@BindingAdapter( + value = ["coilCircleImageUrl", "coilPlaceHolder"], +) +fun ImageView.loadCoilCircleImage( + url: String?, + placeHolder: Drawable? = null, +) { + load(url) { + placeholder(placeHolder) + transformations(RoundedCornersTransformation(1000f)) + error(placeHolder) + } +} + +@BindingAdapter( + value = ["coilRoundedCornerImageUrl", "coilRoundedCornerPlaceHolder", "coilRoundingRadius"], +) +fun ImageView.setCoilRoundedCornerImage( + url: String?, + placeHolder: Drawable? = null, + roundingRadius: Float, +) { + load(url) { + placeholder(placeHolder) + transformations(RoundedCornersTransformation(roundingRadius)) + error(placeHolder) + } +} + +@BindingAdapter( + value = ["coilRoundedCornerImageUrl", "coilRoundedCornerImageUri", "coilRoundedCornerPlaceHolder", "coilRoundingRadius"], +) +fun ImageView.setCoilRoundedCornerImageWithUri( + url: String?, + uri: Uri?, + placeHolder: Drawable? = null, + roundingRadius: Float, +) { + val image = uri ?: url + load(image) { + placeholder(placeHolder) + transformations(RoundedCornersTransformation(roundingRadius)) + error(placeHolder) + } +} + +@BindingAdapter( + value = [ + "colorImageResource", + "grayImageResource", + ], +) +fun ImageView.setImageResourceWithId( + colorResId: Int, + grayResId: Int, +) { + setImageResource( + if (isSelected) { + colorResId + } else { + grayResId + }, + ) +} diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/TextBindingAdapter.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/TextBindingAdapter.kt new file mode 100644 index 00000000..490328d1 --- /dev/null +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/bindingadapter/TextBindingAdapter.kt @@ -0,0 +1,158 @@ +package com.on.staccato.presentation.bindingadapter + +import android.view.View +import android.widget.TextView +import androidx.core.view.isGone +import androidx.databinding.BindingAdapter +import com.on.staccato.R +import com.on.staccato.domain.model.MemoryCandidate +import com.on.staccato.domain.model.MemoryCandidates +import com.on.staccato.presentation.common.getFormattedLocalDateTime +import java.time.LocalDate +import java.time.LocalDateTime + +@BindingAdapter(value = ["selectedMemory", "memoryCandidates"]) +fun TextView.setSelectedMemory( + selectedMemory: MemoryCandidate?, + memoryCandidates: MemoryCandidates?, +) { + if (memoryCandidates?.memoryCandidate?.isEmpty() == true) { + text = resources.getString(R.string.visit_creation_no_memory_hint) + setTextColor(resources.getColor(R.color.gray3, null)) + isClickable = false + isFocusable = false + } else if (selectedMemory == null) { + text = resources.getString(R.string.visit_creation_memory_selection_hint) + setTextColor(resources.getColor(R.color.gray3, null)) + isClickable = true + isFocusable = true + } else { + text = selectedMemory.memoryTitle + setTextColor(resources.getColor(R.color.staccato_black, null)) + } +} + +@BindingAdapter(value = ["dateTimeWithAmPm", "memoryCandidates"]) +fun TextView.setDateTimeWithAmPm( + dateTime: LocalDateTime?, + memoryCandidates: MemoryCandidates?, +) { + if (memoryCandidates?.memoryCandidate?.isEmpty() == true) { + text = resources.getString(R.string.visit_creation_memory_selection_hint) + setTextColor(resources.getColor(R.color.gray3, null)) + isClickable = false + isFocusable = false + } else { + text = dateTime?.let(::getFormattedLocalDateTime) ?: EMPTY_TEXT + setTextColor(resources.getColor(R.color.staccato_black, null)) + isClickable = true + isFocusable = true + } +} + +@BindingAdapter( + value = ["startDate", "endDate"], +) +fun TextView.setMemoryPeriod( + startDate: LocalDate?, + endDate: LocalDate?, +) { + if (startDate == null || endDate == null) { + text = resources.getString(R.string.memory_creation_period_hint) + setTextColor(resources.getColor(R.color.gray3, null)) + } else { + text = + resources.getString(R.string.memory_creation_selected_period) + .format(startDate, endDate) + setTextColor(resources.getColor(R.color.staccato_black, null)) + } +} + +@BindingAdapter("isMemoryCandidatesEmpty") +fun TextView.setIsMemoryCandidatesEmptyVisibility(memoryCandidates: MemoryCandidates?) { + isGone = !memoryCandidates?.memoryCandidate.isNullOrEmpty() +} + +@BindingAdapter("isMemoryEmpty") +fun TextView.setIsMemoryEmptyVisibility(items: List?) { + isGone = !items.isNullOrEmpty() +} + +@BindingAdapter("visitedAtHistory") +fun TextView.formatVisitedAtHistory(visitedAt: LocalDateTime?) { + text = visitedAt?.let { + resources.getString(R.string.visit_at_history).format(getFormattedLocalDateTime(it)) + } ?: EMPTY_TEXT +} + +@BindingAdapter( + value = ["startAt", "endAt"], +) +fun TextView.formatLocalDateToDatePeriod( + startAt: LocalDate?, + endAt: LocalDate?, +) { + val periodFormatString = resources.getString(R.string.memory_period_dot) + text = + if (startAt != null && endAt != null) { + visibility = View.VISIBLE + periodFormatString.format( + startAt.year, + startAt.monthValue, + startAt.dayOfMonth, + endAt.year, + endAt.monthValue, + endAt.dayOfMonth, + ) + } else { + visibility = View.INVISIBLE + null + } +} + +@BindingAdapter( + value = ["memoryStartAt", "memoryEndAt"], +) +fun TextView.formatLocalDateToDatePeriodInMemory( + startAt: LocalDate?, + endAt: LocalDate?, +) { + val periodFormatString = resources.getString(R.string.memory_period_dot) + text = + if (startAt != null && endAt != null) { + visibility = View.VISIBLE + periodFormatString.format( + startAt.year, + startAt.monthValue, + startAt.dayOfMonth, + endAt.year, + endAt.monthValue, + endAt.dayOfMonth, + ) + } else { + visibility = View.GONE + null + } +} + +@BindingAdapter(value = ["attachedPhotoNumbers", "maxPhotoNumbers"]) +fun TextView.setPhotoNumbers( + attachedPhotoNumbers: Int, + maxPhotoNumbers: Int, +) { + text = + resources.getString(R.string.all_photo_number).format(attachedPhotoNumbers, maxPhotoNumbers) +} + +@BindingAdapter("photoDragHintVisibility") +fun TextView.setPhotoDragHintVisibility(currentPhotoNumbers: Int) { + isGone = currentPhotoNumbers < DRAGGABLE_PHOTO_NUMBER +} + +@BindingAdapter("selectedAddress") +fun TextView.setSelectedAddress(address: String?) { + text = address ?: context.getString(R.string.visit_creation_empty_address) +} + +private const val DRAGGABLE_PHOTO_NUMBER = 2 +private const val EMPTY_TEXT = "" diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/LocalDateFormatter.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/LocalDateFormatter.kt new file mode 100644 index 00000000..e5dd550d --- /dev/null +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/LocalDateFormatter.kt @@ -0,0 +1,35 @@ +package com.on.staccato.presentation.common + +import android.view.View +import com.on.staccato.R +import java.time.LocalDate +import java.time.LocalDateTime + +fun View.getFormattedLocalDate(setNowDate: LocalDate): String = + setNowDate.let { + val year = setNowDate.year + val month = setNowDate.monthValue + val day = setNowDate.dayOfMonth + resources.getString(R.string.all_date_kr_format) + .format(year, month, day) + } + +fun View.getFormattedLocalDateTime(setNowDateTime: LocalDateTime): String = + setNowDateTime.let { + val year = setNowDateTime.year + val month = setNowDateTime.monthValue + val day = setNowDateTime.dayOfMonth + val hour = if (setNowDateTime.hour % HALF_DAY_HOUR == 0) HALF_DAY_HOUR else setNowDateTime.hour % HALF_DAY_HOUR + val noonText = + if (setNowDateTime.hour < HALF_DAY_HOUR) { + resources.getString(R.string.all_am) + } else { + resources.getString( + R.string.all_pm, + ) + } + resources.getString(R.string.all_date_time_am_pm_kr_format) + .format(year, month, day, noonText, hour) + } + +private const val HALF_DAY_HOUR = 12 diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/memoryupdate/MemoryUpdateActivity.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/memoryupdate/MemoryUpdateActivity.kt index acfded7d..d5c5901b 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/memoryupdate/MemoryUpdateActivity.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/memoryupdate/MemoryUpdateActivity.kt @@ -43,7 +43,9 @@ class MemoryUpdateActivity : } override fun onPeriodSelectionClicked() { - dateRangePicker.show(supportFragmentManager, dateRangePicker.toString()) + if (dateRangePicker.isAdded) { + dateRangePicker.show(supportFragmentManager, dateRangePicker.toString()) + } } override fun onSaveClicked() { diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/moment/feeling/FeelingUiModel.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/moment/feeling/FeelingUiModel.kt index a4857f80..40306092 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/moment/feeling/FeelingUiModel.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/moment/feeling/FeelingUiModel.kt @@ -1,8 +1,10 @@ package com.on.staccato.presentation.moment.feeling +import androidx.annotation.ColorRes + data class FeelingUiModel( val feeling: String, - val colorSrc: Int?, - val graySrc: Int?, + @ColorRes val colorSrc: Int?, + @ColorRes val graySrc: Int?, val isSelected: Boolean = false, ) diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/momentcreation/dialog/VisitedAtSelectionFragment.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/momentcreation/dialog/VisitedAtSelectionFragment.kt index 61cef45f..e5981a2c 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/momentcreation/dialog/VisitedAtSelectionFragment.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/momentcreation/dialog/VisitedAtSelectionFragment.kt @@ -66,7 +66,7 @@ class VisitedAtSelectionFragment : BottomSheetDialogFragment() { view: View, savedInstanceState: Bundle?, ) { - binding.items = years + binding.years = years setupPickers() setupPickerListeners() initConfirmButton() diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_login.xml b/android/Staccato_AN/app/src/main/res/layout/activity_login.xml index 7d1aefbd..33b35af4 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_login.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_login.xml @@ -75,7 +75,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/text_input_login_user_nickname" - bind:loginEnabled="@{viewModel.nickname}" /> + bind:loginButtonEnabled="@{viewModel.nickname}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_memory_creation.xml b/android/Staccato_AN/app/src/main/res/layout/activity_memory_creation.xml index 3f15ac78..edb9b548 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_memory_creation.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_memory_creation.xml @@ -57,9 +57,9 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - bind:coilImageUri="@{viewModel.thumbnailUri}" - bind:coilImageUrl="@{viewModel.thumbnailUrl}" - bind:coilPlaceHolder="@{@drawable/shape_all_gray1_8dp}" + bind:coilRoundedCornerImageUri="@{viewModel.thumbnailUri}" + bind:coilRoundedCornerImageUrl="@{viewModel.thumbnailUrl}" + bind:coilRoundedCornerPlaceHolder="@{@drawable/shape_all_gray1_8dp}" bind:coilRoundingRadius="@{12f}" /> + bind:visibilityByThumbnailUri="@{viewModel.thumbnailUri}" + bind:visibilityByThumbnailUrl="@{viewModel.thumbnailUrl}" /> + bind:startDate="@{viewModel.startDate}" + bind:visibleOrGone="@{viewModel.isPeriodActive}" /> + bind:isPhotoUploading="@{viewModel.isPhotoPosting}" + bind:memoryEndDate="@{viewModel.endDate}" + bind:memoryStartDate="@{viewModel.startDate}" + bind:memoryTitle="@{viewModel.title}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_memory_update.xml b/android/Staccato_AN/app/src/main/res/layout/activity_memory_update.xml index 2e79d352..8f20efed 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_memory_update.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_memory_update.xml @@ -57,10 +57,10 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - bind:coilImageUri="@{viewModel.thumbnailUri}" - bind:coilImageUrl="@{viewModel.thumbnailUrl}" - bind:coilPlaceHolder="@{@drawable/shape_all_gray1_8dp}" - bind:coilRoundingRadius="@{12}" /> + bind:coilRoundedCornerImageUri="@{viewModel.thumbnailUri}" + bind:coilRoundedCornerImageUrl="@{viewModel.thumbnailUrl}" + bind:coilRoundedCornerPlaceHolder="@{@drawable/shape_all_gray1_8dp}" + bind:coilRoundingRadius="@{12f}" /> + bind:startDate="@{viewModel.startDate}" + bind:visibleOrGone="@{viewModel.isPeriodActive}" /> + bind:isPhotoUploading="@{viewModel.isPhotoPosting}" + bind:memoryEndDate="@{viewModel.endDate}" + bind:memoryStartDate="@{viewModel.startDate}" + bind:memoryTitle="@{viewModel.title}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_recovery.xml b/android/Staccato_AN/app/src/main/res/layout/activity_recovery.xml index 1bd38175..5eec4c4c 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_recovery.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_recovery.xml @@ -79,7 +79,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - bind:recoveryEnabled="@{viewModel.recoveryCode}" /> + bind:recoveryButtonEnabled="@{viewModel.recoveryCode}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_visit_creation.xml b/android/Staccato_AN/app/src/main/res/layout/activity_visit_creation.xml index fdf76298..5349fcc6 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_visit_creation.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_visit_creation.xml @@ -39,9 +39,9 @@ app:title="@string/visit_creation_toolbar_title" /> @@ -68,7 +68,7 @@ app:layout_constraintBottom_toBottomOf="@id/tv_photo_title" app:layout_constraintStart_toEndOf="@id/tv_photo_title" app:layout_constraintTop_toTopOf="@id/tv_photo_title" - bind:currentPhotoNumbers="@{viewModel.currentPhotos.size}" + bind:attachedPhotoNumbers="@{viewModel.currentPhotos.size}" bind:maxPhotoNumbers="@{5}" tools:text="5/5" /> @@ -187,7 +187,7 @@ app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_place_address_title" - bind:setAddress="@{viewModel.address}" + bind:selectedAddress="@{viewModel.address}" tools:text="상세 주소 (고정)" /> + bind:currentLocationButtonLoading="@{viewModel.isCurrentLocationLoading}" /> + bind:visibleOrGone="@{viewModel.isCurrentLocationLoading}" /> @@ -255,8 +255,8 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_memory_selection_title" - bind:setMemoryCandidates="@{viewModel.memoryCandidates}" - bind:setSelectedMemory="@{viewModel.selectedMemory}" /> + bind:memoryCandidates="@{viewModel.memoryCandidates}" + bind:selectedMemory="@{viewModel.selectedMemory}" /> + bind:dateTimeWithAmPm="@{viewModel.selectedVisitedAt}" + bind:memoryCandidates="@{viewModel.memoryCandidates}" /> + bind:staccatoVisitedAt="@{viewModel.selectedVisitedAt}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/activity_visit_update.xml b/android/Staccato_AN/app/src/main/res/layout/activity_visit_update.xml index 1ca8fb19..5192eff6 100644 --- a/android/Staccato_AN/app/src/main/res/layout/activity_visit_update.xml +++ b/android/Staccato_AN/app/src/main/res/layout/activity_visit_update.xml @@ -68,7 +68,7 @@ app:layout_constraintBottom_toBottomOf="@id/tv_photo_title" app:layout_constraintStart_toEndOf="@id/tv_photo_title" app:layout_constraintTop_toTopOf="@id/tv_photo_title" - bind:currentPhotoNumbers="@{viewModel.currentPhotos.size}" + bind:attachedPhotoNumbers="@{viewModel.currentPhotos.size}" bind:maxPhotoNumbers="@{5}" tools:text="5/5" /> @@ -96,6 +96,7 @@ android:text="@string/visit_creation_photo_drag_hint" android:textAppearance="@style/Typography.Body4" android:textColor="@color/gray3" + android:visibility="@{viewModel.currentPhotos.size < 2 ? View.GONE : View.VISIBLE}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/rv_photo_attach" bind:photoDragHintVisibility="@{viewModel.currentPhotos.size}" /> @@ -187,7 +188,7 @@ app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_place_address_title" - bind:setAddress="@{viewModel.address}" + bind:selectedAddress="@{viewModel.address}" tools:text="상세 주소 (고정)" /> + bind:currentLocationButtonLoading="@{viewModel.isCurrentLocationLoading}" /> + bind:visibleOrGone="@{viewModel.isCurrentLocationLoading}" /> /> @@ -288,8 +289,8 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tv_select_memory_title" - bind:setDateTimeWithAmPm="@{viewModel.selectedVisitedAt}" - bind:setMemoryCandidates="@{viewModel.memoryCandidates}" /> + bind:dateTimeWithAmPm="@{viewModel.selectedVisitedAt}" + bind:memoryCandidates="@{viewModel.memoryCandidates}" /> + bind:staccatoVisitedAt="@{viewModel.selectedVisitedAt}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/fragment_memory_visited_at_selection.xml b/android/Staccato_AN/app/src/main/res/layout/fragment_memory_visited_at_selection.xml index c55eeb69..19286a3f 100644 --- a/android/Staccato_AN/app/src/main/res/layout/fragment_memory_visited_at_selection.xml +++ b/android/Staccato_AN/app/src/main/res/layout/fragment_memory_visited_at_selection.xml @@ -28,7 +28,7 @@ app:layout_constraintTop_toTopOf="parent" /> + bind:isMemoryCandidatesEmpty="@{memoryCandidates}" /> + bind:visitedAtHistory="@{viewModel.momentDetail.visitedAt}" + tools:text="2024년 7월 15일 2시에 방문했어요" /> @@ -100,20 +101,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + bind:sendButtonEnabled="@{viewModel.commentInput}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/fragment_visited_at_selection.xml b/android/Staccato_AN/app/src/main/res/layout/fragment_visited_at_selection.xml index b507cc1f..755a455d 100644 --- a/android/Staccato_AN/app/src/main/res/layout/fragment_visited_at_selection.xml +++ b/android/Staccato_AN/app/src/main/res/layout/fragment_visited_at_selection.xml @@ -6,7 +6,7 @@ @@ -24,7 +24,7 @@ app:layout_constraintTop_toTopOf="parent" /> + bind:isMemoryEmpty="@{years}" /> + bind:visitedAtSelectButtonEnabled="@{years}" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/item_attached_photo.xml b/android/Staccato_AN/app/src/main/res/layout/item_attached_photo.xml index a8cf4bdd..c64f6bc2 100644 --- a/android/Staccato_AN/app/src/main/res/layout/item_attached_photo.xml +++ b/android/Staccato_AN/app/src/main/res/layout/item_attached_photo.xml @@ -31,9 +31,9 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="1:1" app:layout_constraintStart_toStartOf="parent" - bind:coilImageUri="@{attachedPhoto.uri}" - bind:coilImageUrl="@{attachedPhoto.imageUrl}" - bind:coilPlaceHolder="@{@drawable/shape_all_gray2_4dp}" + bind:coilRoundedCornerImageUri="@{attachedPhoto.uri}" + bind:coilRoundedCornerImageUrl="@{attachedPhoto.imageUrl}" + bind:coilRoundedCornerPlaceHolder="@{@drawable/shape_all_gray2_4dp}" bind:coilRoundingRadius="@{12f}" tools:src="@drawable/shape_all_gray2_4dp" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/item_moment_feeling_selection.xml b/android/Staccato_AN/app/src/main/res/layout/item_moment_feeling_selection.xml index 7ac49057..650d694b 100644 --- a/android/Staccato_AN/app/src/main/res/layout/item_moment_feeling_selection.xml +++ b/android/Staccato_AN/app/src/main/res/layout/item_moment_feeling_selection.xml @@ -20,7 +20,7 @@ android:onClick="@{() -> feelingHandler.onFeelingClicked(feeling)}" bind:colorImageResource="@{feeling.colorSrc}" bind:grayImageResource="@{feeling.graySrc}" - bind:setSelected="@{feeling.isSelected}" + bind:selected="@{feeling.isSelected}" tools:src="@drawable/feeling_excited" /> diff --git a/android/Staccato_AN/app/src/main/res/layout/item_visits.xml b/android/Staccato_AN/app/src/main/res/layout/item_visits.xml index af8d4adc..2c7badbb 100644 --- a/android/Staccato_AN/app/src/main/res/layout/item_visits.xml +++ b/android/Staccato_AN/app/src/main/res/layout/item_visits.xml @@ -33,9 +33,9 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - bind:coilPlaceHolder="@{@drawable/staccato_gradient}" + bind:coilRoundedCornerPlaceHolder="@{@drawable/staccato_gradient}" bind:coilRoundedCornerImageUrl="@{visit.visitImageUrl}" - bind:coilRoundingRadius="@{16}" + bind:coilRoundingRadius="@{16f}" tools:src="@drawable/shape_all_gray2_4dp" /> diff --git a/android/Staccato_AN/app/src/main/res/values/strings.xml b/android/Staccato_AN/app/src/main/res/values/strings.xml index dbcfbd36..53f4d2cd 100644 --- a/android/Staccato_AN/app/src/main/res/values/strings.xml +++ b/android/Staccato_AN/app/src/main/res/values/strings.xml @@ -23,6 +23,8 @@ * 사진을 게시하는 중이에요 설정 + 오전 + 오후 위치 권한을 거부 하셨습니다. 웹 브라우저를 띄울 수 없습니다. 클립보드에 복사했어요! @@ -66,7 +68,7 @@ 스타카토를 담을 추억을 수정해 보세요! // fragment_visit - %s년 %s월 %s일 %s %s시에 방문 했어요 + %s에 방문했어요 코멘트 기록하기 코멘트 입력하기