Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
63fba88
[feat] 바텀 네비 세팅 중 임시 커밋
kangyuri1114 Mar 18, 2025
4a5f5c0
[feat] 바텀 네비 UI 세팅
kangyuri1114 Mar 18, 2025
a779c8e
[feat] 바텀 네비 constraint 수정
kangyuri1114 Mar 19, 2025
18b23e2
[feat] 바텀 네비 아이템 클릭 리스너 함수 추가
kangyuri1114 Mar 19, 2025
334cac4
Merge branch 'develop' into feat/set-bottom-navigation
kangyuri1114 Mar 24, 2025
0dc0340
[feat] 현 메인 액티비티 명을 cefeteriaActivity로 변경
kangyuri1114 Mar 25, 2025
1a7ac30
[feat] 현 메인 액티비티 명을 cefeteriaActivity로 변경
kangyuri1114 Mar 25, 2025
cbaa8aa
[feat] Mypage, Cafeteria Fragment 로 전환 후 MainActivity에 있어야 하는 로직 옮기기.…
kangyuri1114 Mar 25, 2025
30d644e
[chore] 주석 추가 및 불필요 코드 삭제
kangyuri1114 Mar 25, 2025
a494fe9
[chore] Mypage, Cafeteria Fragment를 MainActivity ViewPager 로 넣기는 성공 했…
kangyuri1114 Mar 25, 2025
f514999
[feat] CalendarViewModel 로직을 MainViewModel로 옮김
kangyuri1114 Mar 25, 2025
12a89d5
[chore] 불필요한 코드 삭제
kangyuri1114 Mar 25, 2025
f803c08
[fix] 이전, 다음 주차 이동 버튼 클릭 시 앱터짐 이슈 해결 (데이터바인딩을 뷰바인딩으로)
kangyuri1114 Mar 25, 2025
7a5894c
[chore] 불필요한 코드 삭제
kangyuri1114 Mar 25, 2025
8bbea17
[feat] 마이페이지 toolbar 추가
kangyuri1114 Mar 25, 2025
6d534b9
[feat] map 프래그먼트 컴포즈 뷰 띄우기 성공 및 임시로 주석처리 진행
kangyuri1114 Mar 25, 2025
1ae1bd1
Merge branch 'develop' into feat/set-bottom-navigation
kangyuri1114 Mar 27, 2025
bda5973
release 2.1.7 (#278)
kangyuri1114 Mar 27, 2025
b766b9e
[Chore] Change delete/modify/report modal (#248)
HI-JIN2 Mar 27, 2025
39c8996
feat: splash 기존 이미지로 변경 및 스플래쉬 실행 시간 2초로 복구 (#281)
kangyuri1114 Mar 30, 2025
c5879dd
feat: splash 배경 색 변경 (#282)
kangyuri1114 Mar 30, 2025
a1c32f7
Merge branch 'develop' into feat/set-bottom-navigation
kangyuri1114 Apr 1, 2025
7f69207
feat: BottomNavigation 에서 viewPager로 화면 전환하던 방식을 jetpack navigation 방…
kangyuri1114 Apr 5, 2025
af06c6b
Merge branch 'develop' into feat/set-bottom-navigation
kangyuri1114 Apr 12, 2025
15f58b9
Merge branch 'develop' into feat/set-bottom-navigation
kangyuri1114 Apr 12, 2025
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
4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ dependencies {
implementation(libs.transport.runtime)
implementation(libs.activity)
implementation(libs.fragment)
implementation(libs.androidx.activity)

// Testing libraries
testImplementation(libs.junit)
Expand Down Expand Up @@ -178,6 +179,9 @@ dependencies {
androidTestImplementation(libs.compose.bom)
debugImplementation(libs.androidx.ui.test.manifest)

// navigation
implementation ("androidx.navigation:navigation-fragment:2.8.9")
implementation ("androidx.navigation:navigation-ui:2.8.9")
}

kapt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.eatssu.android.R
import com.eatssu.android.presentation.main.MainActivity
import com.eatssu.android.presentation.main.cafeteria.CafeteriaFragment
import java.time.DayOfWeek
import java.time.LocalDateTime

Expand Down Expand Up @@ -44,7 +44,7 @@ class NotificationReceiver : BroadcastReceiver() {
}


val intent = Intent(context, MainActivity::class.java).apply {
val intent = Intent(context, CafeteriaFragment::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Expand Down
258 changes: 106 additions & 152 deletions app/src/main/java/com/eatssu/android/presentation/main/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,173 +1,93 @@
package com.eatssu.android.presentation.main

import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI
import androidx.viewpager2.widget.ViewPager2
import com.eatssu.android.R
import com.eatssu.android.databinding.ActivityMainBinding
import com.eatssu.android.presentation.base.BaseActivity
import com.eatssu.android.presentation.main.calendar.CalendarAdapter
import com.eatssu.android.presentation.main.calendar.CalendarAdapter.OnItemListener
import com.eatssu.android.presentation.main.calendar.CalendarViewModel
import com.eatssu.android.presentation.mypage.MyPageActivity
import com.eatssu.android.presentation.login.LoginActivity
import com.eatssu.android.presentation.main.cafeteria.CafeteriaFragment
import com.eatssu.android.presentation.mypage.MyPageViewModel
import com.eatssu.android.presentation.mypage.usernamechange.UserNameChangeActivity
import com.eatssu.android.presentation.util.CalendarUtil
import com.eatssu.android.presentation.util.CalendarUtil.daysInWeekArray
import com.eatssu.android.presentation.util.CalendarUtil.monthYearFromDate
import com.eatssu.android.presentation.util.showToast
import com.eatssu.android.presentation.util.startActivity
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.bottomnavigation.BottomNavigationView
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.util.Locale

@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate), OnItemListener {
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate){

private val mainViewModel: MainViewModel by viewModels()
private val myPageViewModel: MyPageViewModel by viewModels()


private lateinit var calendarViewModel: CalendarViewModel

private var monthYearText: TextView? = null
private var calendarRecyclerView: RecyclerView? = null

private var mainPosition: Int = -1

@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("SuspiciousIndentation")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setupNoToolbar()

// 알림 퍼미션 있는지 자가 진단
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
// 권한이 없다면 요청
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),
1000
)
} else {
// 권한이 이미 있어
}
}
checkAlarmPermission()

checkNicknameIsNull()
collectLogoutState()

// 1) ViewPager2 참조
val viewPager: ViewPager2 = binding.vpMain
val tabLayout: TabLayout = binding.tabLayout

// 2) FragmentStateAdapter 생성 : Fragment 여러개를 ViewPager2에 연결해주는 역할
val viewpagerFragmentAdapter = ViewPager2Adapter(this)

// 3) ViewPager2의 adapter에 설정
viewPager.adapter = viewpagerFragmentAdapter
viewPager.setCurrentItem(viewpagerFragmentAdapter.getDefaultFragmentPosition(), false)

// ###### TabLayout과 ViewPager2를 연결
// 1. 탭메뉴의 이름을 리스트로 생성해둔다.
val tabTitles = listOf("아침", "점심", "저녁")

// 2. TabLayout과 ViewPager2를 연결하고, TabItem의 메뉴명을 설정한다.
TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = tabTitles[position] }.attach()

binding.btnSetting.setOnClickListener {
startActivity<MyPageActivity>();
}

initWidgets()
CalendarUtil.selectedDate = LocalDate.now()
calendarViewModel.setData(LocalDate.now())
setWeekView()
}

private fun initWidgets() {
calendarRecyclerView = binding.weekRecycler
monthYearText = binding.monthYearTV
calendarViewModel = ViewModelProvider(this)[CalendarViewModel::class.java]
}

@RequiresApi(Build.VERSION_CODES.O)
private fun setWeekView() {
monthYearText?.setText(CalendarUtil.selectedDate?.let { monthYearFromDate(it) })
val days: ArrayList<LocalDate>? = CalendarUtil.selectedDate?.let { daysInWeekArray(it) }
val calendarAdapter = days?.let { CalendarAdapter(it, this) }
val gridLayoutManager = GridLayoutManager(applicationContext, 7)

calendarRecyclerView!!.layoutManager = gridLayoutManager
calendarRecyclerView!!.adapter = calendarAdapter
}
setNavigation()

@RequiresApi(Build.VERSION_CODES.O)
fun previousWeekAction(view: View?) {
CalendarUtil.selectedDate = CalendarUtil.selectedDate.minusWeeks(1)
onItemClick(mainPosition, CalendarUtil.selectedDate)
setWeekView()
}

@RequiresApi(Build.VERSION_CODES.O)
fun nextWeekAction(view: View?) {
CalendarUtil.selectedDate = CalendarUtil.selectedDate.plusWeeks(1)
onItemClick(mainPosition, CalendarUtil.selectedDate)
setWeekView()
}

@RequiresApi(Build.VERSION_CODES.O)
override fun onItemClick(position: Int, date: LocalDate) {
CalendarUtil.selectedDate = date
calendarViewModel.setData(date)
mainPosition = position

val viewPager: ViewPager2 = binding.vpMain
val tabLayout: TabLayout = binding.tabLayout
private fun setNavigation() {
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

val viewpagerFragmentAdapter = ViewPager2Adapter(this)

viewPager.adapter = viewpagerFragmentAdapter
viewPager.setCurrentItem(viewpagerFragmentAdapter.getDefaultFragmentPosition(), false)
binding.bottomNaviBar.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.cafeteria_menu -> {
navController.navigate(R.id.homeFragment)
true
}

val tabTitles = listOf("아침", "점심", "저녁")
R.id.map_menu -> {
navController.navigate(R.id.mapFragment)
true
}

TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = tabTitles[position] }.attach()
R.id.mypage_menu -> {
navController.navigate(R.id.myPageFragment)
true
}

binding.btnSetting.setOnClickListener {
startActivity<MyPageActivity>()
else -> {
false
}
}
}

initWidgets()
setWeekView()
}

