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

[둘리] 3, 4 단계 영화 티켓 예매 제출합니다. #47

Merged
merged 47 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
afc8cca
test: PriceCalculatorTest 생성
hyemdooly Apr 18, 2023
4ca2988
test: TicketTest 수정
hyemdooly Apr 18, 2023
aaace58
refactor: fold를 사용하여 코드 단축
hyemdooly Apr 18, 2023
067af6b
refactor: PlayingDateTimes로 클래스명과 코드 수정
hyemdooly Apr 18, 2023
f5c4730
refactor: package 이동으로 인한 수정
hyemdooly Apr 18, 2023
eeaeb22
refactor: 필요없는 주석 삭제
hyemdooly Apr 18, 2023
d8f91d8
refactor: TicketResultActivity View 세팅 코드 분리
hyemdooly Apr 18, 2023
417aca7
feat: SeatSelectActivity xml 작성
hyemdooly Apr 20, 2023
d9672f2
refactor: DateSpinnerListener 삭제, findViewById 한번만 하도록 수정
hyemdooly Apr 20, 2023
e174e3d
refactor: MovieListItemListener 분리
hyemdooly Apr 20, 2023
debeaca
fix: onItemClickListener -> SelectedListener 수정
hyemdooly Apr 20, 2023
76c0a90
feat: SeatView 구현
hyemdooly Apr 20, 2023
3738630
refactor: Ticket Model 구조 변경
hyemdooly Apr 20, 2023
e892f4b
feat: 좌석 선택 페이지로 넘어가도록 수정
hyemdooly Apr 20, 2023
2c8cc14
feat: 좌석 Grade 클래스 추가
hyemdooly Apr 20, 2023
21c892b
feat: TheaterInfo 생성
hyemdooly Apr 21, 2023
61f7022
feat: SeatSelectSystem 생성
hyemdooly Apr 21, 2023
09e0766
feat: SelectResult Success sead class 생성
hyemdooly Apr 21, 2023
cf52062
refactor: PriceCalculator 리팩토링
hyemdooly Apr 21, 2023
8291de2
feat: PriceSystem 생성
hyemdooly Apr 21, 2023
f4d6e7c
refactor: JUnit4 버전 수정
hyemdooly Apr 21, 2023
cd9c49e
feat: Seat 클래스 생성, seats custom getter 생성
hyemdooly Apr 21, 2023
e351227
refactor: 패키지명 수정
hyemdooly Apr 21, 2023
7ff59f2
feat: 좌석 선택 액티비티 구현
hyemdooly Apr 21, 2023
55df55c
feat: Listener 수정, 자리 선택 액티비티 구현 완료
hyemdooly Apr 21, 2023
025733a
refactor: Ticket 액티비티에서 자리 순서대로 출력하도록 수정
hyemdooly Apr 21, 2023
61c6a5f
refactor: count max값 추가
hyemdooly Apr 21, 2023
29d7245
refactor: PriceModel 구현 및 수정
hyemdooly Apr 22, 2023
a410609
feat: Dialog 구현
hyemdooly Apr 22, 2023
1e294bc
feat: Dialog NegativeButton Listener 추가
hyemdooly Apr 22, 2023
371ec72
refactor: UI 변경 사항 수정
hyemdooly Apr 22, 2023
9c41ac5
test: MovieDetailActivity, SeatSelectActivity UI Test 추가
hyemdooly Apr 22, 2023
21c60b1
test: TicketResultActivity UI Test 추가
hyemdooly Apr 22, 2023
04b076e
feat: ListView -> RecyclerView로 변경
hyemdooly Apr 22, 2023
74fbd10
feat: RecyclerView Ad View 추가
hyemdooly Apr 22, 2023
cc1abcc
refactor: ViewHolder property private 수정
hyemdooly Apr 22, 2023
3b89b78
test: MovieListActivityTest 추가
hyemdooly Apr 22, 2023
ea36840
docs: Update README.md
hyemdooly Apr 22, 2023
aa5050c
refactor: MovieDetailActivityTest 수정
hyemdooly Apr 24, 2023
8a3b1df
refactor: MovieDetailActivityTest 수정
hyemdooly Apr 24, 2023
55c309b
refactor: Listener interface 삭제
hyemdooly Apr 24, 2023
27c24b4
refactor: layoutManager xml에서 지정, View에서 Bundle이 아닌 Data 주입
hyemdooly Apr 24, 2023
03d294e
refactor: ReserveInfoModel 추가 및 수정
hyemdooly Apr 24, 2023
bb03b6a
refactor: sealed class view holder, view type enum class 생성, item들 xm…
hyemdooly Apr 24, 2023
0522cc9
Merge remote-tracking branch 'origin/step4' into step4
hyemdooly Apr 24, 2023
8f35ee7
refactor: 코드 변경에 따른 테스트 수정, 패키지 변경
hyemdooly Apr 24, 2023
9f09fcd
refactor: Log 삭제
hyemdooly Apr 24, 2023
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
Prev Previous commit
Next Next commit
feat: 좌석 선택 액티비티 구현
  • Loading branch information
