Skip to content

Commit 8852463

Browse files
authored
Merge pull request #244 from YAPP-Github/feat/#243-sdk35-support
[FEAT] Target SDK 35 λŒ€μ‘ 및 μ•ŒλžŒ ν•΄μ œ λ²„νŠΌμ„ ν†΅ν•œ λ―Έμ…˜ μ§„μž… μ‹€νŒ¨ 버그 μˆ˜μ •
2 parents e0de396 + 374369f commit 8852463

16 files changed

Lines changed: 277 additions & 267 deletions

File tree

β€Žapp/build.gradle.ktsβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ android {
1212
defaultConfig {
1313
versionCode = 5
1414
versionName = "1.0.3"
15-
targetSdk = 34
15+
targetSdk = 35
1616
}
1717

1818
buildTypes {

β€Žapp/src/main/java/com/yapp/orbit/MainActivity.ktβ€Ž

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
44
import android.content.pm.ActivityInfo
55
import android.os.Bundle
66
import androidx.activity.ComponentActivity
7-
import androidx.activity.SystemBarStyle
87
import androidx.activity.compose.setContent
98
import androidx.activity.enableEdgeToEdge
109
import androidx.compose.runtime.CompositionLocalProvider
@@ -25,16 +24,7 @@ class MainActivity : ComponentActivity() {
2524
override fun onCreate(savedInstanceState: Bundle?) {
2625
super.onCreate(savedInstanceState)
2726
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
28-
enableEdgeToEdge(
29-
statusBarStyle = SystemBarStyle.light(
30-
android.graphics.Color.TRANSPARENT,
31-
android.graphics.Color.TRANSPARENT,
32-
),
33-
navigationBarStyle = SystemBarStyle.light(
34-
android.graphics.Color.BLACK,
35-
android.graphics.Color.BLACK,
36-
),
37-
)
27+
enableEdgeToEdge()
3828
setContent {
3929
val navigator = rememberOrbitNavigator()
4030

β€Žapp/src/main/java/com/yapp/orbit/OrbitNavHost.ktβ€Ž

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,24 @@ import androidx.compose.animation.fadeIn
66
import androidx.compose.animation.fadeOut
77
import androidx.compose.animation.slideInVertically
88
import androidx.compose.animation.slideOutVertically
9-
import androidx.compose.foundation.layout.navigationBarsPadding
9+
import androidx.compose.foundation.background
10+
import androidx.compose.foundation.layout.Box
11+
import androidx.compose.foundation.layout.BoxScope
12+
import androidx.compose.foundation.layout.WindowInsets
13+
import androidx.compose.foundation.layout.fillMaxWidth
14+
import androidx.compose.foundation.layout.navigationBars
1015
import androidx.compose.foundation.layout.padding
16+
import androidx.compose.foundation.layout.windowInsetsBottomHeight
1117
import androidx.compose.material3.Scaffold
1218
import androidx.compose.material3.SnackbarHost
1319
import androidx.compose.material3.SnackbarHostState
1420
import androidx.compose.runtime.Composable
1521
import androidx.compose.runtime.remember
22+
import androidx.compose.ui.Alignment
1623
import androidx.compose.ui.Modifier
24+
import androidx.compose.ui.graphics.Color
1725
import androidx.compose.ui.unit.dp
26+
import androidx.compose.ui.zIndex
1827
import androidx.navigation.compose.NavHost
1928
import com.yapp.common.navigation.OrbitNavigator
2029
import com.yapp.common.navigation.rememberOrbitNavigator
@@ -41,55 +50,65 @@ internal fun OrbitNavHost(
4150
) {
4251
val snackBarHostState = remember { SnackbarHostState() }
4352

44-
OrbitBottomSheetLayout(
45-
sheetState = bottomSheetState,
46-
) {
47-
Scaffold(
48-
modifier = modifier,
49-
snackbarHost = {
50-
OrbitSnackBarHost(snackBarHostState = snackBarHostState)
51-
},
52-
containerColor = OrbitTheme.colors.gray_900,
53-
) {
54-
NavHost(
55-
navController = navigator.navController,
56-
startDestination = navigator.startDestination,
57-
modifier = Modifier.navigationBarsPadding(),
53+
Box {
54+
OrbitBottomSheetLayout(sheetState = bottomSheetState) {
55+
Scaffold(
56+
modifier = modifier,
57+
snackbarHost = { OrbitSnackBarHost(snackBarHostState) },
58+
containerColor = OrbitTheme.colors.gray_900,
5859
) {
59-
splashScreen(
60-
navigator = navigator,
61-
)
62-
onboardingNavGraph(
63-
navigator = navigator,
64-
bottomSheetState = bottomSheetState,
65-
)
66-
homeNavGraph(
60+
OrbitNavigationGraph(
6761
navigator = navigator,
6862
bottomSheetState = bottomSheetState,
6963
snackBarHostState = snackBarHostState,
7064
)
71-
missionScreen(navigator = navigator)
72-
fortuneNavGraph(
73-
navigator = navigator,
74-
snackBarHostState = snackBarHostState,
75-
)
76-
settingNavGraph(navigator = navigator)
77-
webViewScreen(navigator = navigator)
7865
}
7966
}
67+
68+
NavigationBarScrim()
8069
}
8170
}
8271

72+
@Composable
73+
private fun OrbitNavigationGraph(
74+
navigator: OrbitNavigator,
75+
bottomSheetState: OrbitBottomSheetState,
76+
snackBarHostState: SnackbarHostState,
77+
) {
78+
NavHost(
79+
navController = navigator.navController,
80+
startDestination = navigator.startDestination,
81+
) {
82+
splashScreen(navigator)
83+
onboardingNavGraph(navigator, bottomSheetState)
84+
homeNavGraph(navigator, bottomSheetState, snackBarHostState)
85+
missionScreen(navigator)
86+
fortuneNavGraph(navigator, snackBarHostState)
87+
settingNavGraph(navigator)
88+
webViewScreen(navigator)
89+
}
90+
}
91+
92+
@Composable
93+
private fun BoxScope.NavigationBarScrim() {
94+
Box(
95+
modifier = Modifier
96+
.align(Alignment.BottomCenter)
97+
.fillMaxWidth()
98+
.windowInsetsBottomHeight(WindowInsets.navigationBars)
99+
.background(Color.Black)
100+
.zIndex(1f),
101+
)
102+
}
103+
83104
@Composable
84105
private fun OrbitSnackBarHost(
85106
snackBarHostState: SnackbarHostState,
86107
) {
87108
AnimatedVisibility(
88109
visible = snackBarHostState.currentSnackbarData != null,
89110
enter = slideInVertically(initialOffsetY = { it }) + fadeIn(),
90-
exit = slideOutVertically(
91-
targetOffsetY = { it },
92-
) + fadeOut(),
111+
exit = slideOutVertically(targetOffsetY = { it }) + fadeOut(),
93112
) {
94113
SnackbarHost(
95114
hostState = snackBarHostState,
@@ -102,9 +121,9 @@ private fun OrbitSnackBarHost(
102121
end = 20.dp,
103122
bottom = visuals?.bottomPadding ?: 12.dp,
104123
),
105-
label = visuals?.actionLabel ?: "",
124+
label = visuals?.actionLabel.orEmpty(),
106125
iconRes = visuals?.iconRes,
107-
message = visuals?.message ?: "",
126+
message = visuals?.message.orEmpty(),
108127
onAction = { snackBarHostState.currentSnackbarData?.performAction() },
109128
)
110129
},

β€Žcore/alarm/src/main/java/com/yapp/alarm/AlarmConstants.ktβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ object AlarmConstants {
77
const val ACTION_ALARM_INTERACTION_ACTIVITY_CLOSE = "com.yapp.orbit.ACTION_ALERT_INTERACTION_CLOSE"
88

99
const val EXTRA_NOTIFICATION_ID = "com.yapp.orbit.EXTRA_NOTIFICATION_ID"
10+
const val EXTRA_MISSION_TYPE = "com.yapp.orbit.EXTRA_MISSION_TYPE"
11+
const val EXTRA_MISSION_COUNT = "com.yapp.orbit.EXTRA_MISSION_COUNT"
1012

1113
const val EXTRA_ALARM = "com.yapp.orbit.EXTRA_ALARM"
1214
const val EXTRA_ALARM_DAY = "com.yapp.orbit.EXTRA_ALARM_DAY"

β€Žcore/alarm/src/main/java/com/yapp/alarm/pendingIntent/interaction/AlarmDismissPendingIntent.ktβ€Ž

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import com.yapp.alarm.receivers.AlarmReceiver
1212
fun createAlarmDismissPendingIntent(
1313
applicationContext: Context,
1414
pendingIntentId: Long,
15+
missionType: Int,
16+
missionCount: Int,
1517
): PendingIntent {
16-
val alarmDismissIntent = createAlarmDismissIntent(applicationContext, pendingIntentId)
18+
val alarmDismissIntent = createAlarmDismissIntent(applicationContext, pendingIntentId, missionType, missionCount)
1719
return PendingIntent.getBroadcast(
1820
applicationContext,
1921
pendingIntentId.toInt(),
@@ -25,10 +27,14 @@ fun createAlarmDismissPendingIntent(
2527
fun createAlarmDismissIntent(
2628
context: Context,
2729
notificationId: Long,
30+
missionType: Int,
31+
missionCount: Int,
2832
): Intent {
2933
return Intent(AlarmConstants.ACTION_ALARM_DISMISSED).apply {
3034
setClass(context, AlarmReceiver::class.java)
3135
putExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, notificationId)
36+
putExtra(AlarmConstants.EXTRA_MISSION_TYPE, missionType)
37+
putExtra(AlarmConstants.EXTRA_MISSION_COUNT, missionCount)
3238
}
3339
}
3440

β€Žcore/alarm/src/main/java/com/yapp/alarm/receivers/AlarmInteractionActivityReceiver.ktβ€Ž

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.yapp.alarm.receivers
33
import android.content.BroadcastReceiver
44
import android.content.Context
55
import android.content.Intent
6+
import android.util.Log
67
import androidx.activity.ComponentActivity
78
import androidx.core.net.toUri
89
import com.yapp.alarm.AlarmConstants
@@ -29,14 +30,25 @@ class AlarmInteractionActivityReceiver(private val activity: ComponentActivity)
2930
activity.finish()
3031

3132
if (!isSnoozed) {
33+
val notificationId = intent.getLongExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, -1L)
34+
val missionType = intent.getIntExtra(AlarmConstants.EXTRA_MISSION_TYPE, -1)
35+
val missionCount = intent.getIntExtra(AlarmConstants.EXTRA_MISSION_COUNT, -1)
36+
37+
if (notificationId == -1L || missionType == -1 || missionCount == -1) {
38+
Log.e("AlarmInteraction", "ν•„μˆ˜ κ°’ λˆ„λ½")
39+
return
40+
}
41+
3242
CoroutineScope(Dispatchers.IO).launch {
3343
val fortuneDate = fortuneRepository.fortuneDateFlow.firstOrNull()
3444
val todayDate = LocalDate.now().format(DateTimeFormatter.ISO_DATE)
3545

3646
if (fortuneDate != todayDate) {
3747
context?.let {
48+
val uriString =
49+
"orbitapp://mission?notificationId=$notificationId&missionType=$missionType&missionCount=$missionCount"
3850
val missionIntent =
39-
Intent(Intent.ACTION_VIEW, "orbitapp://mission".toUri()).apply {
51+
Intent(Intent.ACTION_VIEW, uriString.toUri()).apply {
4052
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
4153
setPackage(context.packageName)
4254
}

β€Žcore/alarm/src/main/java/com/yapp/alarm/receivers/AlarmReceiver.ktβ€Ž

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ class AlarmReceiver : BroadcastReceiver() {
4646
val alarmServiceIntent = createAlarmServiceIntent(context, intent)
4747
when (intent.action) {
4848
AlarmConstants.ACTION_ALARM_TRIGGERED -> {
49-
Log.d("AlarmReceiver", "Alarm Triggered")
50-
5149
val alarm: Alarm? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
52-
alarmServiceIntent.getParcelableExtra(AlarmConstants.EXTRA_ALARM, Alarm::class.java)
50+
alarmServiceIntent.getParcelableExtra(
51+
AlarmConstants.EXTRA_ALARM,
52+
Alarm::class.java,
53+
)
5354
} else {
5455
@Suppress("DEPRECATION")
5556
alarmServiceIntent.getParcelableExtra(AlarmConstants.EXTRA_ALARM)
@@ -68,8 +69,6 @@ class AlarmReceiver : BroadcastReceiver() {
6869
}
6970

7071
AlarmConstants.ACTION_ALARM_SNOOZED -> {
71-
Log.d("AlarmReceiver", "Alarm Snoozed")
72-
7372
val alarm: Alarm? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
7473
intent.getParcelableExtra(AlarmConstants.EXTRA_ALARM, Alarm::class.java)
7574
} else {
@@ -86,44 +85,54 @@ class AlarmReceiver : BroadcastReceiver() {
8685
)
8786
alarm?.let { handleSnooze(context, it) }
8887

89-
Toast.makeText(context, "μ•ŒλžŒμ΄ ${alarm?.snoozeInterval}λΆ„ ν›„ λ‹€μ‹œ μšΈλ €μš”", Toast.LENGTH_SHORT).show()
88+
Toast.makeText(
89+
context,
90+
"μ•ŒλžŒμ΄ ${alarm?.snoozeInterval}λΆ„ ν›„ λ‹€μ‹œ μšΈλ €μš”",
91+
Toast.LENGTH_SHORT,
92+
).show()
9093
}
9194

9295
AlarmConstants.ACTION_ALARM_DISMISSED -> {
93-
Log.d("AlarmReceiver", "Alarm Dismissed")
94-
95-
val alarmId = intent.getLongExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, -1L)
96-
if (alarmId != -1L) {
97-
CoroutineScope(Dispatchers.IO).launch {
98-
val alarms = alarmUseCase.getAllAlarms().first().sortedBy { it.isAlarmActive }
99-
val isFirstAlarm = alarms.firstOrNull()?.id == alarmId
100-
101-
analyticsHelper.logEvent(
102-
AnalyticsEvent(
103-
type = "alarm_dismiss",
104-
properties = mapOf(
105-
AnalyticsEvent.AlarmPropertiesKeys.ALARM_ID to "$alarmId",
106-
AnalyticsEvent.AlarmPropertiesKeys.DISMISS_IS_FIRST_ALARM to isFirstAlarm,
107-
),
108-
),
109-
)
110-
val existingId = fortuneRepository.firstDismissedAlarmIdFlow.firstOrNull()
111-
if (existingId == null) {
112-
// 첫 번째 μ•ŒλžŒ ν•΄μ œ 기둝
113-
fortuneRepository.saveFirstDismissedAlarmId(alarmId)
114-
} else if (existingId != alarmId) {
115-
// 두 번째 μ•ŒλžŒ ν•΄μ œ 감지 - κΈ°μ‘΄ 기둝 μ‚­μ œ
116-
fortuneRepository.clearDismissedAlarmId()
117-
}
118-
}
96+
val notificationId = intent.getLongExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, -1L)
97+
val missionType = intent.getIntExtra(AlarmConstants.EXTRA_MISSION_TYPE, -1)
98+
val missionCount = intent.getIntExtra(AlarmConstants.EXTRA_MISSION_COUNT, -1)
11999

120-
androidAlarmScheduler.cancelSnoozedAlarm(alarmId)
121-
} else {
122-
Log.e("AlarmReceiver", "μ•ŒλžŒ ID μˆ˜μ‹  μ‹€νŒ¨")
100+
if (notificationId == -1L) {
101+
Log.e("AlarmReceiver", "notificationId μˆ˜μ‹  μ‹€νŒ¨")
102+
return
123103
}
124-
androidAlarmScheduler.cancelSnoozedAlarm(alarmId)
104+
105+
androidAlarmScheduler.cancelSnoozedAlarm(notificationId)
125106
context.stopService(alarmServiceIntent)
126-
sendBroadCastToCloseAlarmInteractionActivity(context)
107+
108+
sendBroadCastToCloseAlarmInteractionActivity(
109+
context = context,
110+
notificationId = notificationId,
111+
missionType = missionType,
112+
missionCount = missionCount,
113+
)
114+
115+
CoroutineScope(Dispatchers.IO).launch {
116+
val alarms = alarmUseCase.getAllAlarms().first().sortedBy { it.isAlarmActive }
117+
val isFirstAlarm = alarms.firstOrNull()?.id == notificationId
118+
119+
analyticsHelper.logEvent(
120+
AnalyticsEvent(
121+
type = "alarm_dismiss",
122+
properties = mapOf(
123+
AnalyticsEvent.AlarmPropertiesKeys.ALARM_ID to "$notificationId",
124+
AnalyticsEvent.AlarmPropertiesKeys.DISMISS_IS_FIRST_ALARM to isFirstAlarm,
125+
),
126+
),
127+
)
128+
129+
val existingId = fortuneRepository.firstDismissedAlarmIdFlow.firstOrNull()
130+
if (existingId == null) {
131+
fortuneRepository.saveFirstDismissedAlarmId(notificationId)
132+
} else if (existingId != notificationId) {
133+
fortuneRepository.clearDismissedAlarmId()
134+
}
135+
}
127136

128137
Toast.makeText(context, "μ•ŒλžŒμ΄ ν•΄μ œλ˜μ—ˆμ–΄μš”", Toast.LENGTH_SHORT).show()
129138
}
@@ -160,21 +169,22 @@ class AlarmReceiver : BroadcastReceiver() {
160169
id = alarm.id + AlarmConstants.SNOOZE_ID_OFFSET,
161170
)
162171

163-
Log.d(
164-
"AlarmReceiver",
165-
"Scheduling snooze alarm: alarmId=${updatedAlarm.id}, newTime=${updatedAlarm.hour}:${updatedAlarm.minute}, remaining snoozeCount=$newSnoozeCount",
166-
)
167-
168172
context.stopService(Intent(context, AlarmService::class.java))
169173
androidAlarmScheduler.scheduleAlarm(updatedAlarm)
170174
}
171175

172-
private fun sendBroadCastToCloseAlarmInteractionActivity(context: Context) {
173-
Log.d("AlarmReceiver", "Send Broadcast to close Alarm Interaction Activity")
174-
val alarmAlertActivityCloseIntent =
175-
Intent(AlarmConstants.ACTION_ALARM_INTERACTION_ACTIVITY_CLOSE).apply {
176-
putExtra(AlarmConstants.EXTRA_IS_SNOOZED, false)
177-
}
178-
context.sendBroadcast(alarmAlertActivityCloseIntent)
176+
private fun sendBroadCastToCloseAlarmInteractionActivity(
177+
context: Context,
178+
notificationId: Long,
179+
missionType: Int,
180+
missionCount: Int,
181+
) {
182+
val intent = Intent(AlarmConstants.ACTION_ALARM_INTERACTION_ACTIVITY_CLOSE).apply {
183+
putExtra(AlarmConstants.EXTRA_IS_SNOOZED, false)
184+
putExtra(AlarmConstants.EXTRA_NOTIFICATION_ID, notificationId)
185+
putExtra(AlarmConstants.EXTRA_MISSION_TYPE, missionType)
186+
putExtra(AlarmConstants.EXTRA_MISSION_COUNT, missionCount)
187+
}
188+
context.sendBroadcast(intent)
179189
}
180190
}

0 commit comments

Comments
Β (0)