Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
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.

6 changes: 6 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ android {
}

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

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

buildTypes {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
package com.doyoonkim.knutice.data

import android.content.Context
import androidx.annotation.WorkerThread
import com.doyoonkim.knutice.data.local.KnuticeLocalSource
import com.doyoonkim.knutice.data.local.LocalDatabase
import com.doyoonkim.knutice.domain.NoticeDummySource
import com.doyoonkim.knutice.model.Bookmark
import com.doyoonkim.knutice.model.Notice
import com.doyoonkim.knutice.model.NoticeCategory
import com.doyoonkim.knutice.model.NoticeEntity
import com.doyoonkim.knutice.model.NoticesPerPage
import com.doyoonkim.knutice.model.TopThreeNotices
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ActivityRetainedScoped
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject
Expand All @@ -34,8 +28,12 @@ class NoticeLocalRepository @Inject constructor(
private val localSource: KnuticeLocalSource
) {
// Local
fun createBookmark(bookmark: Bookmark) {
localSource.createBookmark(bookmark)
fun createBookmark(bookmark: Bookmark): Result<Boolean> {
return localSource.createBookmark(bookmark)
}

fun createBookmark(bookmark: Bookmark, targetNotice: Notice): Result<Boolean> {
return localSource.createBookmark(bookmark, targetNotice)
}

fun updateBookmark(bookmark: Bookmark) {
Expand All @@ -46,19 +44,29 @@ class NoticeLocalRepository @Inject constructor(
localSource.deleteBookmark(bookmark)
}

fun getAllBookmarks(): Flow<List<Bookmark>> {
fun deleteNoticeEntity(entity: NoticeEntity) {
localSource.deleteNoticeEntity(entity)
}

fun getAllBookmarks(): Flow<Bookmark> {
return flow {
localSource.getAllBookmarks().fold(
onSuccess = {
emit(it)
},
onFailure = {
emit(emptyList())
}
)
runCatching {
localSource.getAllBookmarks().forEach { emit(it) }
}.onFailure { emit(Bookmark(-1)) }
}
}

fun getNoticeByNttId(nttId: Int): Notice {
val noticeEntity = localSource.getNoticeByNttId(nttId)
return noticeEntity.toNotice()
}

fun getBookmarkByNttID(nttId: Int): Result<Bookmark> {
return runCatching {
localSource.getBookmarkByNttId(nttId) ?: Bookmark(-1)
}.onFailure { throw it }
}

// Remote
@WorkerThread
fun getTopThreeNotice(category: NoticeCategory): Flow<NoticesPerPage> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package com.doyoonkim.knutice.data.local

import android.content.Context
import com.doyoonkim.knutice.model.Bookmark
import com.doyoonkim.knutice.model.Notice
import com.doyoonkim.knutice.model.NoticeEntity
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject


Expand All @@ -25,24 +26,47 @@ class KnuticeLocalSource @Inject constructor(
}
}

fun updateBookmark(bookmark: Bookmark): Result<Boolean> {
fun createBookmark(bookmark: Bookmark, targetNotice: Notice): Result<Boolean> {
return runCatching {
localDatabase.getDao().updateBookmark(bookmark)
// Insert Notice First.
localDatabase.getDao().createNoticeEntity(targetNotice.toNoticeEntity())
// Insert Bookmark Entity
localDatabase.getDao().createBookmark(bookmark)
true
}.onFailure { throw it }
}

fun getAllBookmarks(): Result<List<Bookmark>> {
fun updateBookmark(bookmark: Bookmark): Result<Boolean> {
return runCatching {
localDatabase.getDao().getAllBookmarks()
localDatabase.getDao().updateBookmark(bookmark)
true
}.onFailure { throw it }
}

fun getAllBookmarks(): List<Bookmark> {
return localDatabase.getDao().getAllBookmarks()
}

fun deleteBookmark(bookmark: Bookmark): Result<Boolean> {
return runCatching {
localDatabase.getDao().deleteBookmark(bookmark)
true
}.onFailure { throw it }
}

fun deleteNoticeEntity(entity: NoticeEntity): Result<Boolean> {
return runCatching {
localDatabase.getDao().deleteNoticeEntity(entity)
true
}.onFailure { throw it }
}

fun getNoticeByNttId(nttId: Int): NoticeEntity {
return localDatabase.getDao().getNoticeByNttId(nttId)
}

fun getBookmarkByNttId(nttId: Int): Bookmark? {
return localDatabase.getDao().getBookmarkByNttId(nttId)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.doyoonkim.knutice.model.Bookmark
import com.doyoonkim.knutice.model.NoticeEntity

@Dao
interface MainDatabaseDao {
Expand All @@ -16,9 +17,22 @@ interface MainDatabaseDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun createBookmark(entity: Bookmark)

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun createNoticeEntity(entity: NoticeEntity)

@Update
fun updateBookmark(updated: Bookmark)

@Delete
fun deleteBookmark(target: Bookmark)

@Delete
fun deleteNoticeEntity(target: NoticeEntity)

@Query("SELECT * FROM NoticeEntity WHERE ntt_id=:nttId")
fun getNoticeByNttId(nttId: Int): NoticeEntity

@Query("SELECT * FROM Bookmark WHERE target_ntt_id=:nttId")
fun getBookmarkByNttId(nttId: Int): Bookmark?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.doyoonkim.knutice.domain

import com.doyoonkim.knutice.data.NoticeLocalRepository
import com.doyoonkim.knutice.model.Bookmark
import com.doyoonkim.knutice.model.Notice
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class FetchBookmarkFromDatabase @Inject constructor(
private val repository: NoticeLocalRepository
) {

fun getAllBookmarkWithNotices(): Flow<Pair<Bookmark, Notice>> {
return repository.getAllBookmarks().map {
Pair(it, repository.getNoticeByNttId(it.nttId))
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class FetchTopThreeNoticeByCategory @Inject constructor (
private fun ArrayList<RawNoticeData>.toNotice(): List<Notice> {
return List<Notice>(3) { index ->
Notice(
nttId = this[index].nttId ?: -1,
title = this[index].title ?: "Unknown",
url = this[index].contentUrl ?: "Unknown",
departName = this[index].departName ?: "Unknown",
Expand Down
38 changes: 36 additions & 2 deletions app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.doyoonkim.knutice.model

import androidx.room.Entity
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable


data class Result(
Expand Down Expand Up @@ -81,14 +82,36 @@ data class ManageTopicRequest(

// Data class to be applied to uiState.
// Universal
@Serializable
data class Notice(
val nttId: Int = -1,
val title: String = "Unknown",
val url: String = "Unknown",
val imageUrl: String = "",
val departName: String = "Unknown",
val timestamp: String = "Unknown"
)
) {
fun toFullContent(): FullContent {
return FullContent(
title,
"[$departName] $timestamp",
url,
imageUrl
)
}

fun toNoticeEntity(): NoticeEntity {
return NoticeEntity(
noticeEntityId = 0,
nttId = nttId,
title = title,
url = url,
imageUrl = imageUrl,
departName = departName,
timestamp = timestamp
)
}
}

// DetailedNoticeContent
data class DetailedContentState(
Expand All @@ -105,6 +128,7 @@ data class DetailedContentState(
data class CustomerServiceReportState(
val userReport: String = "",
val reachedMaxCharacters: Boolean = false,
val exceedMinCharacters: Boolean = false,
val isSubmissionFailed: Boolean = false,
val isSubmissionCompleted: Boolean = false
)
Expand All @@ -125,8 +149,18 @@ data class NotificationPreferenceStatus(

// BookmarkComposable
data class BookmarkComposableState(
val bookmarks: List<Bookmark> = emptyList(),
val bookmarks: List<Pair<Bookmark, Notice>> = emptyList(),
val isRefreshing: Boolean = false,
val isRefreshRequested: Boolean = false
)

// EditBookmark
data class EditBookmarkState(
val bookmarkId: Int = 0,
val targetNotice: Notice = Notice(),
val isReminderRequested: Boolean = false,
val timeForRemind: Long = 0, // Should be replaced with an appropriate data type later.
val bookmarkNote: String = "",
val requireCreation: Boolean = true
)

16 changes: 10 additions & 6 deletions app/src/main/java/com/doyoonkim/knutice/model/RoomEntities.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ import androidx.room.PrimaryKey

@Entity
data class NoticeEntity(
@PrimaryKey(autoGenerate = true) val id: Int,
@PrimaryKey(autoGenerate = true) val noticeEntityId: Int,
@ColumnInfo("ntt_id") val nttId: Int = -1,
@ColumnInfo("notice_title") val title: String,
@ColumnInfo("notice_url") val url: String,
@ColumnInfo("notice_image") val imageUrl: String,
@ColumnInfo("info_dept") val departName: String,
@ColumnInfo("info_timestamp") val timestamp: String
)
) {
fun toNotice(): Notice {
return Notice(nttId, title, url, imageUrl, departName, timestamp)
}
}

@Entity
data class Bookmark(
@PrimaryKey(autoGenerate = true) val bookmarkId: Int,
@ColumnInfo("bookmarked_notice") val noticeNttId: String,
@ColumnInfo("isScheduled") val isScheduled: Boolean,
@ColumnInfo("remind_schedule") val reminderSchedule: String,
@ColumnInfo("bookmark_note") val note: String
@ColumnInfo("isScheduled") val isScheduled: Boolean = false,
@ColumnInfo("remind_schedule") val reminderSchedule: Long = 0,
@ColumnInfo("bookmark_note") val note: String = "",
@ColumnInfo("target_ntt_id") val nttId: Int = -1
)

/*
Expand Down
Loading
Loading