hyemdooly committed Apr 21, 2023
commit 7ff59f267fe89721394b0be620be2bf395099de1
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ class MovieDetailView(private val viewGroup: ViewGroup) {
private fun setPlayingDate(startDate: LocalDate, endDate: LocalDate) {
playingDateView.text = viewGroup.context.getString(
R.string.playing_date_range,
DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format)).format(startDate),
DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format)).format(endDate)
DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format))
.format(startDate),
DateTimeFormatter.ofPattern(viewGroup.context.getString(R.string.date_format))
.format(endDate),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import woowacourse.movie.model.MovieModel
import woowacourse.movie.util.getKeyFromIndex
import woowacourse.movie.util.getOrEmptyList
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime

class ReservationInfoView(private val viewGroup: ViewGroup) {
Expand All @@ -40,7 +41,7 @@ class ReservationInfoView(private val viewGroup: ViewGroup) {
setDateSpinner(savedDate, movie.playingDateTimes)
setTimeSpinner(
savedTime,
movie.playingDateTimes.getOrEmptyList(movie.playingDateTimes.getKeyFromIndex(savedDate))
movie.playingDateTimes.getOrEmptyList(movie.playingDateTimes.getKeyFromIndex(savedDate)),
)
}

Expand All @@ -51,8 +52,7 @@ class ReservationInfoView(private val viewGroup: ViewGroup) {
val time = viewGroup.findViewById<Spinner>(R.id.spinner_time).selectedItem as LocalTime
val count = viewGroup.findViewById<TextView>(R.id.text_count).text.toString().toInt()
intent.putExtra(SeatSelectActivity.TITLE_KEY, title)
intent.putExtra(SeatSelectActivity.DATE_KEY, date)
intent.putExtra(SeatSelectActivity.TIME_KEY, time)
intent.putExtra(SeatSelectActivity.DATETIME_KEY, LocalDateTime.of(date, time))
intent.putExtra(SeatSelectActivity.COUNT_KEY, count)
it.context.startActivity(intent)
}
Expand All @@ -65,7 +65,7 @@ class ReservationInfoView(private val viewGroup: ViewGroup) {

private fun setDateSpinner(
savedDatePosition: Int,
playingTimes: Map<LocalDate, List<LocalTime>>
playingTimes: Map<LocalDate, List<LocalTime>>,
) {
dateSpinner.adapter = SpinnerAdapter(playingTimes.keys.toList())
dateSpinner.setSelection(savedDatePosition, false)
Expand All @@ -74,10 +74,11 @@ class ReservationInfoView(private val viewGroup: ViewGroup) {
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
id: Long,
) {
val times = playingTimes.getOrEmptyList(playingTimes.getKeyFromIndex(position))
timeSpinner.adapter = ArrayAdapter(viewGroup.context, android.R.layout.simple_spinner_item, times)
timeSpinner.adapter =
ArrayAdapter(viewGroup.context, android.R.layout.simple_spinner_item, times)
}

override fun onNothingSelected(parent: AdapterView<*>?) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,54 @@
package woowacourse.movie.activity.seatselect

import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import woowacourse.movie.R
import woowacourse.movie.activity.ticketresult.TicketResultActivity
import woowacourse.movie.domain.price.PriceCalculator
import woowacourse.movie.domain.system.PriceSystem
import woowacourse.movie.domain.system.SeatSelectSystem
import woowacourse.movie.model.toPresentation
import woowacourse.movie.util.Theater
import woowacourse.movie.util.getSerializableExtraCompat
import java.time.LocalDateTime

class SeatSelectActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_seat_select)
val seatView = SeatView(findViewById(R.id.layout_seat_area))
seatView.set()

val title = intent.getStringExtra(TITLE_KEY)
val dateTime = intent.getSerializableExtraCompat<LocalDateTime>(DATETIME_KEY)
val count = intent.getIntExtra(COUNT_KEY, -1)

if (isDataNull(title, dateTime, count)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전달 받는 객체를 한 개로 묶어서 전달 받으면 isDataNull 같은 함수를 만들지 않아도 되겠네요 :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

객체를 생성해서 함수를 삭제했습니다!

Toast.makeText(this, DATA_LOADING_ERROR_MESSAGE, Toast.LENGTH_LONG).show()
finish()
return
}

val seatSelectSystem = SeatSelectSystem(Theater.info, count)
val priceSystem = PriceSystem(PriceCalculator(Theater.policies), dateTime!!)
val seatView =
SeatSelectView(findViewById(R.id.layout_select_seat), seatSelectSystem, priceSystem) {
val intent = Intent(this, TicketResultActivity::class.java)
intent.putExtra(TicketResultActivity.INFO_KEY, it.toPresentation())
startActivity(intent)
}

seatView.set(title!!)
}

private fun isDataNull(title: String?, dateTime: LocalDateTime?, count: Int): Boolean {
return title == null || dateTime == null || count == -1
}

companion object {
private const val DATA_LOADING_ERROR_MESSAGE = "데이터가 로딩되지 않았습니다. 다시 시도해주세요."
const val TITLE_KEY = "TITLE"
const val DATETIME_KEY = "DATETIME"
const val COUNT_KEY = "COUNT"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package woowacourse.movie.activity.seatselect

import android.util.Log
import android.view.ViewGroup
import android.widget.Button
import android.widget.TableLayout
import android.widget.TableRow
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.children
import woowacourse.movie.R
import woowacourse.movie.domain.price.Price
import woowacourse.movie.domain.system.PriceSystem
import woowacourse.movie.domain.system.SeatSelectSystem
import woowacourse.movie.domain.system.SelectResult
import woowacourse.movie.domain.ticket.Ticket
import woowacourse.movie.model.toPresentation
import woowacourse.movie.util.Theater
import java.text.DecimalFormat

class SeatSelectView(
private val viewGroup: ViewGroup,
private val seatSystem: SeatSelectSystem,
private val priceSystem: PriceSystem,
private val nextListener: (Ticket) -> Unit,
) {
private val seatViews: List<TextView> = viewGroup.findViewById<TableLayout>(R.id.layout_seats)
.children
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<TextView>().toList()

private val titleView = viewGroup.findViewById<TextView>(R.id.text_title)
private val priceView = viewGroup.findViewById<TextView>(R.id.text_price)
private val nextButton = viewGroup.findViewById<Button>(R.id.btn_next)

private var price: Price = Price(0)

fun set(title: String) {
setSeatViews()
setTitle(title)
setNextButton()
setPrice(price.toPresentation())
}

private fun setTitle(title: String) {
titleView.text = title
}

private fun setNextButton() {
nextButton.setOnClickListener {
Log.d("click", true.toString())
nextListener
}
}

private fun setPrice(price: Int) {
priceView.text = viewGroup.context.getString(
R.string.price,
DecimalFormat(viewGroup.context.getString(R.string.decimal_format)).format(price),
)
}

private fun setSeatViews() {
seatViews.forEachIndexed { index, textView ->
textView.setOnClickListener {
val (row, col) = indexToRowCol(index)
val result = seatSystem.select(row, col)
when (result) {
is SelectResult.Success.Selection -> {
textView.setBackgroundColor(textView.context.getColor(R.color.select_seat))
if (result.isSelectAll) {
nextButton.isEnabled = true
}
}
is SelectResult.Success.Deselection -> {
textView.setBackgroundColor(textView.context.getColor(R.color.white))
nextButton.isEnabled = false
setPrice(result.seatPrice.price)
}
is SelectResult.MaxSelection -> {
Toast.makeText(
viewGroup.context,
SELECT_ALL_SEAT_MESSAGE,
Toast.LENGTH_LONG,
)
.show()
}
is SelectResult.WrongInput -> {
Toast.makeText(
viewGroup.context,
SELECT_WRONG_SEAT_MESSAGE,
Toast.LENGTH_LONG,
)
.show()
}
}
val newPrice = priceSystem.getCurrentPrice(price, result)
price = newPrice
setPrice(newPrice.toPresentation())
}
}
}

private fun indexToRowCol(index: Int): Pair<Int, Int> = Pair((index) / Theater.col, (index) % Theater.col)

companion object {
private const val SELECT_ALL_SEAT_MESSAGE = "좌석을 이미 다 선택하셨습니다."
private const val SELECT_WRONG_SEAT_MESSAGE = "잘못된 접근입니다."
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ class TicketResultActivity : AppCompatActivity() {

companion object {
private const val DATA_LOADING_ERROR_MESSAGE = "데이터가 로딩되지 않았습니다. 다시 시도해주세요."
const val INFO_KEY = "TICKETING_INFO"
const val INFO_KEY = "TICKET_INFO"
}
}
7 changes: 7 additions & 0 deletions app/src/main/java/woowacourse/movie/model/PriceMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package woowacourse.movie.model

import woowacourse.movie.domain.price.Price

fun Price.toPresentation(): Int {
return price
}
7 changes: 7 additions & 0 deletions app/src/main/java/woowacourse/movie/model/SeatMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package woowacourse.movie.model

import woowacourse.movie.domain.seat.Seat

fun Seat.toPresentation(): SeatModel {
return SeatModel(row, col)
}
9 changes: 9 additions & 0 deletions app/src/main/java/woowacourse/movie/model/SeatModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package woowacourse.movie.model

class SeatModel(row: Int, col: Int) {
val seatId: String

init {
seatId = ('A'.code + row).toString() + col.toString()
}
}
3 changes: 2 additions & 1 deletion app/src/main/java/woowacourse/movie/model/TicketMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ package woowacourse.movie.model

import woowacourse.movie.domain.ticket.Ticket

fun Ticket.toPresentation(): TicketModel = TicketModel(title, playingDateTime, count, price.price)
fun Ticket.toPresentation(): TicketModel =
TicketModel(title, playingDateTime, seats.size, seats.map { it.toPresentation() }, price.toPresentation())
1 change: 1 addition & 0 deletions app/src/main/java/woowacourse/movie/model/TicketModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ data class TicketModel(
val title: String,
val playingDateTime: LocalDateTime,
val count: Int,
val seats: List<SeatModel>,
val price: Int
) : java.io.Serializable
26 changes: 26 additions & 0 deletions app/src/main/java/woowacourse/movie/util/Theater.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package woowacourse.movie.util

import woowacourse.movie.domain.policy.MorningPolicy
import woowacourse.movie.domain.policy.MovieDayPolicy
import woowacourse.movie.domain.policy.NightPolicy
import woowacourse.movie.domain.seat.Grade
import woowacourse.movie.domain.theater.TheaterInfo

object Theater {
private val rowGrade = mapOf(
0 to Grade.B,
1 to Grade.B,
2 to Grade.S,
3 to Grade.S,
4 to Grade.A,
)
val row = 5
val col = 4

val info = TheaterInfo(rowGrade, row, col)
val policies = listOf(
MovieDayPolicy(),
MorningPolicy(),
NightPolicy(),
)
}
5 changes: 3 additions & 2 deletions app/src/main/res/layout/activity_seat_select.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EAEAEA"
android:id="@+id/layout_select_seat"
tools:context=".activity.seatselect.SeatSelectActivity">

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -313,7 +314,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingHorizontal="20dp"
app:layout_constraintEnd_toStartOf="@id/btn_okay">
app:layout_constraintEnd_toStartOf="@id/btn_next">

<TextView
android:id="@+id/text_title"
Expand All @@ -334,7 +335,7 @@
</LinearLayout>

<Button
android:id="@+id/btn_okay"
android:id="@+id/btn_next"
android:layout_width="88dp"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
Expand Down
Loading