Skip to content

Commit b549d8d

Browse files
authored
Merge pull request #53 from Richter3766/Feat/issue-#51
Feat/issue #51
2 parents fc1c0ec + d02c4a7 commit b549d8d

File tree

8 files changed

+190
-5
lines changed

8 files changed

+190
-5
lines changed

app/src/main/java/com/example/notimanager/common/objects/DateFormatter.kt

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ package com.example.notimanager.common.objects
33
import android.content.Context
44
import android.graphics.Bitmap
55
import android.graphics.drawable.Drawable
6-
import android.icu.text.SimpleDateFormat
76
import com.example.notimanager.R
8-
import java.util.Date
7+
import java.time.Instant
8+
import java.time.ZoneId
9+
import java.time.format.DateTimeFormatter
910
import java.util.Locale
1011
import java.util.concurrent.TimeUnit
1112

1213
object DateFormatter {
13-
fun formatTimestamp(context: Context, timestamp: Long, format: String = "relative"): String {
14+
fun formatTimestamp(context: Context, timestamp: Long): String {
15+
val sharedPreferences = context.getSharedPreferences("date_format", Context.MODE_PRIVATE)
16+
val format = sharedPreferences.getString("date_format", "relative") ?: "relative"
17+
1418
return if (format == "relative") {
1519
val currentTime = System.currentTimeMillis()
1620
val timeDifference = currentTime - timestamp
@@ -26,8 +30,25 @@ object DateFormatter {
2630
else -> context.getString(R.string.time_year, timeDifference / TimeUnit.DAYS.toMillis(365))
2731
}
2832
} else {
29-
SimpleDateFormat("HH:mm dd.MM.yyyy", Locale.getDefault()).format(Date(timestamp))
33+
formatDate(timestamp)
34+
}
35+
}
36+
37+
private fun formatDate(timestamp: Long): String {
38+
val currentLocale = Locale.getDefault()
39+
40+
// 로케일에 따라 포맷터 설정
41+
val formatter: DateTimeFormatter = if (currentLocale.language == "ko") {
42+
DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH시 mm분", currentLocale)
43+
} else {
44+
DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm a", currentLocale)
3045
}
46+
47+
// 타임스탬프를 Instant로 변환
48+
val instant = Instant.ofEpochMilli(timestamp)
49+
50+
// 포맷터를 사용하여 날짜 포맷팅
51+
return formatter.withZone(ZoneId.systemDefault()).format(instant)
3152
}
3253

3354
fun Drawable.toBitmap(): Bitmap {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.example.notimanager.presentation.stateholder.viewmodel
2+
3+
import android.content.Context
4+
import androidx.lifecycle.ViewModel
5+
import dagger.hilt.android.lifecycle.HiltViewModel
6+
import dagger.hilt.android.qualifiers.ApplicationContext
7+
import javax.inject.Inject
8+
9+
@HiltViewModel
10+
class DateFormatterViewModel @Inject constructor(
11+
@ApplicationContext private val appContext: Context
12+
) : ViewModel() {
13+
private val prefs = "date_format"
14+
private val sharedPreferences = appContext.getSharedPreferences(prefs, Context.MODE_PRIVATE)
15+
16+
val relativeTime = "relative"
17+
val absoluteTime = "absolute"
18+
19+
fun setDateFormat(format: String) {
20+
if (format == relativeTime || format == absoluteTime)
21+
sharedPreferences.edit().putString(prefs, format).apply()
22+
}
23+
24+
fun getDateFormat(): String {
25+
return sharedPreferences.getString(prefs, relativeTime) ?: relativeTime
26+
}
27+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.example.notimanager.presentation.ui.component
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.PaddingValues
6+
import androidx.compose.foundation.layout.Row
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material3.Button
10+
import androidx.compose.material3.RadioButton
11+
import androidx.compose.material3.Text
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.getValue
14+
import androidx.compose.runtime.mutableStateOf
15+
import androidx.compose.runtime.remember
16+
import androidx.compose.runtime.setValue
17+
import androidx.compose.ui.Modifier
18+
import androidx.compose.ui.platform.LocalContext
19+
import androidx.compose.ui.unit.dp
20+
import androidx.hilt.navigation.compose.hiltViewModel
21+
import com.example.notimanager.R
22+
import com.example.notimanager.presentation.stateholder.viewmodel.DateFormatterViewModel
23+
24+
@Composable
25+
fun DateFormatterView(
26+
innerPadding: PaddingValues,
27+
viewModel: DateFormatterViewModel = hiltViewModel()
28+
){
29+
// 언어 설정에 따라 문자열 리소스를 가져오기
30+
val context = LocalContext.current
31+
val relativeTime = context.getString(R.string.format_relative_time)
32+
val absoluteTime = context.getString(R.string.format_absolute_time)
33+
val relativeExample = context.getString(R.string.format_relative_example)
34+
val absoluteExample = context.getString(R.string.format_absolute_example)
35+
val exampleExplanation = context.getString(R.string.format_example_explanation)
36+
val apply = context.getString(R.string.format_apply)
37+
38+
Column(
39+
modifier = Modifier
40+
.padding(innerPadding)
41+
) {
42+
var selectedOption by remember { mutableStateOf(viewModel.getDateFormat()) }
43+
44+
Column {
45+
Row(
46+
modifier = Modifier
47+
.fillMaxWidth()
48+
.padding(16.dp)
49+
.clickable(onClick = { selectedOption = viewModel.relativeTime })
50+
) {
51+
RadioButton(
52+
selected = selectedOption == viewModel.relativeTime,
53+
onClick = { selectedOption = viewModel.relativeTime }
54+
)
55+
Column{
56+
Text(relativeTime)
57+
Text(relativeExample)
58+
Text(exampleExplanation)
59+
}
60+
}
61+
Row(
62+
modifier = Modifier
63+
.fillMaxWidth()
64+
.padding(16.dp)
65+
.clickable(onClick = { selectedOption = viewModel.absoluteTime })
66+
) {
67+
RadioButton(
68+
selected = selectedOption == viewModel.absoluteTime,
69+
onClick = { selectedOption = viewModel.absoluteTime }
70+
)
71+
Column{
72+
Text(absoluteTime)
73+
Text(absoluteExample)
74+
Text(exampleExplanation)
75+
}
76+
}
77+
Button(
78+
onClick = { viewModel.setDateFormat(selectedOption) },
79+
modifier = Modifier
80+
.padding(16.dp)
81+
.fillMaxWidth()
82+
) {
83+
Text(apply)
84+
}
85+
}
86+
87+
}
88+
}

app/src/main/java/com/example/notimanager/presentation/ui/component/SettingView.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,30 @@ fun SettingView(
2626
val filteredList = context.getString(R.string.setting_filtered_list)
2727
val accessPermission = context.getString(R.string.setting_access_permission)
2828
val sendPermission = context.getString(R.string.setting_send_permission)
29+
val dateFormatter = context.getString(R.string.setting_date_format)
2930

3031
Column(
3132
modifier = Modifier
3233
.padding(innerPadding)
3334
) {
35+
// 받지 않는 알림 목록
3436
ClickableTextView(filteredList) {
3537
navController.navigate("FilteredListScreen")
3638
}
3739

40+
// 알림 접근 권한
3841
ClickableTextView(accessPermission) {
3942
servicePermissionViewModel.requestServicePermission()
4043
}
4144

45+
// 알림 발송 권한
4246
ClickableTextView(sendPermission) {
4347
notificationPermissionViewModel.requestPermission(context as Activity)
4448
}
49+
50+
// 시간 형식 변경
51+
ClickableTextView(dateFormatter) {
52+
navController.navigate("DateFormatterScreen")
53+
}
4554
}
4655
}

app/src/main/java/com/example/notimanager/presentation/ui/navigation/AppNavHost.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.navigation.NavHostController
55
import androidx.navigation.compose.NavHost
66
import androidx.navigation.compose.composable
77
import com.example.notimanager.common.objects.Encoder.getDecodeString
8+
import com.example.notimanager.presentation.ui.screen.DateFormatterScreen
89
import com.example.notimanager.presentation.ui.screen.FilteredListScreen
910
import com.example.notimanager.presentation.ui.screen.MainScreen
1011
import com.example.notimanager.presentation.ui.screen.NotificationScreen
@@ -38,5 +39,8 @@ fun AppNavHost(navController: NavHostController) {
3839
composable("FilteredListScreen") {
3940
FilteredListScreen(navController)
4041
}
42+
composable("DateFormatterScreen") {
43+
DateFormatterScreen(navController)
44+
}
4145
}
4246
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.example.notimanager.presentation.ui.screen
2+
3+
import androidx.compose.material3.Scaffold
4+
import androidx.compose.runtime.Composable
5+
import androidx.navigation.NavController
6+
import com.example.notimanager.presentation.ui.component.DateFormatterView
7+
import com.example.notimanager.presentation.ui.component.SettingTopAppBar
8+
9+
@Composable
10+
fun DateFormatterScreen(
11+
navController: NavController,
12+
) {
13+
Scaffold(
14+
topBar = {
15+
SettingTopAppBar{ navController.popBackStack() }
16+
}
17+
) { innerPadding ->
18+
DateFormatterView(innerPadding)
19+
}
20+
}

app/src/main/res/values-ko/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<string name="setting_locale">언어 설정하기</string>
2121
<string name="setting_access_permission">알림 접근 권한 변경하기</string>
2222
<string name="setting_send_permission">알림 발송 권한 변경하기</string>
23+
<string name="setting_date_format">시간 형식 변경하기</string>"
2324

2425
<!-- 허용창 UI -->
2526
<string name="permission_ok">확인</string>
@@ -42,4 +43,12 @@
4243
<string name="time_month">%1$d달 전</string>
4344
<string name="time_year">%1$d년 전</string>
4445

46+
<!-- 시간 설정창 UI -->
47+
<string name="format_relative_time">상대 시간</string>
48+
<string name="format_relative_example">5분 전</string>
49+
<string name="format_absolute_time">절대 시간</string>
50+
<string name="format_absolute_example">2025년 3월 21일 15시 31분</string>
51+
<string name="format_example_explanation">아래와 같이 나타납니다.</string>
52+
<string name="format_apply">적용하기</string>"
53+
4554
</resources>

app/src/main/res/values/strings.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<string name="setting_locale">Change Language Settings</string>
2121
<string name="setting_access_permission">Change Notification Access Permission</string>
2222
<string name="setting_send_permission">Change Notification Send Permission</string>
23-
23+
<string name="setting_date_format">Change Date Format</string>"
2424

2525
<!-- 허용창 UI -->
2626
<string name="permission_ok">OK</string>
@@ -43,4 +43,11 @@
4343
<string name="time_month">%1$d months ago</string>
4444
<string name="time_year">%1$d years ago</string>
4545

46+
<string name="format_relative_time">Relative Time</string>
47+
<string name="format_relative_example">5 minutes ago</string>
48+
<string name="format_absolute_time">Absolute Time</string>
49+
<string name="format_absolute_example">March 21, 2025, 3:31 PM</string>
50+
<string name="format_example_explanation">It will be displayed like this.</string>
51+
<string name="format_apply">Apply</string>
52+
4653
</resources>

0 commit comments

Comments
 (0)