// set UI --
private fun setupNoToolbar() {
// 툴바 사용하지 않도록 설정
toolbar.let {
Expand All @@ -179,43 +99,24 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
}


private fun checkNicknameIsNull() {
Timber.d("관찰 시작")
mainViewModel.checkNameNull()

lifecycleScope.launch {
mainViewModel.uiState.collectLatest {
if (it.isNicknameNull) {
//닉네임이 null일 때는 닉네임 설정을 안하면 서비스를 못쓰게 막아야함
intent.putExtra("force", true)
startActivity<UserNameChangeActivity>()
showToast(it.toastMessage)
} else {
showToast(it.toastMessage) //Todo 이게 누구님 반갑습니다. 인데 두번 뜸
}
}
}
}


override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_setting -> {
val intent = Intent(this, MyPageActivity::class.java) // 인텐트를 생성해줌,
startActivity(intent) // 화면 전환을 시켜줌
true
}

else -> super.onOptionsItemSelected(item)
}
}

// override fun onCreateOptionsMenu(menu: Menu?): Boolean {
// menuInflater.inflate(R.menu.menu_main, menu)
// return true
// }

// override fun onOptionsItemSelected(item: MenuItem): Boolean {
// return when (item.itemId) {
// R.id.action_setting -> {
// val intent = Intent(this, MyPageActivity::class.java) // 인텐트를 생성해줌,
// startActivity(intent) // 화면 전환을 시켜줌
// true
// }
//
// else -> super.onOptionsItemSelected(item)
// }
// }

// Permission --
// 권한 요청 결과 처리
override fun onRequestPermissionsResult(
requestCode: Int,
Expand All @@ -238,4 +139,57 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
}
}

// 알림 퍼미션 있는지 자가 진단
private fun checkAlarmPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
// 권한이 없다면 요청
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
1000
)
} else {
// 권한이 이미 있어
}
}
}

// CollectState --

private fun checkNicknameIsNull() {
Timber.d("관찰 시작")
mainViewModel.checkNameNull()

lifecycleScope.launch {
mainViewModel.uiState.collectLatest {
if (it.isNicknameNull) {
//닉네임이 null일 때는 닉네임 설정을 안하면 서비스를 못쓰게 막아야함
intent.putExtra("force", true)
startActivity<UserNameChangeActivity>()
showToast(it.toastMessage)
} else {
showToast(it.toastMessage) //Todo 이게 누구님 반갑습니다. 인데 두번 뜸
}
}
}
}

// 로그아웃 처리
private fun collectLogoutState() {
lifecycleScope.launch {
mainViewModel.uiState.collectLatest { state ->
if (state.isLoggedOut) {
showToast(state.toastMessage)
startActivity<LoginActivity>()
finishAffinity()
}
}
}
}
}
Loading
Loading