Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c5266be
[CHORE] Typo Fix
doyoonkim3312 Dec 1, 2024
1cc6a8a
[CHORE] Add required string resources
doyoonkim3312 Dec 21, 2024
ac10f78
[FEAT] New feature (Searching Notices) Applied.
doyoonkim3312 Dec 21, 2024
fe1bc15
[CHORE] Add necessary vector resources
doyoonkim3312 Dec 21, 2024
25c8fd1
[REFACT] Change method to display detailed content.
doyoonkim3312 Dec 21, 2024
415b80d
[REFACT] Change Interface structure.
doyoonkim3312 Dec 21, 2024
e04720a
[REFACT] Modify data wrappers.
doyoonkim3312 Dec 21, 2024
bf9a06b
[CHORE] Change version code.
doyoonkim3312 Dec 21, 2024
19bc15a
[CHORE] Update Gradle information and dependency
doyoonkim3312 Jan 4, 2025
797ad15
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
3d20edb
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
07a2fa7
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
802aa56
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
717c623
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
6c23655
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
b19c8ae
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
b0270e3
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
caa9e3f
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
68d0599
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
74510c8
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
a64f54b
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
4395540
[FEAT] Topic Subscription
doyoonkim3312 Jan 4, 2025
1c468dd
Merge pull request #22 from KNUTICE/development
doyoonkim3312 Jan 4, 2025
c0af5a1
Update README.md
doyoonkim3312 Jan 4, 2025
08b6dd9
Merge pull request #23 from KNUTICE/doyoonkim3312-patch-1
doyoonkim3312 Jan 4, 2025
bf50727
Update README.md
doyoonkim3312 Jan 5, 2025
b27aaca
[CHORE] Fix Cosmetic Issue
doyoonkim3312 Jan 20, 2025
8aab9f6
[CHORE] Fix Cosmetic Issue
doyoonkim3312 Jan 20, 2025
89b4aba
[FEAT] Implement Local Database
doyoonkim3312 Jan 20, 2025
89a2708
[FEAT] Implement Local Database
doyoonkim3312 Jan 20, 2025
63e8680
[FEAT] Implement Local Database
doyoonkim3312 Jan 20, 2025
c2e370c
[CHORE] Fix Cosmetic Issue
doyoonkim3312 Jan 20, 2025
458fe39
[CHORE] Fix Cosmetic Issue
doyoonkim3312 Jan 20, 2025
980d377
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
7623405
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
d784511
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
479b038
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
6ff99d3
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
717f005
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
481e24a
[FEAT] Implement Bookmark Feature.
doyoonkim3312 Jan 20, 2025
20d8fbf
[CHORE] Add necessary image assets.
doyoonkim3312 Jan 20, 2025
04a3d69
Merge remote-tracking branch 'origin/main'
doyoonkim3312 Jan 20, 2025
88405b7
Merge pull request #24 from KNUTICE/main
doyoonkim3312 Jan 20, 2025
2787689
[FEAT] Animated Dialog
doyoonkim3312 Jan 22, 2025
3d38b71
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
337225b
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
69f7c0b
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
00382b6
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
dfbc076
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
b9c116c
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
e77821f
[CHORE] TODO task
doyoonkim3312 Feb 23, 2025
f052333
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
1b89f4a
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
81052e3
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
8789271
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
d8a20be
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
f1d245a
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
4cc0f60
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
71ff570
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
8707682
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
f811669
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
6a2d0f1
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
b00e0ce
[FEAT] Bookmark Feature
doyoonkim3312 Feb 23, 2025
35acfb9
[FEAT] Bookmark Feature
doyoonkim3312 Feb 24, 2025
7124b9d
[FEAT] Bookmark Feature
doyoonkim3312 Feb 24, 2025
3ad26fa
[FEAT] Bookmark Feature
doyoonkim3312 Feb 24, 2025
8f5a2f6
[REFACT] Fix identified issue on sending Customer Report
doyoonkim3312 Feb 25, 2025
bc1ee81
[REFACT] Disable Back Button / Swipe-To-Back
doyoonkim3312 Feb 25, 2025
d04308e
[CHORE] Remove unnecessary comments
doyoonkim3312 Feb 25, 2025
13d27b0
[REFACT] Fix LazyColumn Refresh Issue
doyoonkim3312 Feb 26, 2025
f1e38a4
[REFACT] Fix cosmetic issue on BottomNavBar
doyoonkim3312 Mar 2, 2025
5fe41b0
[REFACT] Add information for unsupported feature
doyoonkim3312 Mar 2, 2025
3648594
[REFACT] Add Blank page for List of Bookmarks
doyoonkim3312 Mar 2, 2025
3ce21bc
[CHORE] Add necessary string resources
doyoonkim3312 Mar 3, 2025
d5385f3
[REFACTOR] Resolve compile issue on Github Action
doyoonkim3312 Mar 3, 2025
179c8fd
[REFACTOR] Resolve compile issue on Github Action
doyoonkim3312 Mar 3, 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
14 changes: 7 additions & 7 deletions .github/workflows/GenerateBuildArtifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Generate Build Artifact

