diff --git a/android/2023-emmsale/app/src/main/AndroidManifest.xml b/android/2023-emmsale/app/src/main/AndroidManifest.xml index 88ea197a8..1c7de9486 100644 --- a/android/2023-emmsale/app/src/main/AndroidManifest.xml +++ b/android/2023-emmsale/app/src/main/AndroidManifest.xml @@ -23,6 +23,9 @@ + - \ No newline at end of file + diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetail.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetail.kt new file mode 100644 index 000000000..5a319b241 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetail.kt @@ -0,0 +1,15 @@ +package com.emmsale.data.eventdetail + +data class EventDetail( + val id: Long, + val name: String, + val status: String, + val location: String, + val startDate: String, + val endDate: String, + val informationUrl: String, + val tags: List, + val imageUrl: String, + val remainingDays: Int, + val type: String, +) diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepository.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepository.kt new file mode 100644 index 000000000..ecef11dd1 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepository.kt @@ -0,0 +1,7 @@ +package com.emmsale.data.eventdetail + +import com.emmsale.data.common.ApiResult + +interface EventDetailRepository { + suspend fun fetchEventDetail(eventId: Long): ApiResult +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepositoryImpl.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepositoryImpl.kt new file mode 100644 index 000000000..4ed96862e --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailRepositoryImpl.kt @@ -0,0 +1,18 @@ +package com.emmsale.data.eventdetail + +import com.emmsale.data.common.ApiResult +import com.emmsale.data.common.handleApi +import com.emmsale.data.eventdetail.dto.EventDetailApiModel + +class EventDetailRepositoryImpl( + private val eventDetailService: EventDetailService, +) : EventDetailRepository { + + override suspend fun fetchEventDetail(eventId: Long): ApiResult { + val response = eventDetailService.fetchEventDetail(eventId) + return handleApi( + response = response, + mapToDomain = EventDetailApiModel::toData, + ) + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailService.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailService.kt new file mode 100644 index 000000000..4bbb2cc74 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/EventDetailService.kt @@ -0,0 +1,13 @@ +package com.emmsale.data.eventdetail + +import com.emmsale.data.eventdetail.dto.EventDetailApiModel +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path + +interface EventDetailService { + @GET("events/{eventId}") + suspend fun fetchEventDetail( + @Path("eventId") eventId: Long, + ): Response +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/dto/EventDetailApiModel.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/dto/EventDetailApiModel.kt new file mode 100644 index 000000000..0818ae7b1 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/eventdetail/dto/EventDetailApiModel.kt @@ -0,0 +1,45 @@ +package com.emmsale.data.eventdetail.dto + +import com.emmsale.data.eventdetail.EventDetail +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EventDetailApiModel( + @SerialName("id") + val id: Long, + @SerialName("name") + val name: String, + @SerialName("status") + val status: String, + @SerialName("location") + val location: String, + @SerialName("startDate") + val startDate: String, + @SerialName("endDate") + val endDate: String, + @SerialName("informationUrl") + val informationUrl: String, + @SerialName("tags") + val tags: List, + @SerialName("imageUrl") + val imageUrl: String, + @SerialName("remainingDays") + val remainingDays: Int, + @SerialName("type") + val type: String, +) { + fun toData(): EventDetail = EventDetail( + id = id, + name = name, + status = status, + location = location, + startDate = startDate, + endDate = endDate, + informationUrl = informationUrl, + tags = tags, + imageUrl = imageUrl, + remainingDays = remainingDays, + type = type, + ) +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/data/member/MemberService.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/data/member/MemberService.kt index ec2dd4442..6dcbe3531 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/data/member/MemberService.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/data/member/MemberService.kt @@ -19,4 +19,4 @@ interface MemberService { @POST("/members") suspend fun updateMember(@Body member: MemberApiModel): Response -} \ No newline at end of file +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/di/RepositoryContainer.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/di/RepositoryContainer.kt index bd8e8d98f..791e20622 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/di/RepositoryContainer.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/di/RepositoryContainer.kt @@ -4,6 +4,8 @@ import com.emmsale.data.activity.ActivityRepository import com.emmsale.data.activity.ActivityRepositoryImpl import com.emmsale.data.event.EventRepository import com.emmsale.data.event.EventRepositoryImpl +import com.emmsale.data.eventdetail.EventDetailRepository +import com.emmsale.data.eventdetail.EventDetailRepositoryImpl import com.emmsale.data.fcmToken.FcmTokenRepository import com.emmsale.data.fcmToken.FcmTokenRepositoryImpl import com.emmsale.data.login.LoginRepository @@ -35,4 +37,7 @@ class RepositoryContainer( val fcmTokenRepository: FcmTokenRepository by lazy { FcmTokenRepositoryImpl(fcmTokenService = serviceContainer.fcmTokenService) } + val eventDetailRepository: EventDetailRepository by lazy { + EventDetailRepositoryImpl(eventDetailService = serviceContainer.eventDetailService) + } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/di/ServiceContainer.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/di/ServiceContainer.kt index 184c5b6b2..4d9759710 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/di/ServiceContainer.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/di/ServiceContainer.kt @@ -3,6 +3,7 @@ package com.emmsale.di import com.emmsale.data.activity.ActivityService import com.emmsale.data.common.ServiceFactory import com.emmsale.data.event.EventService +import com.emmsale.data.eventdetail.EventDetailService import com.emmsale.data.fcmToken.FcmTokenService import com.emmsale.data.login.LoginService import com.emmsale.data.member.MemberService @@ -13,4 +14,5 @@ class ServiceContainer(serviceFactory: ServiceFactory) { val memberService: MemberService by lazy { serviceFactory.create(MemberService::class.java) } val eventService: EventService by lazy { serviceFactory.create(EventService::class.java) } val fcmTokenService: FcmTokenService by lazy { serviceFactory.create(FcmTokenService::class.java) } + val eventDetailService: EventDetailService by lazy { serviceFactory.create(EventDetailService::class.java) } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/KerdyApplication.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/KerdyApplication.kt index 66349c786..648577ebe 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/KerdyApplication.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/KerdyApplication.kt @@ -5,7 +5,7 @@ import com.emmsale.data.common.ServiceFactory import com.emmsale.di.RepositoryContainer import com.emmsale.di.ServiceContainer import com.emmsale.di.SharedPreferenceContainer -import com.emmsale.presentation.common.firebase.analytics.Kerdy.initFirebaseAnalytics +import com.emmsale.presentation.common.firebase.analytics.KerdyAnalytics.initFirebaseAnalytics import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -16,7 +16,7 @@ class KerdyApplication : Application() { super.onCreate() repositoryContainer = RepositoryContainer( serviceContainer = ServiceContainer(ServiceFactory()), - preferenceContainer = SharedPreferenceContainer(this) + preferenceContainer = SharedPreferenceContainer(this), ) applicationScope.launch { repositoryContainer.tokenRepository.getToken()?.let(::initFirebaseAnalytics) diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/firebase/analytics/KerdyAnalytics.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/firebase/analytics/KerdyAnalytics.kt index 028df4c1e..ff65e7deb 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/firebase/analytics/KerdyAnalytics.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/firebase/analytics/KerdyAnalytics.kt @@ -1,4 +1,4 @@ -package com.emmsale.presentation.common.firebase.analytics +package com.emmsale.presentation.common.firebase.analytics // ktlint-disable filename import com.emmsale.data.token.Token import com.google.firebase.analytics.FirebaseAnalytics @@ -7,7 +7,7 @@ import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase -object Kerdy { +object KerdyAnalytics { private val firebaseAnalytics: FirebaseAnalytics = Firebase.analytics fun initFirebaseAnalytics(token: Token) { @@ -18,4 +18,3 @@ object Kerdy { firebaseAnalytics.logEvent(event, parameters) } } - diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailActivity.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailActivity.kt new file mode 100644 index 000000000..5ab9511b5 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailActivity.kt @@ -0,0 +1,96 @@ +package com.emmsale.presentation.eventdetail + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.widget.Toast +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import com.emmsale.databinding.ActivityEventDetailBinding +import com.emmsale.presentation.ui.eventdetail.EventDetailFragmentStateAdpater +import com.emmsale.presentation.ui.eventdetail.EventDetailViewModel +import com.emmsale.presentation.ui.eventdetail.EventTag +import com.emmsale.presentation.ui.eventdetail.uistate.EventDetailUiState +import com.google.android.material.tabs.TabLayoutMediator + +class EventDetailActivity : AppCompatActivity() { + private lateinit var binding: ActivityEventDetailBinding + private val viewModel: EventDetailViewModel by viewModels { EventDetailViewModel.factory } + private val eventId: Long by lazy { + intent.getLongExtra(EVENT_ID_KEY, DEFAULT_EVENT_ID) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setUpBinding() + setUpEventDetail() + setBackPress() + viewModel.fetchEventDetail(1) + } + + private fun initFragmentStateAdapter(informationUrl: String, imageUrl: String) { + binding.vpEventdetail.adapter = + EventDetailFragmentStateAdpater(this, eventId, informationUrl, imageUrl) + TabLayoutMediator(binding.tablayoutEventdetail, binding.vpEventdetail) { tab, position -> + when (position) { + INFORMATION_TAB_POSITION -> tab.text = "상세 정보" + COMMENT_TAB_POSITION -> tab.text = "댓글" + PARTICIPANT_TAB_POSITION -> tab.text = "같이가요" + } + }.attach() + } + + private fun setUpBinding() { + binding = ActivityEventDetailBinding.inflate(layoutInflater) + setContentView(binding.root) + } + + private fun setUpEventDetail() { + viewModel.eventDetail.observe(this) { eventDetailUiState -> + when (eventDetailUiState) { + is EventDetailUiState.Success -> { + binding.eventDetail = eventDetailUiState + addTag(eventDetailUiState.tags) + initFragmentStateAdapter( + eventDetailUiState.informationUrl, + eventDetailUiState.imageUrl, + ) + } + + else -> showToastMessage("행사 받아오기 실패") + } + } + } + + private fun addTag(tags: List) { + tags.forEach { binding.chipgroupEvendetailTags.addView(createTag(it)) } + } + + private fun createTag(tag: String) = EventTag(this).apply { + text = tag + } + + private fun showToastMessage(message: String) { + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + } + + private fun setBackPress() { + binding.ivEventdetailBackpress.setOnClickListener { + finish() + } + } + + companion object { + private const val EVENT_ID_KEY = "EVENT_ID_KEY" + private const val DEFAULT_EVENT_ID = 1L + private const val INFORMATION_TAB_POSITION = 0 + private const val COMMENT_TAB_POSITION = 1 + private const val PARTICIPANT_TAB_POSITION = 2 + + fun startActivity(context: Context, eventId: Long) { + val intent = Intent(context, EventDetailActivity::class.java) + intent.putExtra(EVENT_ID_KEY, eventId) + context.startActivity(intent) + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailFragmentStateAdpater.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailFragmentStateAdpater.kt new file mode 100644 index 000000000..3620fb7c2 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailFragmentStateAdpater.kt @@ -0,0 +1,34 @@ +package com.emmsale.presentation.ui.eventdetail + +import EventParticipantFragment +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.emmsale.presentation.ui.eventdetail.comment.EventCommentFragment +import com.emmsale.presentation.ui.eventdetail.information.EventInfoFragment + +class EventDetailFragmentStateAdpater( + fragmentActivity: FragmentActivity, + private val eventId: Long, + private val informationUrl: String, + private val imageUrl: String, +) : FragmentStateAdapter(fragmentActivity) { + + override fun getItemCount(): Int = EVENT_DETAIL_TAB_COUNT + + override fun createFragment(position: Int): Fragment { + return when (position) { + INFORMATION_TAB -> EventInfoFragment.create(informationUrl, imageUrl) + COMMENT_TAB -> EventCommentFragment.create(eventId) + PARTICIPANT_TAB -> EventParticipantFragment.create(eventId) + else -> throw IllegalArgumentException("알수없는 ViewPager 오류입니다.") + } + } + + companion object { + private const val INFORMATION_TAB = 0 + private const val COMMENT_TAB = 1 + private const val PARTICIPANT_TAB = 2 + private const val EVENT_DETAIL_TAB_COUNT = 3 + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailViewModel.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailViewModel.kt new file mode 100644 index 000000000..f30ec108d --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventDetailViewModel.kt @@ -0,0 +1,45 @@ +package com.emmsale.presentation.ui.eventdetail + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.emmsale.data.common.ApiError +import com.emmsale.data.common.ApiException +import com.emmsale.data.common.ApiSuccess +import com.emmsale.data.eventdetail.EventDetailRepository +import com.emmsale.presentation.KerdyApplication +import com.emmsale.presentation.common.ViewModelFactory +import com.emmsale.presentation.ui.eventdetail.uistate.EventDetailUiState +import kotlinx.coroutines.launch + +class EventDetailViewModel( + private val eventDetailRepository: EventDetailRepository, +) : ViewModel() { + + private val _eventDetail: MutableLiveData = + MutableLiveData() + val eventDetail: LiveData + get() = _eventDetail + + fun fetchEventDetail(id: Long) { + viewModelScope.launch { + when (val result = eventDetailRepository.fetchEventDetail(id)) { + is ApiSuccess -> _eventDetail.postValue( + EventDetailUiState.from(result.data), + ) + + is ApiError -> _eventDetail.postValue(EventDetailUiState.Error) + is ApiException -> _eventDetail.postValue(EventDetailUiState.Error) + } + } + } + + companion object { + val factory = ViewModelFactory { + EventDetailViewModel( + eventDetailRepository = KerdyApplication.repositoryContainer.eventDetailRepository, + ) + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventTag.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventTag.kt new file mode 100644 index 000000000..ba90dec5f --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/EventTag.kt @@ -0,0 +1,29 @@ +package com.emmsale.presentation.ui.eventdetail + +import android.content.Context +import android.util.AttributeSet +import android.view.Gravity +import androidx.appcompat.widget.AppCompatTextView +import androidx.core.content.ContextCompat +import androidx.core.view.updatePadding +import com.emmsale.R +import com.emmsale.presentation.utils.extension.px + +class EventTag : AppCompatTextView { + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + init { + initView() + } + + private fun initView() { + isClickable = false + textSize = 12F + gravity = Gravity.CENTER + minimumHeight = 0 + background = ContextCompat.getDrawable(context, R.drawable.bg_eventdetail_tag) + setTextColor(ContextCompat.getColor(context, R.color.black)) + updatePadding(12.px, 3.px, 12.px, 3.px) + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/comment/EventCommentFragment.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/comment/EventCommentFragment.kt new file mode 100644 index 000000000..aa296d215 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/comment/EventCommentFragment.kt @@ -0,0 +1,22 @@ +package com.emmsale.presentation.ui.eventdetail.comment + +import android.os.Bundle +import com.emmsale.R +import com.emmsale.databinding.FragmentEventCommentBinding +import com.emmsale.presentation.base.fragment.BaseFragment + +class EventCommentFragment() : BaseFragment() { + override val layoutResId: Int = R.layout.fragment_event_comment + + companion object { + private const val EVENT_ID_KEY = "EVENT_ID_KEY" + + fun create(eventId: Long): EventCommentFragment { + val fragment = EventCommentFragment() + fragment.arguments = Bundle().apply { + putLong(EVENT_ID_KEY, eventId) + } + return fragment + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/information/EventInfoFragment.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/information/EventInfoFragment.kt new file mode 100644 index 000000000..c1540fc5b --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/information/EventInfoFragment.kt @@ -0,0 +1,24 @@ +package com.emmsale.presentation.ui.eventdetail.information + +import android.os.Bundle +import com.emmsale.R +import com.emmsale.databinding.FragmentEventInformationBinding +import com.emmsale.presentation.base.fragment.BaseFragment + +class EventInfoFragment() : BaseFragment() { + override val layoutResId: Int = R.layout.fragment_event_information + + companion object { + private const val INFORMATION_URL_KEY = "INFORMATION_URL_KEY" + private const val IMAGE_URL_KEY = "IMAGE_URL_KEY" + + fun create(informationUrl: String, imageUrl: String): EventInfoFragment { + val fragment = EventInfoFragment() + fragment.arguments = Bundle().apply { + putString(INFORMATION_URL_KEY, informationUrl) + putString(IMAGE_URL_KEY, imageUrl) + } + return fragment + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/participant/EventParticipantFragment.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/participant/EventParticipantFragment.kt new file mode 100644 index 000000000..7087499cd --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/participant/EventParticipantFragment.kt @@ -0,0 +1,20 @@ +import android.os.Bundle +import com.emmsale.R +import com.emmsale.databinding.FragmentEventParticipantBinding +import com.emmsale.presentation.base.fragment.BaseFragment + +class EventParticipantFragment : BaseFragment() { + override val layoutResId: Int = R.layout.fragment_event_participant + + companion object { + private const val EVENT_ID_KEY = "EVENT_ID_KEY" + + fun create(eventId: Long): EventParticipantFragment { + val fragment = EventParticipantFragment() + fragment.arguments = Bundle().apply { + putLong(EVENT_ID_KEY, eventId) + } + return fragment + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/uistate/EventDetailUiState.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/uistate/EventDetailUiState.kt new file mode 100644 index 000000000..8dd403800 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/eventdetail/uistate/EventDetailUiState.kt @@ -0,0 +1,38 @@ +package com.emmsale.presentation.ui.eventdetail.uistate + +import com.emmsale.data.eventdetail.EventDetail +import com.emmsale.presentation.utils.DateStringFormat + +sealed class EventDetailUiState { + data class Success( + val id: Long, + val name: String, + val status: String, + val location: String, + val startDate: String, + val endDate: String, + val informationUrl: String, + val tags: List, + val imageUrl: String, + ) : EventDetailUiState() + + object Error : EventDetailUiState() + + companion object { + fun from(eventDetail: EventDetail): Success { + return with(eventDetail) { + Success( + id = id, + name = name, + status = status, + location = location, + startDate = DateStringFormat.getGeneralDateFormat(startDate), + endDate = DateStringFormat.getGeneralDateFormat(endDate), + informationUrl = informationUrl, + tags = tags, + imageUrl = imageUrl, + ) + } + } + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/MainActivity.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/MainActivity.kt index d3a4da890..55a38a91e 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/MainActivity.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/MainActivity.kt @@ -2,13 +2,14 @@ package com.emmsale.presentation.ui.main import android.content.Context import android.content.Intent -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.commit import androidx.fragment.app.commitNow import com.emmsale.R import com.emmsale.databinding.ActivityMainBinding -import com.emmsale.presentation.ui.main.events.EventsFragment +import com.emmsale.presentation.eventdetail.EventDetailActivity +import com.emmsale.presentation.ui.main.event.EventFragment import com.emmsale.presentation.ui.main.myProfile.MyProfileFragment class MainActivity : AppCompatActivity() { @@ -32,7 +33,8 @@ class MainActivity : AppCompatActivity() { mainBottomNavigationView.setOnItemSelectedListener { when (it.itemId) { R.id.mi_main_profile -> showFragment(MyProfileFragment.TAG) - R.id.mi_main_home -> showFragment(EventsFragment.TAG) + R.id.mi_main_home -> showFragment(EventFragment.TAG) + R.id.mi_main_setting -> EventDetailActivity.startActivity(this, 1) } return@setOnItemSelectedListener true } @@ -43,7 +45,7 @@ class MainActivity : AppCompatActivity() { private fun addAllFragments() { supportFragmentManager.commitNow { add(R.id.fcv_main, MyProfileFragment(), MyProfileFragment.TAG) - add(R.id.fcv_main, EventsFragment(), EventsFragment.TAG) + add(R.id.fcv_main, EventFragment(), EventFragment.TAG) } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventFragment.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventFragment.kt index 8373398ba..b29de6e2b 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventFragment.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventFragment.kt @@ -1,13 +1,13 @@ package com.emmsale.presentation.ui.main.event import android.os.Bundle -import android.util.Log import android.view.View import androidx.fragment.app.viewModels import com.emmsale.R import com.emmsale.databinding.FragmentEventBinding import com.emmsale.presentation.base.fragment.BaseFragment import com.emmsale.presentation.common.extension.showToast +import com.emmsale.presentation.eventdetail.EventDetailActivity import com.emmsale.presentation.ui.main.event.recyclerview.EventRecyclerViewAdapter import com.emmsale.presentation.ui.main.event.uistate.EventUiState import com.emmsale.presentation.ui.main.event.uistate.EventsUiState @@ -58,7 +58,10 @@ class EventFragment : BaseFragment() { } private fun navigateToEventDetail(event: EventUiState) { - Log.d("buna", event.toString()) - // EventDetail.startActivity(event) + EventDetailActivity.startActivity(requireContext(), event.id) + } + + companion object { + const val TAG = "eventfragmenttag" } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventViewModel.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventViewModel.kt index 3c8350b9d..d5aab4613 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventViewModel.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/event/EventViewModel.kt @@ -26,10 +26,13 @@ class EventViewModel( fun fetchEvents() { viewModelScope.launch { _events.value = EventsUiState.Loading - when (val eventsResult = - eventRepository.getConferences(year, month, status = "종료된 행사")) { - is ApiSuccess -> _events.value = - EventsUiState.Success(eventsResult.data.map(EventUiState::from)) + when ( + val eventsResult = + eventRepository.getConferences(year, month, status = "종료된 행사") + ) { + is ApiSuccess -> + _events.value = + EventsUiState.Success(eventsResult.data.map(EventUiState::from)) is ApiError -> _events.value = EventsUiState.Error is ApiException -> _events.value = EventsUiState.Error diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/events/EventsFragment.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/events/EventsFragment.kt deleted file mode 100644 index 73a75711b..000000000 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/events/EventsFragment.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.emmsale.presentation.ui.main.events - -import android.os.Bundle -import androidx.fragment.app.Fragment -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import com.emmsale.R - -class EventsFragment : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?, - ): View? { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_events, container, false) - } - - companion object { - const val TAG = "Events" - } -} \ No newline at end of file diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/adapter/JobsViewHolder.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/adapter/JobsViewHolder.kt index b3171702e..3c48be10e 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/adapter/JobsViewHolder.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/adapter/JobsViewHolder.kt @@ -19,10 +19,10 @@ class JobsViewHolder( val binding = ItemMyprofileJobsBinding.inflate( LayoutInflater.from(parent.context), parent, - false + false, ) return JobsViewHolder(binding) } } -} \ No newline at end of file +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/uiState/ActivityUiState.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/uiState/ActivityUiState.kt index 548be77ef..22b7cc615 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/uiState/ActivityUiState.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/main/myProfile/uiState/ActivityUiState.kt @@ -11,7 +11,7 @@ data class ActivityUiState( fun from(activity: Activity1): ActivityUiState = ActivityUiState( id = activity.id, - name = activity.name + name = activity.name, ) } -} \ No newline at end of file +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/DateStringFormat.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/DateStringFormat.kt new file mode 100644 index 000000000..ec0b2a830 --- /dev/null +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/DateStringFormat.kt @@ -0,0 +1,20 @@ +package com.emmsale.presentation.utils + +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.format.DateTimeFormatter + +object DateStringFormat { + fun getGeneralDateFormat(dateString: String): String { + val formatter = DateTimeFormatter.ofPattern("yyyy:MM:dd:HH:mm:ss") + val dateTime = LocalDateTime.parse(dateString, formatter) + + val targetDate = LocalDate.of(dateTime.year, dateTime.month, dateTime.dayOfMonth) + val targetTime = LocalTime.of(dateTime.hour, dateTime.minute) + val targetDateTime = LocalDateTime.of(targetDate, targetTime) + + val resultFormatter = DateTimeFormatter.ofPattern("yyyy.M.d HH:mm") + return targetDateTime.format(resultFormatter) + } +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/ImageViewBindingAdapter.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/ImageViewBindingAdapter.kt index 158d6572e..d3840c25b 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/ImageViewBindingAdapter.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/ImageViewBindingAdapter.kt @@ -10,7 +10,7 @@ import com.emmsale.R import com.emmsale.presentation.utils.extension.dp @BindingAdapter("app:imageUrl") -fun ImageView.setImage(imageUrl: String) { +fun ImageView.setImage(imageUrl: String?) { Glide.with(this) .load(imageUrl) .error(R.color.event_thumbnail_default_color) diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/SwipeRefreshLayoutBindingAdapter.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/SwipeRefreshLayoutBindingAdapter.kt index b936d6f82..59ff97c8f 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/SwipeRefreshLayoutBindingAdapter.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/bindingadapter/SwipeRefreshLayoutBindingAdapter.kt @@ -9,4 +9,4 @@ fun setOnRefresh(swipeRefreshLayout: SwipeRefreshLayout, onRefresh: () -> Unit) onRefresh() swipeRefreshLayout.isRefreshing = false } -} \ No newline at end of file +} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/extension/IntExt.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/extension/IntExt.kt index fa85e6187..68db98db7 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/extension/IntExt.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/utils/extension/IntExt.kt @@ -4,4 +4,7 @@ import android.content.res.Resources import kotlin.math.roundToInt val Int.dp: Int + get() = (this / Resources.getSystem().displayMetrics.density).roundToInt() + +val Int.px: Int get() = (this * Resources.getSystem().displayMetrics.density).roundToInt() diff --git a/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tab.xml b/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tab.xml new file mode 100644 index 000000000..dcd7f2a7d --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tab.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tag.xml b/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tag.xml new file mode 100644 index 000000000..eaa3c4423 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/bg_eventdetail_tag.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/bg_eventinformation_urlbutton.xml b/android/2023-emmsale/app/src/main/res/drawable/bg_eventinformation_urlbutton.xml new file mode 100644 index 000000000..002328415 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/bg_eventinformation_urlbutton.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/ic_all_arrowback.xml b/android/2023-emmsale/app/src/main/res/drawable/ic_all_arrowback.xml new file mode 100644 index 000000000..dbe05f179 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/ic_all_arrowback.xml @@ -0,0 +1,14 @@ + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/ic_all_errorimage.xml b/android/2023-emmsale/app/src/main/res/drawable/ic_all_errorimage.xml new file mode 100644 index 000000000..9f2eb6861 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/ic_all_errorimage.xml @@ -0,0 +1,5 @@ + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_date.xml b/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_date.xml new file mode 100644 index 000000000..3b5d9e13b --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_date.xml @@ -0,0 +1,16 @@ + + + + diff --git a/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_place.xml b/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_place.xml new file mode 100644 index 000000000..231135b69 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/drawable/ic_eventdetail_place.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/2023-emmsale/app/src/main/res/layout/activity_event_detail.xml b/android/2023-emmsale/app/src/main/res/layout/activity_event_detail.xml new file mode 100644 index 000000000..746d3daae --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/layout/activity_event_detail.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/layout/activity_main.xml b/android/2023-emmsale/app/src/main/res/layout/activity_main.xml index 979fc057f..5dd6515e0 100644 --- a/android/2023-emmsale/app/src/main/res/layout/activity_main.xml +++ b/android/2023-emmsale/app/src/main/res/layout/activity_main.xml @@ -14,7 +14,6 @@ - \ No newline at end of file + diff --git a/android/2023-emmsale/app/src/main/res/layout/fragment_event_comment.xml b/android/2023-emmsale/app/src/main/res/layout/fragment_event_comment.xml new file mode 100644 index 000000000..9e8c6d96a --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/layout/fragment_event_comment.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/layout/fragment_event_information.xml b/android/2023-emmsale/app/src/main/res/layout/fragment_event_information.xml new file mode 100644 index 000000000..7c8272e5f --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/layout/fragment_event_information.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/layout/fragment_event_participant.xml b/android/2023-emmsale/app/src/main/res/layout/fragment_event_participant.xml new file mode 100644 index 000000000..ff36eb5f5 --- /dev/null +++ b/android/2023-emmsale/app/src/main/res/layout/fragment_event_participant.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/android/2023-emmsale/app/src/main/res/layout/fragment_events.xml b/android/2023-emmsale/app/src/main/res/layout/fragment_events.xml deleted file mode 100644 index bbaf599b7..000000000 --- a/android/2023-emmsale/app/src/main/res/layout/fragment_events.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/2023-emmsale/app/src/main/res/values/colors.xml b/android/2023-emmsale/app/src/main/res/values/colors.xml index 14248a60f..f4df5f9e8 100644 --- a/android/2023-emmsale/app/src/main/res/values/colors.xml +++ b/android/2023-emmsale/app/src/main/res/values/colors.xml @@ -17,4 +17,16 @@ #70DEA2 #70DEA2 #D9D9D9 + + + + #FFFFFF + #7CF0B1 + #FFEA9F + + #70DEA2 + #D9D9D9 + #B1B1B1 + #545454 + #000000 diff --git a/android/2023-emmsale/app/src/main/res/values/strings.xml b/android/2023-emmsale/app/src/main/res/values/strings.xml index 5123d59dd..14f29dc31 100644 --- a/android/2023-emmsale/app/src/main/res/values/strings.xml +++ b/android/2023-emmsale/app/src/main/res/values/strings.xml @@ -25,4 +25,6 @@ D-%d + + Hello blank fragment diff --git a/android/2023-emmsale/app/src/main/res/values/styles.xml b/android/2023-emmsale/app/src/main/res/values/styles.xml index b1ae6409c..1264f7811 100644 --- a/android/2023-emmsale/app/src/main/res/values/styles.xml +++ b/android/2023-emmsale/app/src/main/res/values/styles.xml @@ -1,13 +1,26 @@ + + - \ No newline at end of file + + + + + +