Skip to content

Commit

Permalink
Merge branch 'develop' into feat-plan-location
Browse files Browse the repository at this point in the history
# Conflicts:
#	app/src/main/java/org/sopt/pingle/presentation/ui/main/plan/PlanViewModel.kt
#	app/src/main/res/values/strings.xml
  • Loading branch information
HAJIEUN02 committed Jan 7, 2024
2 parents 5e3b28c + a073dd1 commit a8005a7
Show file tree
Hide file tree
Showing 24 changed files with 786 additions and 58 deletions.
63 changes: 61 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,61 @@
# PINGLE-ANDROID
눈물이 핑~
# 🌀 PINGLE-ANDROID 🌀

## ➰ *****PINGLE*****
Ready to PINGLE? <br>
가볍고 재미있는 모임 문화, 핑글과 함께 만들어요!

<br>

## 👋 *****Contributors*****
| 배지현 <br> [@jihyunniiii](https://github.com/jihyunniiii) | 김민우 <br> [@DoReMinWoo](https://github.com/DoReMinWoo) | 하지은 <br>[@HAJIEUN02](https://github.com/HAJIEUN02) | 이다은 <br>[@Dan2dani](https://github.com/Dan2dani) |
|:---:| :---: | :---: | :---: |
| <img width="250" src="https://avatars.githubusercontent.com/u/103172971?v=4"/> |<img width="250" src="https://avatars.githubusercontent.com/u/86788873?v=4"/>|<img width="250" src="https://avatars.githubusercontent.com/u/83916472?v=4"/>|<img width="250" src="https://avatars.githubusercontent.com/u/77060011?v=4"/>|
| `메인 지도뷰` |`온보딩/회원가입`|`핑글 개최 프로세스`|`핑글 개최 프로세스`, `설정`|

<br>

## 📁 *****Foldering*****
```
📂 org.sopt.pingle
┣ 📂 data
┃ ┣ 📂 datasource
┃ ┣ 📂 datasourceimpl
┃ ┣ 📂 interceptor
┃ ┣ 📂 model
┃ ┣ 📂 repository
┃ ┣ 📂 service
┣ 📂 di
┣ 📂 domain
┃ ┣ 📂 model
┃ ┣ 📂 repository
┃ ┣ 📂 usecase
┣ 📂 presentation
┃ ┣ 📂 mapper
┃ ┣ 📂 mode
┃ ┣ 📂 type
┃ ┣ 📂 ui
┣ 📂 util
┃ ┣ 📂 base
┃ ┣ 📂 component
┃ ┣ 📂 context
┃ ┣ 📂 fragment
┃ ┣ 📂 intent
┃ ┣ 📂 view
```

## *****Convention*****

[안핑이들의 깃 컨벤션과 브랜치 전략이 궁금하다면? click ✔️](https://pinglepingle.notion.site/Git-Convention-Branch-Strategy-a6510c29e8594a2581314aa0a2cbbe8f?pvs=4)
<br>

[안핑이들의 코드 컨벤션이 궁금하다면? click ✔️](https://pinglepingle.notion.site/Android-Coding-Convention-ca4ed7540eb84ab49535af4b481027b3?pvs=4)
<br>

[안핑이들의 ISSUE, PR 컨벤션이 궁금하다면? click ✔️](https://pinglepingle.notion.site/Issue-PR-Convention-eae2f1dd2e014a54b62d070b32665976?pvs=4)
<br>

[안핑이들의 칸반보드가 궁금하다면? click ✔️](https://pinglepingle.notion.site/Kanban-Board-e14724c84cc444ffb73a3d78c18b3f24?pvs=4)
<br>

[안핑이들의 Github Project가 궁금하다면? click ✔️](https://github.com/orgs/TeamPINGLE/projects/4)
<br>
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<activity
android:name=".presentation.ui.main.plan.PlanActivity"
android:exported="false"
android:windowSoftInputMode="adjustNothing"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.pingle.presentation.type

import androidx.annotation.StringRes
import org.sopt.pingle.R

enum class MeridiemType(
@StringRes val meridiemStringRes: Int
) {
AM(R.string.plan_time_am), PM(R.string.plan_time_pm)
}
13 changes: 13 additions & 0 deletions app/src/main/java/org/sopt/pingle/presentation/type/PlanType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.pingle.presentation.type

enum class PlanType(
val position: Int
) {
CATEGORY(0),
TITLE(1),
DATETIME(2),
LOCATION(3),
RECRUITMENT(4),
OPENCHATTING(5),
SUMMARY(6)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class PlanActivity : BindingActivity<ActivityPlanBinding>(R.layout.activity_plan
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding.viewModel = planViewModel
setPlanFragmentStateAdapter()
addListeners()
collectData()
Expand Down Expand Up @@ -79,7 +80,6 @@ class PlanActivity : BindingActivity<ActivityPlanBinding>(R.layout.activity_plan
fragmentList.size - 1 -> {
binding.btnPlan.text = getString(R.string.plan_pingle)
}

// TODO 다른 다음으로 스트링과 합치기
else -> {
binding.btnPlan.text = getString(R.string.plan_next)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.sopt.pingle.presentation.ui.main.plan

import android.os.Bundle
import android.view.View
import android.widget.NumberPicker
import org.sopt.pingle.R
import org.sopt.pingle.databinding.DialogDatePickerBinding
import org.sopt.pingle.util.base.BindingBottomSheetDialogFragment

class PlanDateDialogFragment(
private val onDialogClosed: (year: Int, month: Int, day: Int) -> Unit
) :
BindingBottomSheetDialogFragment<DialogDatePickerBinding>(R.layout.dialog_date_picker) {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isCancelable = false
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initLayout()
addListeners()
}

private fun initLayout() {
val yearPicker = binding.npDatePickerYear
yearPicker.apply {
wrapSelectorWheel = false // 순한 안되게 막기
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS // editText 설정 해제
minValue = YEAR_MIN
maxValue = YEAR_MAX
}

val hoursPicker = binding.npDatePickerMonth
hoursPicker.apply {
wrapSelectorWheel = false
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
minValue = MONTH_MIN
maxValue = MONTH_MAX
}
val dayPicker = binding.npDatePickerDay
dayPicker.apply {
wrapSelectorWheel = false
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
minValue = DAY_MIN
maxValue = DAY_MAX
}
}

private fun addListeners() {
binding.tvDatePickerDone.setOnClickListener {
onDialogClosed(
binding.npDatePickerYear.value,
binding.npDatePickerMonth.value,
binding.npDatePickerDay.value
)
dismiss()
}
}

companion object {
const val YEAR_MIN = 2024
const val YEAR_MAX = 2050
const val MONTH_MIN = 1
const val MONTH_MAX = 12
const val DAY_MIN = 1
const val DAY_MAX = 31
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,89 @@ package org.sopt.pingle.presentation.ui.main.plan

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import java.text.SimpleDateFormat
import java.time.LocalDate
import org.sopt.pingle.R
import org.sopt.pingle.databinding.FragmentPlanDateTimeBinding
import org.sopt.pingle.util.base.BindingFragment
import timber.log.Timber

class PlanDateTimeFragment : BindingFragment<FragmentPlanDateTimeBinding>(R.layout.fragment_plan_date_time) {
class PlanDateTimeFragment :
BindingFragment<FragmentPlanDateTimeBinding>(R.layout.fragment_plan_date_time) {
private val planViewModel: PlanViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

addListeners()
}

private fun addListeners() {
binding.includePlanTextWithTitleDate.root.setOnClickListener {
val dialogDateFragment = PlanDateDialogFragment(::onDateDialogFragmentClosed)
dialogDateFragment.show(
parentFragmentManager,
dialogDateFragment.tag
)
}

binding.includePlanTextWithTitleStartTime.root.setOnClickListener {
val dialogStartTimeFragment = PlanTimeDialogFragment(::onTimeDialogFragmentClosed)
dialogStartTimeFragment.show(
parentFragmentManager,
dialogStartTimeFragment.tag
)
planViewModel.setSelectedTimeType(START_TIME)
}

binding.includePlanTextWithTitleEndTime.root.setOnClickListener {
val dialogEndTimeFragment = PlanTimeDialogFragment(::onTimeDialogFragmentClosed)
dialogEndTimeFragment.show(
parentFragmentManager,
dialogEndTimeFragment.tag
)
planViewModel.setSelectedTimeType(END_TIME)
}
}

// TODO format 관련 refactor
private fun onDateDialogFragmentClosed(year: Int, month: Int, day: Int) {
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val todayLocalDate = dateFormat.parse(LocalDate.now().toString())
val selectedFormatDate = String.format("%d-%02d-%02d", year, month, day)
val selectedLocalDate = dateFormat.parse(selectedFormatDate)

if (selectedLocalDate != null) {
if (selectedLocalDate.before(todayLocalDate)) {
// TODO 에러 스낵바 노출
} else {
binding.includePlanTextWithTitleDate.tvText.text = String.format(
"%d년 %d월 %d일",
year,
month,
day
)
planViewModel.setPlanDate(selectedFormatDate)
}
}
}

// TODO 시간 포맷 나오면 수정 예정
// TODO {} 수정 예정
private fun onTimeDialogFragmentClosed(time: String) {
when (planViewModel.selectedTimeType.value) {
START_TIME -> {
Timber.d(START_TIME)
}

END_TIME -> {
Timber.d(END_TIME)
}
}
}

companion object {
const val START_TIME = "startTime"
const val END_TIME = "endTime"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@ package org.sopt.pingle.presentation.ui.main.plan

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import org.sopt.pingle.R
import org.sopt.pingle.databinding.FragmentPlanOpenChattingBinding
import org.sopt.pingle.util.base.BindingFragment
import org.sopt.pingle.util.context.hideKeyboard

class PlanOpenChattingFragment : BindingFragment<FragmentPlanOpenChattingBinding>(R.layout.fragment_plan_open_chatting) {
class PlanOpenChattingFragment :
BindingFragment<FragmentPlanOpenChattingBinding>(R.layout.fragment_plan_open_chatting) {
private val planViewModel: PlanViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.viewModel = planViewModel

addListeners()
}

private fun addListeners() {
binding.root.setOnClickListener {
requireActivity().hideKeyboard(it)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.sopt.pingle.presentation.ui.main.plan

import android.os.Bundle
import android.view.View
import android.widget.NumberPicker
import org.sopt.pingle.R
import org.sopt.pingle.databinding.DialogTimePickerBinding
import org.sopt.pingle.presentation.type.MeridiemType
import org.sopt.pingle.util.base.BindingBottomSheetDialogFragment

class PlanTimeDialogFragment(
private val onDialogClosed: (String) -> Unit
) :
BindingBottomSheetDialogFragment<DialogTimePickerBinding>(R.layout.dialog_time_picker) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isCancelable = false
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initLayout()
addListeners()
}

private fun initLayout() {
val meridiemPicker = binding.npTimePickerMeridiem
meridiemPicker.apply {
wrapSelectorWheel = false // 순한 안되게 막기
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS // editText 설정 해제
minValue = 0
maxValue = 1
displayedValues =
arrayOf(
getString(MeridiemType.AM.meridiemStringRes),
getString(MeridiemType.PM.meridiemStringRes)
)
}

val hoursPicker = binding.npTimePickerHour
hoursPicker.apply {
wrapSelectorWheel = false // 순한 안되게 막기
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS // editText 설정 해제
minValue = HOUR_MIN
maxValue = HOUR_MAX
}
val minutesPicker = binding.npTimePickerMinute
minutesPicker.apply {
wrapSelectorWheel = false // 순한 안되게 막기
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS // editText 설정 해제
minValue = MINUTE_MIN
maxValue = MINUTE_MAX
setFormatter { value -> String.format("%02d", value) }
}
}

private fun addListeners() {
binding.tvTimePickerDone.setOnClickListener {
onDialogClosed("aaa")
// 시간 설정 후 editText에 띄우기
// with(binding) {
// val timeFormat =
// String.format("%02d:%02d:00", npTimePickerHour.value, npTimePickerMinute.value)
// onDialogClosed(timeFormat)
// Log.d(
// "aaa",
// String.format("%02d:%02d:00", npTimePickerHour.value, npTimePickerMinute.value)
// )
// }
dismiss()
}
}

companion object {
const val HOUR_MIN = 1
const val HOUR_MAX = 12
const val MINUTE_MIN = 0
const val MINUTE_MAX = 59
}
}
Loading

0 comments on commit a8005a7

Please sign in to comment.