on:
pull_request:
branches: ["main", "release"]
branches: ["release"]

jobs:
build:
Expand Down Expand Up @@ -37,10 +37,10 @@ jobs:
run: ./gradlew clean

- name: Build with Gradle
run: ./gradlew
run: ./gradlew build

- name: Generate and upload a Build Artifact
uses: actions/upload-artifact@v3.1.3
with:
name: KNUTICE_RC.apk
path: app/build/outputs/apk/debug/app-debug.apk
# - name: Generate and upload a Build Artifact
# uses: actions/upload-artifact@v3.1.3
# with:
# name: KNUTICE_RC.apk
# path: app/build/outputs/apk/debug/app-debug.apk
40 changes: 0 additions & 40 deletions .github/workflows/ValidateDevelopmentForRelease.yml

This file was deleted.

22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<img src="https://github.com/user-attachments/assets/f1bc12e8-f218-4d58-a7bf-5e8d4c24327b" width="100">
![Banner](https://github.com/user-attachments/assets/67608836-b085-4d6b-9f6f-faa562e20912)
[<img width="380px;" src="https://github.com/user-attachments/assets/e49643e6-3e2b-4a33-97fb-d2f94a8ea91e"/>](https://play.google.com/store/apps/details?id=com.doyoonkim.knutice)

<br>


# 🔔 KNUTICE
- 국립한국교통대학교 공지사항 알리미

Expand Down Expand Up @@ -29,22 +32,23 @@
<br>

# 📱 Preview
<div style="display: flex; justify-content: center; margin-bottom: 10px;">

<img width="190" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/5f6568fc-b839-4704-96d7-f893d18600c6">

<img width="190" alt="스크린샷 2024-08-15 23 52 56" src="https://github.com/user-attachments/assets/070ee2c6-420f-416a-9395-4837b4c5c009">

<img width="190" alt="스크린샷 2024-08-15 23 53 12" src="https://github.com/user-attachments/assets/40e37308-ac29-4b69-b065-2184591f7375">

<div style="display: flex; overflow-x: auto; justify-content: center; margin-bottom: 10px;">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/5ba32b68-0103-4609-83e0-20cc1a4d58f3">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/3b8021c6-74f5-40a4-a1e7-447f2773a62f">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/e800a5eb-7ea8-4431-ad3e-0cdfd74c8b3f">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/64a89caa-8ed2-41a4-9128-18870bc93e90">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/d9cb1e37-67b1-484a-bf29-ae446f79a469">
<img width="180" alt="스크린샷 2024-08-15 23 51 59" src="https://github.com/user-attachments/assets/faa05f29-d41d-4def-b483-ed0655f1c116">
</div>

<br>

# 🧐 What I learned
- Jetpack Compose를 이용하여 UI 설계/구현하는 방법, Jetpack Compose로 구현한 UI의 생명주기 관리등과 더불어 실제 클라이언트에 Jetpack Compose를 효율적으로 접목시키는 방법에 대해 알게 되었어요.
- Kotlin Flow를 활용하여 MVVM 아키텍쳐를 준수하며 각 레이어를 이어주는 데이터 파이프라인 구축에 대 자세히 알게 되었어요.
> snapshotFlow를 통하여 지속되는 데이터 입력을 요구 조건에 맞게 처리하는 방법에 대해 알게 되었어요.
- Dagger Hilt를 사용한 의존성 주입을 실제 클라이언트에 적용해 보면서 의존성 주입 기법이 가진 장점들을 몸소 경험할 수 있었어요.
- Kotlin Coroutine을 활용하여 기기에 부담이 되는 작업(외부 저장소에서 데이터 획득 등)을 효율적으로 비동기 처리하는 방법에 대해 자세히 알게 되었어요.
- Jetpack Compose Navigaton을 활용하여 싱글 엑티비티에서 다양한 Composable 간의 전환 및 데이터 이동을 가능하게 하는 방법에 대해 알게 되었어요.
- Jetpack Datastore를 사용하여 사용자 설정과 같은 작은 데이터를 보관하는 로컬 스토리지의 사용법과 활용에 대해 더 자세히 알게 되었어요.
- GitHub Action를 사용한 CI기능을 구현해 볼 수 있었어요.
23 changes: 21 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ plugins {
alias(libs.plugins.google.gms.google.services)

alias(libs.plugins.kotlinSerialization)

// KSP Plugin for Room Database
// id("com.google.devtools.ksp")
}

android {
Expand All @@ -26,15 +29,21 @@ android {
applicationId = "com.doyoonkim.knutice"
minSdk = 29
targetSdk = 34
versionCode = 5
versionName = "1.1.0"
versionCode = 9
versionName = "1.2.0.01"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}

buildConfigField("String", "API_ROOT", "\"$apiRoot\"")

javaCompileOptions {
annotationProcessorOptions {
arguments["room.schemaLocation"] = "$projectDir/schemas"
}
}
}

buildTypes {
Expand Down Expand Up @@ -80,6 +89,7 @@ dependencies {
implementation(libs.androidx.material)
implementation(libs.firebase.messaging)
implementation(libs.firebase.messaging.directboot)
implementation(libs.androidx.junit.ktx)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test) // Library to test coroutines in JUnit
androidTestImplementation(libs.androidx.junit)
Expand Down Expand Up @@ -110,6 +120,15 @@ dependencies {
// Jsoup HTML Parser Library
implementation(libs.jsoup)

// DataStore
implementation (libs.androidx.datastore.preferences)

// Room Database
implementation(libs.androidx.room.runtime)
kapt(libs.androidx.room.compiler)
// Room Database - Kotlin Extensions and Coroutine Support
implementation(libs.androidx.room.ktx)

}

// Allow references to generated code
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
Expand Down
17 changes: 10 additions & 7 deletions app/src/main/java/com/doyoonkim/knutice/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.os.Build
import androidx.core.content.getSystemService
import com.doyoonkim.knutice.fcm.PushNotificationHandler
import com.doyoonkim.knutice.R
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject

Expand All @@ -16,21 +14,26 @@ class MainApplication() : Application() {

override fun onCreate() {
super.onCreate()
createNotificationChannel()
// Create channel group
(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).run {
createNotificationChannel(
getString(R.string.inapp_notification_channel_id),
getString(R.string.inapp_notificaiton_channel_name),
getString(R.string.inapp_notification_channel_description)
)
}
notificationHandler.requestCurrentToken()
}

override fun onTerminate() {
super.onTerminate()
}

private fun createNotificationChannel() {
private fun createNotificationChannel(id: String, name: String, description: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = getString(R.string.inapp_notificaiton_channel_name)
val description = getString(R.string.inapp_notification_channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(
getString(R.string.inapp_notification_channel_id),
id,
name,
importance
).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import com.doyoonkim.knutice.model.TopThreeNotices
import com.doyoonkim.knutice.model.ApiPostResult
import com.doyoonkim.knutice.BuildConfig
import com.doyoonkim.knutice.model.ApiReportRequest
import com.doyoonkim.knutice.model.ApiTopicSubscriptionRequest
import com.doyoonkim.knutice.model.ManageTopicRequest
import com.doyoonkim.knutice.model.ReportRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import org.jetbrains.annotations.TestOnly
import org.jsoup.Jsoup
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
Expand Down Expand Up @@ -54,6 +55,11 @@ class KnuticeRemoteSource @Inject constructor() {
}
}

suspend fun queryNoticesByKeyword(keyword: String): NoticesPerPage {
Log.d("KnuticeRemoteSource", "Start retrofit service (Querying Notices...)")
return knuticeService.create(KnuticeService::class.java).queryNoticeByKeyword(keyword)
}

suspend fun getFullNoticeContent(url: String): Deferred<String> =
CoroutineScope(Dispatchers.IO).async {
Jsoup.connect(url)
Expand Down Expand Up @@ -103,6 +109,28 @@ class KnuticeRemoteSource @Inject constructor() {
}
}

suspend fun submitTopicSubscriptionPreference(topic: NoticeCategory, status: Boolean): Result<Boolean> {
Log.d("KnuticeRemoteSource", "Update Topic Subscription Preference")
try {
knuticeService.create(KnuticeService::class.java).submitTopicSubscriptionPreference(
ApiTopicSubscriptionRequest(
body = ManageTopicRequest(validatedToken, topic.name, status)
)
).run {
if (this.result?.resultCode == 200) {
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}")
return Result.success(false)
}
}
} catch (e: Exception) {
Log.d("KnuticeServer", "Failed to submit user report. \nREASON: ${e.message}")
return Result.failure(e)
}
}

}

interface KnuticeService {
Expand All @@ -127,6 +155,11 @@ interface KnuticeService {
@Query("noticeName") category: NoticeCategory
): NoticesPerPage

@GET("/open-api/search")
suspend fun queryNoticeByKeyword(
@Query("keyword") keyword: String
): NoticesPerPage

@Headers("Content-Type: application/json")
@POST("/open-api/token")
suspend fun validateToken(
Expand All @@ -139,4 +172,10 @@ interface KnuticeService {
@Body requestBody: ApiReportRequest
): ApiPostResult

@Headers("Content-Type: application/json")
@POST("/open-api/token/topic")
suspend fun submitTopicSubscriptionPreference(
@Body requestBody: ApiTopicSubscriptionRequest
): ApiPostResult

}
Loading
Loading