diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 74a7fc08..74eedd49 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,21 +23,21 @@ android { val properties = Properties().apply { load(FileInputStream("${rootDir}/local.properties")) } - val apiRoot = properties["api_root"] ?: "" + val apiMigrated = properties["api_migrated"] ?: "" defaultConfig { applicationId = "com.doyoonkim.knutice" minSdk = 31 targetSdk = 34 - versionCode = 11 - versionName = "1.3.2" + versionCode = 13 + versionName = "1.3.3" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } - buildConfigField("String", "API_ROOT", "\"$apiRoot\"") + buildConfigField("String", "API_MIGRATED", "\"$apiMigrated\"") javaCompileOptions { annotationProcessorOptions { @@ -131,7 +131,7 @@ dependencies { implementation(libs.androidx.room.ktx) // Translation -// implementation(libs.translate) + implementation(libs.translate) } diff --git a/app/src/main/java/com/doyoonkim/knutice/data/KnuticeRemoteSource.kt b/app/src/main/java/com/doyoonkim/knutice/data/KnuticeRemoteSource.kt index a921f68f..f7cfc2b0 100644 --- a/app/src/main/java/com/doyoonkim/knutice/data/KnuticeRemoteSource.kt +++ b/app/src/main/java/com/doyoonkim/knutice/data/KnuticeRemoteSource.kt @@ -31,7 +31,7 @@ import javax.inject.Singleton class KnuticeRemoteSource @Inject constructor() { private val knuticeService = Retrofit.Builder() - .baseUrl(BuildConfig.API_ROOT) + .baseUrl(BuildConfig.API_MIGRATED) .addConverterFactory(GsonConverterFactory.create()) .build() @@ -93,13 +93,13 @@ class KnuticeRemoteSource @Inject constructor() { Log.d("KnuticeRemoteSource", "ValidatedToken: $validatedToken") try { knuticeService.create(KnuticeService::class.java).submitUserReport( - ApiReportRequest(body = report.copy(token = validatedToken)) + ApiReportRequest(body = report.copy(fcmToken = validatedToken)) ).run { if (this.result?.resultCode == 200) { - Log.d("KnuticeServer", "User report has been submitted successfully.\n${this.body?.message}") + Log.d("KnuticeServer", "User report has been submitted successfully.\n${this.body}") return Result.success(true) } else { - Log.d("KnuticeServer", "Failed to submit user report\n${this.body?.message}") + Log.d("KnuticeServer", "Failed to submit user report\n${this.body ?: false}") return Result.success(false) } } @@ -121,7 +121,7 @@ class KnuticeRemoteSource @Inject constructor() { Log.d("KnuticeServer", "Topic preference has been updated.\n${this.body}") return Result.success(true) } else { - Log.d("KnuticeServer", "Failed to update topic preference.\n${this.body?.message}") + Log.d("KnuticeServer", "Failed to update topic preference.\n${this.body ?: false}") return Result.success(false) } } @@ -135,9 +135,6 @@ class KnuticeRemoteSource @Inject constructor() { interface KnuticeService { - @GET("/open-api/notice") - suspend fun getTopThreeNotice(): TopThreeNotices - @GET("/open-api/notice/list") suspend fun getTopThreeNotice( @Query("noticeName") category: NoticeCategory, @@ -161,7 +158,7 @@ interface KnuticeService { ): NoticesPerPage @Headers("Content-Type: application/json") - @POST("/open-api/token") + @POST("/open-api/fcm") suspend fun validateToken( @Body requestBody: ApiDeviceTokenRequest ): ApiPostResult @@ -173,7 +170,7 @@ interface KnuticeService { ): ApiPostResult @Headers("Content-Type: application/json") - @POST("/open-api/token/topic") + @POST("/open-api/topic") suspend fun submitTopicSubscriptionPreference( @Body requestBody: ApiTopicSubscriptionRequest ): ApiPostResult diff --git a/app/src/main/java/com/doyoonkim/knutice/domain/FetchTopThreeNoticeByCategory.kt b/app/src/main/java/com/doyoonkim/knutice/domain/FetchTopThreeNoticeByCategory.kt index c55e4689..3ebb3c2f 100644 --- a/app/src/main/java/com/doyoonkim/knutice/domain/FetchTopThreeNoticeByCategory.kt +++ b/app/src/main/java/com/doyoonkim/knutice/domain/FetchTopThreeNoticeByCategory.kt @@ -1,5 +1,6 @@ package com.doyoonkim.knutice.domain +import android.util.Log import com.doyoonkim.knutice.data.NoticeLocalRepository import com.doyoonkim.knutice.model.Notice import com.doyoonkim.knutice.model.NoticeCategory @@ -7,6 +8,7 @@ import com.doyoonkim.knutice.model.RawNoticeData import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map +import java.util.Locale import javax.inject.Inject @@ -35,15 +37,17 @@ class FetchTopThreeNoticeByCategory @Inject constructor ( } fun getTopThreeNotices(category: NoticeCategory): Flow { + val translateNeeded: Boolean = Locale.getDefault() != Locale.KOREAN return repository.getTopThreeNotice(category).map { if (it.body.isNotEmpty()) { val result = it.body.toNotice() + TopThreeInCategory( isSuccessful = true, notice1 = result[0], notice2 = result[1], notice3 = result[2] - ) + ).also { Log.d("TEST", it.toString()) } } else { TopThreeInCategory( isSuccessful = false diff --git a/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt b/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt index 6361a2d2..475839ab 100644 --- a/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt +++ b/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt @@ -1,6 +1,5 @@ package com.doyoonkim.knutice.model -import androidx.room.Entity import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable @@ -16,8 +15,9 @@ data class RawNoticeData( @SerializedName("title") var title: String? = null, @SerializedName("contentUrl") var contentUrl: String? = null, @SerializedName("contentImage") var contentImage: String? = null, - @SerializedName("departName") var departName: String? = null, - @SerializedName("registeredAt") var registeredAt: String? = null + @SerializedName("departmentName") var departName: String? = null, + @SerializedName("registeredAt") var registeredAt: String? = null, + @SerializedName("noticeName") var noticeCategory: String? = null ) // POJO for receiving raw data from the server. @@ -40,12 +40,8 @@ data class NoticesPerPage( data class ApiPostResult( @SerializedName("result") var result: Result? = Result(), - @SerializedName("body") var body: Body? = Body() -) { - data class Body( - val message: String = "" - ) -} + @SerializedName("body") var body: Boolean? = null +) data class ApiDeviceTokenRequest( val result: Result = Result(), @@ -53,7 +49,7 @@ data class ApiDeviceTokenRequest( ) data class DeviceTokenRequest( - val deviceToken: String + val fcmToken: String ) data class ApiReportRequest( @@ -62,7 +58,7 @@ data class ApiReportRequest( ) data class ReportRequest( - val token: String = "", + val fcmToken: String = "", val content: String = "", val clientType: String = "APP", val deviceName: String = "", @@ -75,7 +71,7 @@ data class ApiTopicSubscriptionRequest( ) data class ManageTopicRequest( - val deviceToken: String = "", + val fcmToken: String = "", val noticeName: String = "", val isSubscribed: Boolean = false ) diff --git a/app/src/main/java/com/doyoonkim/knutice/presentation/CategorizedNoficiation.kt b/app/src/main/java/com/doyoonkim/knutice/presentation/CategorizedNoficiation.kt index 255f8167..0908acd1 100644 --- a/app/src/main/java/com/doyoonkim/knutice/presentation/CategorizedNoficiation.kt +++ b/app/src/main/java/com/doyoonkim/knutice/presentation/CategorizedNoficiation.kt @@ -1,6 +1,7 @@ package com.doyoonkim.knutice.presentation import android.content.res.Configuration +import android.util.Log import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -9,10 +10,8 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -38,7 +37,6 @@ import com.doyoonkim.knutice.ui.theme.notificationType4 import com.doyoonkim.knutice.ui.theme.subTitle import com.doyoonkim.knutice.viewModel.CategorizedNotificationViewModel import com.doyoonkim.knutice.R -import com.doyoonkim.knutice.model.FullContent @Composable fun CategorizedNotification( diff --git a/app/src/main/java/com/doyoonkim/knutice/presentation/MainActivity.kt b/app/src/main/java/com/doyoonkim/knutice/presentation/MainActivity.kt index e65de7e4..8b10b250 100644 --- a/app/src/main/java/com/doyoonkim/knutice/presentation/MainActivity.kt +++ b/app/src/main/java/com/doyoonkim/knutice/presentation/MainActivity.kt @@ -32,6 +32,7 @@ import com.doyoonkim.knutice.alarm.NotificationAlarmScheduler import com.doyoonkim.knutice.presentation.component.PermissionRationaleComposable import com.doyoonkim.knutice.ui.theme.KNUTICETheme import dagger.hilt.android.AndroidEntryPoint +import java.util.Locale @AndroidEntryPoint class MainActivity : ComponentActivity() { diff --git a/app/src/main/java/com/doyoonkim/knutice/presentation/MainServiceScreen.kt b/app/src/main/java/com/doyoonkim/knutice/presentation/MainServiceScreen.kt index 63157929..42ce2862 100644 --- a/app/src/main/java/com/doyoonkim/knutice/presentation/MainServiceScreen.kt +++ b/app/src/main/java/com/doyoonkim/knutice/presentation/MainServiceScreen.kt @@ -66,6 +66,13 @@ fun MainServiceScreen( val mainAppState by viewModel.uiState.collectAsState() val navController = rememberNavController() +// //TODO Live translation feature (TBD) +// var showLanguageDownloadRationale by remember { mutableStateOf(false) } +// LaunchedEffect(Unit) { +// if (Locale.getDefault() != Locale.KOREAN) { +// showLanguageDownloadRationale = true +// } +// } LaunchedEffect(mainAppState.scheduleTriggered) { Log.d("MainServiceScreen", "Triggered") @@ -277,5 +284,27 @@ fun MainServiceScreen( ) .background(MaterialTheme.colorScheme.displayBackground) ) + + //TODO Live Translation Feature (TBD) +// AnimatedVisibility( +// visible = showLanguageDownloadRationale, +// enter = scaleIn(), +// exit = scaleOut() +// ) { +// Box( +// modifier = Modifier.fillMaxSize() +// .clickable { showLanguageDownloadRationale = false } +// ) { +// PermissionRationaleComposable( +// modifier = Modifier.align(Alignment.Center).padding(start = 20.dp, end = 20.dp), +// permissionName = stringResource(R.string.text_language), +// rationaleTitle = stringResource(R.string.title_langauge_model_download), +// description = stringResource(R.string.description_language_model_download) +// ) { +// viewModel.requestModelDownload() +// showLanguageDownloadRationale = true +// } +// } +// } } } \ No newline at end of file diff --git a/app/src/main/java/com/doyoonkim/knutice/viewModel/CategorizedNotificationViewModel.kt b/app/src/main/java/com/doyoonkim/knutice/viewModel/CategorizedNotificationViewModel.kt index 9e0c0aac..e8c7367f 100644 --- a/app/src/main/java/com/doyoonkim/knutice/viewModel/CategorizedNotificationViewModel.kt +++ b/app/src/main/java/com/doyoonkim/knutice/viewModel/CategorizedNotificationViewModel.kt @@ -8,6 +8,7 @@ import com.doyoonkim.knutice.model.Notice import com.doyoonkim.knutice.model.NoticeCategory import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -62,9 +63,12 @@ class CategorizedNotificationViewModel @Inject constructor( onSuccess = { val notices = listOf(it.notice1!!, it.notice2!!, it.notice3!!) when(category) { - NoticeCategory.GENERAL_NEWS -> updateState( - updatedNotificationGeneral = notices - ) + NoticeCategory.GENERAL_NEWS -> { + + updateState( + updatedNotificationGeneral = notices + ) + } NoticeCategory.ACADEMIC_NEWS -> updateState( updatedNotificationAcademic = notices ) @@ -83,6 +87,7 @@ class CategorizedNotificationViewModel @Inject constructor( ) } } + } data class CategorizedNotificationState( diff --git a/app/src/main/java/com/doyoonkim/knutice/viewModel/MainServiceViewModel.kt b/app/src/main/java/com/doyoonkim/knutice/viewModel/MainServiceViewModel.kt index 7a3a01f8..4a7fca64 100644 --- a/app/src/main/java/com/doyoonkim/knutice/viewModel/MainServiceViewModel.kt +++ b/app/src/main/java/com/doyoonkim/knutice/viewModel/MainServiceViewModel.kt @@ -34,6 +34,14 @@ class MainServiceViewModel @Inject constructor() : ViewModel() { ) } } + + fun updateLanguageModelDownloadStatus(newStatus: String) { + _uiState.update { + it.copy( + languageModelDownloadResult = newStatus + ) + } + } } data class MainServiceState( @@ -42,5 +50,6 @@ data class MainServiceState( val isBottomNavBarVisible: Boolean = false, val tempReserveNoticeForBookmark: Notice = Notice(), // ? val currentTargetBookmark: Bookmark = Bookmark(-1), - val scheduleTriggered: Boolean = false + val scheduleTriggered: Boolean = false, + val languageModelDownloadResult: String = "YET_STARTED" ) \ 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 23b5f713..9fda8c4c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,7 +11,7 @@ About Version Open Source License - 1.3.2 + 1.3.3 Notification Preference New Notice has been delivered! diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 52eeb39c..15f2e82e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,6 +31,7 @@ firebaseMessaging = "24.0.2" kotlinSerialization = "1.6.0" junitKtx = "1.2.1" protoliteWellKnownTypes = "18.0.0" +translate = "17.0.3" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -72,6 +73,7 @@ firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref="kotlinSerialization" } androidx-junit-ktx = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "junitKtx" } protolite-well-known-types = { group = "com.google.firebase", name = "protolite-well-known-types", version.ref = "protoliteWellKnownTypes" } +translate = { module = "com.google.mlkit:translate", version.ref = "translate" } [plugins]