diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 68388f5..fbb9fc9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -53,23 +53,22 @@ android {
}
dependencies {
- implementation 'androidx.core:core-ktx:1.12.0'
+ implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
- implementation 'androidx.activity:activity-compose:1.8.2'
- implementation platform('androidx.compose:compose-bom:2024.04.00')
- implementation "androidx.compose.ui:ui:1.6.5"
- implementation "androidx.compose.ui:ui-tooling-preview:1.6.5"
- implementation 'androidx.compose.material3:material3'
- implementation platform('androidx.compose:compose-bom:2024.04.00')
+ implementation 'androidx.activity:activity-compose:1.9.0'
+ implementation platform('androidx.compose:compose-bom:2024.05.00')
+ implementation "androidx.compose.ui:ui:1.6.7"
+ implementation "androidx.compose.ui:ui-tooling-preview:1.6.7"
+ implementation platform('androidx.compose:compose-bom:2024.05.00')
implementation 'androidx.compose.ui:ui-graphics'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
- androidTestImplementation platform('androidx.compose:compose-bom:2024.04.00')
- androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.6.5"
- androidTestImplementation platform('androidx.compose:compose-bom:2024.04.00')
- debugImplementation "androidx.compose.ui:ui-tooling:1.6.5"
- debugImplementation "androidx.compose.ui:ui-test-manifest:1.6.5"
+ androidTestImplementation platform('androidx.compose:compose-bom:2024.05.00')
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.6.7"
+ androidTestImplementation platform('androidx.compose:compose-bom:2024.05.00')
+ debugImplementation "androidx.compose.ui:ui-tooling:1.6.7"
+ debugImplementation "androidx.compose.ui:ui-test-manifest:1.6.7"
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.appcompat:appcompat-resources:1.6.1"
@@ -82,10 +81,10 @@ dependencies {
runtimeOnly 'androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0'
// https://mvnrepository.com/artifact/androidx.fragment/fragment-ktx
- runtimeOnly 'androidx.fragment:fragment-ktx:1.7.0-rc01'
+ runtimeOnly 'androidx.fragment:fragment-ktx:1.7.0'
// https://mvnrepository.com/artifact/androidx.compose.material3/material3
- runtimeOnly 'androidx.compose.material3:material3:1.2.1'
+ implementation 'androidx.compose.material3:material3:1.2.1'
// AlarmManager for restart service after closed
// Required to avoid crash on Android 12 - API 31
@@ -126,10 +125,12 @@ dependencies {
implementation 'com.github.dutwrapper:dutwrapper-java:v1.9.0'
- implementation 'com.google.android.material:material:1.11.0'
+ implementation 'com.google.android.material:material:1.12.0'
// Display time ago in news subject
implementation 'com.github.marlonlom:timeago:4.0.3'
+
+ implementation 'androidx.core:core-splashscreen:1.2.0-alpha01'
}
// Allow references to generated code
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index 8842667..371c693 100644
Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/io/zoemeow/dutschedule/activity/BaseActivity.kt b/app/src/main/java/io/zoemeow/dutschedule/activity/BaseActivity.kt
index d80cb98..89467a9 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/activity/BaseActivity.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/activity/BaseActivity.kt
@@ -6,6 +6,7 @@ import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.StrictMode
+import android.window.SplashScreen
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
@@ -14,15 +15,18 @@ import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.foundation.Image
import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.graphics.Color
@@ -32,6 +36,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
+import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import io.zoemeow.dutschedule.model.settings.BackgroundImageOption
@@ -72,6 +77,11 @@ abstract class BaseActivity: ComponentActivity() {
permitAllPolicy()
setContent {
+ // Initialize MainViewModel
+ if (!isMainViewModelInitialized()) {
+ mainViewModel = viewModel()
+ }
+
// SnackBar state
snackBarHostState = remember { SnackbarHostState() }
snackBarScope = rememberCoroutineScope()
@@ -80,11 +90,6 @@ abstract class BaseActivity: ComponentActivity() {
focusManager = LocalFocusManager.current
keyboardController = LocalSoftwareKeyboardController.current
- // Initialize MainViewModel
- if (!isMainViewModelInitialized()) {
- mainViewModel = viewModel()
- }
-
DutScheduleTheme(
darkTheme = when (mainViewModel.appSettings.value.themeMode) {
ThemeMode.DarkMode -> true
diff --git a/app/src/main/java/io/zoemeow/dutschedule/model/NavBarItem.kt b/app/src/main/java/io/zoemeow/dutschedule/model/NavBarItem.kt
index 82c34f0..a691054 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/model/NavBarItem.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/model/NavBarItem.kt
@@ -8,32 +8,32 @@ import androidx.compose.ui.graphics.vector.ImageVector
import io.zoemeow.dutschedule.R
data class NavBarItem(
- val title: String,
+ val titleResId: Int,
val icon: ImageVector? = null,
val resourceIconId: Int? = null,
val route: String
) {
companion object {
val news = NavBarItem(
- title = "News",
+ titleResId = R.string.news_title,
resourceIconId = R.drawable.ic_baseline_newspaper_24,
route = "news"
)
val account = NavBarItem(
- title = "Account",
+ titleResId = R.string.account_title,
icon = Icons.Default.AccountCircle,
route = "account"
)
val notification = NavBarItem(
- title = "Notifications",
+ titleResId = R.string.notification_panel_title,
icon = Icons.Default.Notifications,
route = "notifications"
)
val settings = NavBarItem(
- title = "Settings",
+ titleResId = R.string.settings_title,
icon = Icons.Default.Settings,
route = "settings"
)
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/component/main/NotificationItem.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/component/main/NotificationItem.kt
index 9f9c517..724a2cf 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/component/main/NotificationItem.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/component/main/NotificationItem.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.component.main
+import android.content.Context
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
@@ -23,6 +24,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -32,6 +36,7 @@ import io.zoemeow.dutschedule.utils.getRandomString
@Composable
fun NotificationItem(
+ context: Context,
modifier: Modifier = Modifier,
item: NotificationHistory,
showDate: Boolean = false,
@@ -66,7 +71,10 @@ fun NotificationItem(
) {
if (showDate) {
Text(
- CustomDateUtil.unixToDuration(item.timestamp),
+ CustomDateUtil.unixToDurationWithLocale(
+ context = context,
+ unix = item.timestamp
+ ),
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(bottom = 5.dp)
)
@@ -117,6 +125,7 @@ private fun Preview1() {
isRead = false
)
NotificationItem(
+ context = LocalContext.current,
item = notificationHistory
)
}
@@ -134,6 +143,7 @@ private fun Preview2() {
isRead = false
)
NotificationItem(
+ context = LocalContext.current,
item = notificationHistory
)
}
\ No newline at end of file
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/component/news/NewsDetailScreen.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/component/news/NewsDetailScreen.kt
index da11988..aaffd8d 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/component/news/NewsDetailScreen.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/component/news/NewsDetailScreen.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.component.news
+import android.content.Context
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -30,6 +31,7 @@ import io.zoemeow.dutschedule.utils.CustomDateUtil
@Composable
fun NewsDetailScreen(
+ context: Context,
newsItem: NewsGlobalItem,
newsType: NewsType,
padding: PaddingValues = PaddingValues(0.dp),
@@ -38,6 +40,7 @@ fun NewsDetailScreen(
when (newsType) {
NewsType.Global -> {
NewsDetailBody_NewsGlobal(
+ context = context,
padding = padding,
newsItem = newsItem,
linkClicked = linkClicked
@@ -45,6 +48,7 @@ fun NewsDetailScreen(
}
NewsType.Subject -> {
NewsDetailBody_NewsSubject(
+ context = context,
padding = padding,
newsItem = newsItem as NewsSubjectItem,
linkClicked = linkClicked
@@ -55,6 +59,7 @@ fun NewsDetailScreen(
@Composable
private fun NewsDetailBody_NewsGlobal(
+ context: Context,
padding: PaddingValues,
newsItem: NewsGlobalItem,
linkClicked: ((String) -> Unit)? = null
@@ -81,7 +86,10 @@ private fun NewsDetailBody_NewsGlobal(
"dd/MM/yyyy",
"UTC"
)
- } (${CustomDateUtil.unixToDuration(newsItem.date)})",
+ } (${CustomDateUtil.unixToDurationWithLocale(
+ context = context,
+ unix = newsItem.date
+ )})",
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(vertical = 7.dp)
)
@@ -154,6 +162,7 @@ private fun NewsDetailBody_NewsGlobal(
@Composable
private fun NewsDetailBody_NewsSubject(
+ context: Context,
padding: PaddingValues,
newsItem: NewsSubjectItem,
linkClicked: ((String) -> Unit)? = null
@@ -184,7 +193,10 @@ private fun NewsDetailBody_NewsSubject(
"dd/MM/yyyy",
"UTC"
)
- } (${CustomDateUtil.unixToDuration(newsItem.date)})",
+ } (${CustomDateUtil.unixToDurationWithLocale(
+ context = context,
+ unix = newsItem.date
+ )})",
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(vertical = 7.dp)
)
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/AccountInformation.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/AccountInformation.kt
index fb9acea..f906731 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/AccountInformation.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/AccountInformation.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_OK
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -52,7 +53,7 @@ fun AccountActivity.AccountInformation(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/MainView.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/MainView.kt
index 72008df..700cb6e 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/MainView.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/MainView.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
@@ -30,6 +31,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
+import io.zoemeow.dutschedule.R
import io.zoemeow.dutschedule.activity.AccountActivity
import io.zoemeow.dutschedule.model.ProcessState
import io.zoemeow.dutschedule.model.account.AccountAuth
@@ -61,7 +63,7 @@ fun AccountActivity.MainView(
showSnackBar(text = text, clearPrevious = clearPrevious, actionText = actionText, action = action)
},
onBack = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
}
)
@@ -90,7 +92,7 @@ fun AccountMainView(
contentColor = contentColor,
topBar = {
TopAppBar(
- title = { Text("Account") },
+ title = { Text(context.getString(R.string.account_title)) },
colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
navigationIcon = {
if (onBack != null) {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectFee.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectFee.kt
index 6d502e4..454e33f 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectFee.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectFee.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_OK
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -53,7 +54,7 @@ fun AccountActivity.SubjectFee(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectInformation.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectInformation.kt
index c546c0b..0bb6e88 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectInformation.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/SubjectInformation.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_CANCELED
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -59,7 +60,7 @@ fun AccountActivity.SubjectInformation(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_CANCELED)
+ setResult(RESULT_CANCELED)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingResult.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingResult.kt
index 13079da..0fa93d8 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingResult.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingResult.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
@@ -61,7 +62,7 @@ fun AccountActivity.TrainingResult(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingSubjectResult.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingSubjectResult.kt
index fe6db53..d5beea1 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingSubjectResult.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/account/TrainingSubjectResult.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.account
+import android.app.Activity.RESULT_CANCELED
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
@@ -155,7 +156,7 @@ fun AccountActivity.TrainingSubjectResult(
if (searchEnabled.value) {
dismissSearchBar()
} else {
- setResult(ComponentActivity.RESULT_CANCELED)
+ setResult(RESULT_CANCELED)
finish()
}
},
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/MainViewTabbed.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/MainViewTabbed.kt
index 9baad50..4924e6f 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/MainViewTabbed.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/MainViewTabbed.kt
@@ -77,14 +77,14 @@ fun MainActivity.MainViewTabbed(
},
icon = {
if (it.resourceIconId != null) {
- Icon(painter = painterResource(id = it.resourceIconId), it.title)
+ Icon(painter = painterResource(id = it.resourceIconId), context.getString(it.titleResId))
} else if (it.icon != null) {
- Icon(imageVector = it.icon, it.title)
+ Icon(imageVector = it.icon, context.getString(it.titleResId))
} else {
- Icon(imageVector = Icons.Default.Info, it.title)
+ Icon(imageVector = Icons.Default.Info, context.getString(it.titleResId))
}
},
- label = { Text(it.title) }
+ label = { Text(context.getString(it.titleResId)) }
)
}
)
@@ -140,12 +140,12 @@ fun MainActivity.MainViewTabbed(
contentColor = contentColor,
onClick = { item ->
if (listOf(1, 2).contains(item.tag)) {
- Intent(context, NewsActivity::class.java).also {
- it.action = "activity_detail"
+ Intent(context, NewsActivity::class.java).also { intent ->
+ intent.action = "activity_detail"
for (map1 in item.parameters) {
- it.putExtra(map1.key, map1.value)
+ intent.putExtra(map1.key, map1.value)
}
- context.startActivity(it)
+ context.startActivity(intent)
}
}
},
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/NotificationScaffold.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/NotificationScaffold.kt
index 6f8ce6c..703bf67 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/NotificationScaffold.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/main/NotificationScaffold.kt
@@ -106,11 +106,11 @@ fun NotificationScaffold(
)
},
snackbarHost = { snackBarHostState?.let { SnackbarHost(hostState = it) } },
- content = {
+ content = { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
- .padding(it)
+ .padding(paddingValues)
.padding(horizontal = 15.dp)
) {
Column(
@@ -130,12 +130,16 @@ fun NotificationScaffold(
.toSortedMap(compareByDescending { it })
.forEach(action = { group ->
Text(
- CustomDateUtil.unixToDuration(group.key),
+ CustomDateUtil.unixToDurationWithLocale(
+ context = context,
+ unix = group.key
+ ),
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(top = 5.dp, bottom = 4.dp)
)
group.value.forEach { item ->
NotificationItem(
+ context = context,
modifier = Modifier.padding(top = 2.dp, bottom = 5.dp),
isVisible = true,
opacity = opacity,
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/MainView.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/MainView.kt
index 5c7f330..4ef40a8 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/MainView.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/MainView.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.news
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
@@ -70,7 +71,7 @@ fun NewsActivity.MainView(
componentBackgroundAlpha = getControlBackgroundAlpha(),
mainViewModel = getMainViewModel(),
onBack = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
}
)
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsDetail.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsDetail.kt
index 5cfa0b3..982f6ef 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsDetail.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsDetail.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.news
+import android.app.Activity.RESULT_OK
import android.content.Context
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Row
@@ -55,7 +56,7 @@ fun NewsActivity.NewsDetail(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
@@ -104,6 +105,7 @@ fun NewsActivity.NewsDetail(
when (newsType) {
"news_global" -> {
NewsDetailScreen(
+ context = context,
padding = it,
newsItem = Gson().fromJson(newsData, object : TypeToken() {}.type),
newsType = NewsType.Global,
@@ -118,6 +120,7 @@ fun NewsActivity.NewsDetail(
}
"news_subject" -> {
NewsDetailScreen(
+ context = context,
padding = it,
newsItem = Gson().fromJson(newsData, object : TypeToken() {}.type) as NewsGlobalItem,
newsType = NewsType.Subject,
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsSearch.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsSearch.kt
index e18339c..2f85a6d 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsSearch.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/news/NewsSearch.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.news
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
@@ -124,7 +125,7 @@ fun NewsActivity.NewsSearch(
if (isSearchFocused.targetState) {
dismissFocus()
} else {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
}
},
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ExperimentSettings.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ExperimentSettings.kt
index 2f39815..ea0a712 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ExperimentSettings.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ExperimentSettings.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.settings
+import android.app.Activity.RESULT_CANCELED
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -62,7 +63,7 @@ fun SettingsActivity.ExperimentSettings(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_CANCELED)
+ setResult(RESULT_CANCELED)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/LanguageSettings.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/LanguageSettings.kt
index dc583f3..b763d76 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/LanguageSettings.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/LanguageSettings.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.settings
+import android.app.Activity.RESULT_CANCELED
import android.app.LocaleManager
import android.content.Context
import android.os.Build
@@ -65,13 +66,13 @@ fun SettingsActivity.LanguageSettings(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_CANCELED)
+ setResult(RESULT_CANCELED)
finish()
},
content = {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
- "",
+ context.getString(R.string.action_back),
modifier = Modifier.size(25.dp)
)
}
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/MainView.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/MainView.kt
index ad27859..b00979c 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/MainView.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/MainView.kt
@@ -1,11 +1,11 @@
package io.zoemeow.dutschedule.ui.view.settings
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
-import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -71,7 +71,7 @@ fun SettingsActivity.MainView(
showSnackBar(text = text, clearPrevious = clearPrevious, actionText = actionText, action = action)
},
onBack = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
}
)
@@ -100,7 +100,7 @@ fun SettingsMainView(
contentColor = contentColor,
topBar = {
TopAppBar(
- title = { Text(context.getString(R.string.settings_name)) },
+ title = { Text(context.getString(R.string.settings_title)) },
colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
navigationIcon = {
if (onBack != null) {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/NewsNotificationSettings.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/NewsNotificationSettings.kt
index 438a0d4..6be5bd0 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/NewsNotificationSettings.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/NewsNotificationSettings.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.settings
+import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
@@ -94,7 +95,7 @@ fun SettingsActivity.NewsNotificationSettings(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ParseNewsSubjectNotification.kt b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ParseNewsSubjectNotification.kt
index e99ad57..32253bd 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ParseNewsSubjectNotification.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/ui/view/settings/ParseNewsSubjectNotification.kt
@@ -1,5 +1,6 @@
package io.zoemeow.dutschedule.ui.view.settings
+import android.app.Activity.RESULT_OK
import android.content.Context
import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Arrangement
@@ -56,7 +57,7 @@ fun SettingsActivity.ParseNewsSubjectNotification(
navigationIcon = {
IconButton(
onClick = {
- setResult(ComponentActivity.RESULT_OK)
+ setResult(RESULT_OK)
finish()
},
content = {
diff --git a/app/src/main/java/io/zoemeow/dutschedule/utils/CustomDateUtil.kt b/app/src/main/java/io/zoemeow/dutschedule/utils/CustomDateUtil.kt
index cfe7310..c106054 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/utils/CustomDateUtil.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/utils/CustomDateUtil.kt
@@ -1,7 +1,14 @@
package io.zoemeow.dutschedule.utils
import android.annotation.SuppressLint
+import android.content.Context
+import androidx.compose.ui.platform.LocalConfiguration
import com.github.marlonlom.utilities.timeago.TimeAgo
+import com.github.marlonlom.utilities.timeago.TimeAgoMessages
+import io.zoemeow.dutschedule.R
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+import kotlinx.datetime.toLocalDateTime
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
@@ -10,6 +17,7 @@ import java.util.TimeZone
import kotlin.time.DurationUnit
import kotlin.time.toDuration
+
class CustomDateUtil {
companion object {
/**
@@ -52,18 +60,25 @@ class CustomDateUtil {
return SimpleDateFormat(format, Locale.getDefault()).format(Date())
}
- fun unixToDuration(unix: Long = System.currentTimeMillis()): String {
+ fun unixToDurationWithLocale(
+ context: Context,
+ unix: Long = System.currentTimeMillis(),
+ langTag: String = Locale.getDefault().toLanguageTag()
+ ): String {
val duration = (System.currentTimeMillis() - unix).toDuration(DurationUnit.MILLISECONDS)
return when (duration.inWholeHours) {
in 0..23 -> {
- "Today"
+ context.getString(R.string.time_today)
}
in 24..47 -> {
- "Yesterday"
+ context.getString(R.string.time_yesterday)
}
else -> {
- TimeAgo.using(unix)
+ val localeByLangTag = Locale.forLanguageTag(langTag)
+ val messages: TimeAgoMessages =
+ TimeAgoMessages.Builder().withLocale(localeByLangTag).build()
+ TimeAgo.using(unix, messages)
}
}
}
diff --git a/app/src/main/java/io/zoemeow/dutschedule/viewmodel/MainViewModel.kt b/app/src/main/java/io/zoemeow/dutschedule/viewmodel/MainViewModel.kt
index 4b8177c..589da38 100644
--- a/app/src/main/java/io/zoemeow/dutschedule/viewmodel/MainViewModel.kt
+++ b/app/src/main/java/io/zoemeow/dutschedule/viewmodel/MainViewModel.kt
@@ -21,6 +21,8 @@ import io.zoemeow.dutschedule.repository.DutRequestRepository
import io.zoemeow.dutschedule.repository.FileModuleRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
@@ -162,13 +164,13 @@ class MainViewModel @Inject constructor(
}
}
- private val runOnStartupEnabled = mutableStateOf(true)
+ private val _runOnStartup = MutableStateFlow(false)
+ val runOnStartup = _runOnStartup.asStateFlow()
+
private fun runOnStartup(invokeOnCompleted: (() -> Unit)? = null) {
- if (!runOnStartupEnabled.value)
+ if (_runOnStartup.value)
return
- runOnStartupEnabled.value = false
-
appSettings.value = fileModuleRepository.getAppSettings()
accountSession.setAccountSession(fileModuleRepository.getAccountSession())
accountSession.setSchoolYear(schoolYearItem = appSettings.value.currentSchoolYear)
@@ -193,6 +195,7 @@ class MainViewModel @Inject constructor(
forceRequest = true
)
})
+ _runOnStartup.value = true
}
)
}
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
index 47d318e..48a0b2c 100644
--- a/app/src/main/res/drawable/ic_launcher_foreground.xml
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -3,609 +3,174 @@
android:height="108dp"
android:viewportWidth="256"
android:viewportHeight="256">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
index 6fd3463..f5b3906 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
index a66e6a8..f5b3906 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
index eb951cb..4f9d658 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
index 5607e58..4f9d658 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
index 8b30a1a..c099cdd 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
index 4240685..c099cdd 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
index 4b87a90..c4d2c93 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
index b75745e..c4d2c93 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
index e07c0d6..d74963f 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
index 5e5574b..d74963f 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/values-night-v31/themes.xml b/app/src/main/res/values-night-v31/themes.xml
new file mode 100644
index 0000000..d04320c
--- /dev/null
+++ b/app/src/main/res/values-night-v31/themes.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 426b3be..0dcbbc1 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -4,6 +4,9 @@
Tính năng này đang được phát triển. Hãy kiểm tra lại sau.
Bạn cần phải cho phép Quyền truy cập mọi tệp trong quyền hạn ứng dụng để sử dụng tùy chọn này.
Bạn cần phải bật quyền Chuông báo và lời nhắc trong cài đặt Android để sử dụng tính năng này.
+
+ Hôm nay
+ Hôm qua
OK
Mở
@@ -37,7 +40,7 @@
Vào ngày %1$s với tiết học %2$s
Phòng sẽ học bù: %1$s
- Cài đặt
+ Cài đặt
Thông báo
Cài đặt cập nhật tin tức trong nền
Cấu hình cài đặt thông báo tin tức cho bạn, bao gồm thời gian cập nhật, tin tức nào sẽ được bật, cài đặt bộ lọc tin tức và hơn thế nữa.
@@ -185,4 +188,6 @@
Lớp học phần
Lịch sử tìm kiếm
Tìm kiếm %2$s theo %1$s
+
+ Tài khoản
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f0cb02d..1887d6d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,6 +4,9 @@
This function is in development. Check back soon.
You need to grant All files access in application permissions to use this option.
You need to enable Alarms & Reminders in Android app settings to use this feature.
+
+ Today
+ Yesterday
OK
Open
@@ -37,7 +40,7 @@
On %1$s at lesson(s) %2$s
Room will make up: %1$s
- Settings
+ Settings
Notifications
News schedule in background settings
Configure your news notification settings, include duration, which news is enabled, news filter settings, and more.
@@ -185,4 +188,6 @@
News Subject
Search history
Search %1$s in %2$s
+
+ Account
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 35fb10a..8de17f9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id 'com.android.application' version '8.3.2' apply false
+ id 'com.android.application' version '8.4.0' apply false
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
id 'com.google.dagger.hilt.android' version '2.44' apply false
}