Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Update] Weekly9 과제 제출 #100

Merged
merged 24 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b76a83d
Refactor: NotetakingActivity 코드 리팩토링
aengzu Oct 24, 2024
7a74847
Feat: 녹음 버튼 클릭 시 토스트 메시지 (녹음 시작, 녹음 종료) 띄우기
aengzu Oct 24, 2024
8941e6a
Chore: Manifest 에 Record 권한 추가
aengzu Oct 24, 2024
83cb7df
Feat: 녹음 버튼 클릭 시 녹음 시작 및 종료(#62)
aengzu Oct 24, 2024
ec4bbdd
Feat: 서버에 녹음 파일 저장 Usecase 정의
aengzu Oct 25, 2024
d5bbb56
Feat: 페이지 이동 이벤트 유스케이스 정의
aengzu Oct 25, 2024
37dc8dc
Feat: Page이동 이벤트 Room 생성
aengzu Oct 25, 2024
d86cd75
Feat: 녹음 도중 페이지 이동 이벤트 파일에 기록
aengzu Oct 26, 2024
11fa159
Feat: 녹음 기능 구현(#62)
aengzu Oct 27, 2024
2246da1
Merge pull request #88 from aengzu/feature/record
aengzu Oct 27, 2024
1ccead1
Design : 즐겨찾기 화면 제작
Kjamm Oct 28, 2024
46e3b47
Merge pull request #94 from Kjamm/design/favorites
aengzu Oct 29, 2024
e7f80d6
Refactor: AuthInterceptor 에서 토큰 얻어올때 SharedPreferencesHelper 로 변경
aengzu Oct 30, 2024
31c93ff
Refactor: html 포매팅 시 parseAsHtml 사용
aengzu Oct 30, 2024
3fe63a5
Refactor: AIRepositoryImpl 에서 Dispatcher.IO 제거, API 리턴 타입 Result 제거
aengzu Oct 30, 2024
2e7f00a
Refactor: RoomDB 사용으로 변경
aengzu Oct 30, 2024
c45e42a
Refactor: 녹음 상태 전달 시 SharedViewModel 사용
aengzu Oct 30, 2024
926fbf2
Design: 텍스트 편집 모드 아이콘 추가
aengzu Oct 31, 2024
eae9ebd
Merge pull request #95 from aengzu/Refactor/feedback
aengzu Nov 1, 2024
4ee5fe0
Design: 텍스트 버튼 클릭 시 텍스트 편집 바 표시
aengzu Nov 1, 2024
67b85e9
Feat: Annotation 관련 Room 생성
aengzu Nov 1, 2024
95e4070
Feat: 주석 추가 화면에 띄우기 정도로만 구현
aengzu Nov 1, 2024
34a6971
Merge pull request #98 from aengzu/feature/annotation
aengzu Nov 1, 2024
51ab194
Merge pull request #99 from kakao-tech-campus-2nd-step3/Weekly9
aengzu Nov 1, 2024
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
15 changes: 14 additions & 1 deletion .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions core/data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ dependencies {
implementation(libs.retrofit.core)
implementation(libs.retrofit.kotlin.serialization)
implementation(libs.retrofit.gson)
implementation(libs.room.ktx)
kapt(libs.room.compiler)
implementation(libs.room.runtime)
implementation(libs.room.ktx)
implementation(libs.coroutines.android)
implementation(projects.core.domain) // domain 에 있는 걸 구현하므로
kapt(libs.room.compiler)
implementation(projects.core.domain)
implementation(libs.okhttp.logging)
}

Expand Down
5 changes: 3 additions & 2 deletions core/data/src/main/java/com/iguana/data/di/AuthInterceptor.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.iguana.data.di

import com.iguana.domain.repository.SharedPreferencesHelper
import okhttp3.Interceptor
import okhttp3.Response

class AuthInterceptor(private val tokenProvider: () -> String) : Interceptor {
class AuthInterceptor(private val sharedPreference: SharedPreferencesHelper) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val token = tokenProvider()
val token = sharedPreference.getAccessToken()
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
Expand Down
20 changes: 20 additions & 0 deletions core/data/src/main/java/com/iguana/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.iguana.data.di

import android.content.Context
import androidx.room.Room
import com.iguana.data.local.dao.AnnotationDao
import com.iguana.data.local.dao.RecentFileDao
import com.iguana.data.local.db.AppDatabase
import com.iguana.domain.repository.SharedPreferencesHelper
import com.iguana.data.local.db.SharedPreferencesHelperImpl
import com.iguana.data.local.dao.PageTurnEventDao
import com.iguana.data.local.files.FileHelperImpl
import com.iguana.domain.utils.FileHelper
import dagger.Binds
Expand All @@ -14,6 +16,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import java.io.File
import javax.inject.Singleton

@Module
Expand Down Expand Up @@ -48,5 +51,22 @@ abstract class DataModule {
fun provideRecentFileDao(appDatabase: AppDatabase): RecentFileDao {
return appDatabase.recentFileDao()
}

@Provides
fun providePageTurnEventDao(appDatabase: AppDatabase): PageTurnEventDao {
return appDatabase.pageTurnEventDao()
}

@Provides
fun provideAnnotationDao(appDatabase: AppDatabase): AnnotationDao {
return appDatabase.annotationDao()
}

@Provides
@Singleton
fun provideBaseDir(@ApplicationContext context: Context): File {
// 앱의 내부 파일 디렉토리를 기본 디렉토리로 사용
return context.filesDir
}
}
}
9 changes: 8 additions & 1 deletion core/data/src/main/java/com/iguana/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.iguana.data.di
import com.iguana.data.BuildConfig
import com.iguana.data.remote.api.AnnotationApi
import com.iguana.data.remote.api.DocumentApi
import com.iguana.data.remote.api.RecordApi
import com.iguana.data.remote.api.SummarizeApi
import com.iguana.domain.repository.SharedPreferencesHelper
import dagger.Module
Expand All @@ -22,7 +23,7 @@ object NetworkModule {
@Singleton
fun provideOkHttpClient(sharedPreferencesHelper: SharedPreferencesHelper): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(AuthInterceptor { sharedPreferencesHelper.getAccessToken() ?: "" })
.addInterceptor(AuthInterceptor(sharedPreferencesHelper))
.build()
}

Expand Down Expand Up @@ -59,4 +60,10 @@ object NetworkModule {
fun provideSummarizeApi(retrofit: Retrofit): SummarizeApi {
return retrofit.create(SummarizeApi::class.java)
}

@Provides
@Singleton
fun provideRecordApi(retrofit: Retrofit): RecordApi {
return retrofit.create(RecordApi::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import com.iguana.data.repository.AnnotationRepositoryImpl
import com.iguana.data.repository.DocumentsRepositoryImpl
import com.iguana.data.repository.LoginRepositoryImpl
import com.iguana.data.repository.RecentFileRepositoryImpl
import com.iguana.data.repository.RecordRepositoryImpl
import com.iguana.domain.repository.AIRepository
import com.iguana.domain.repository.AnnotationRepository
import com.iguana.domain.repository.DocumentsRepository
import com.iguana.domain.repository.LoginRepository
import com.iguana.domain.repository.RecentFileRepository
import com.iguana.domain.repository.RecordRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -48,4 +50,11 @@ abstract class RepositoryModule {
abstract fun bindAIRepository(
aiRepositoryImpl: AIRepositoryImpl
): AIRepository

@Binds
@Singleton
abstract fun bindRecordingRepository(
recordRepositoryImpl: RecordRepositoryImpl
): RecordRepository

}
28 changes: 28 additions & 0 deletions core/data/src/main/java/com/iguana/data/local/dao/AnnotationDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.iguana.data.local.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.iguana.data.local.entity.AnnotationEntity

@Dao
interface AnnotationDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAnnotation(annotation: AnnotationEntity)

@Query("SELECT * FROM annotations WHERE documentId = :documentId AND pageNumber = :pageNumber")
fun getAnnotationsByPage(documentId: Long, pageNumber: Int): List<AnnotationEntity>

@Query("DELETE FROM annotations WHERE id = :id")
fun deleteAnnotation(id: Long)
@Query("UPDATE annotations SET content = :content, xPosition = :xPosition, yPosition = :yPosition WHERE id = :id")
fun updateAnnotation(id: Long, content: String, xPosition: Float, yPosition: Float)

@Query("DELETE FROM annotations WHERE documentId = :documentId")
fun deleteAnnotationsByDocument(documentId: Long)

@Query("DELETE FROM annotations")
fun clearAnnotations()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.iguana.data.local.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.iguana.data.local.entity.PageTurnEventEntity

@Dao
interface PageTurnEventDao {

@Insert
fun insert(event: PageTurnEventEntity)

@Query("SELECT * FROM page_turn_events WHERE documentId = :documentId")
fun getEventsByDocumentId(documentId: Long): List<PageTurnEventEntity>

@Query("DELETE FROM page_turn_events WHERE documentId = :documentId")
fun deleteEventsByDocumentId(documentId: Long) : Int
}
15 changes: 8 additions & 7 deletions core/data/src/main/java/com/iguana/data/local/db/AppDatabase.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package com.iguana.data.local.db

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.iguana.data.local.dao.AnnotationDao
import com.iguana.data.local.dao.RecentFileDao
import com.iguana.data.local.dao.PageTurnEventDao
import com.iguana.data.local.entity.AnnotationEntity
import com.iguana.data.local.entity.PageTurnEventEntity
import com.iguana.data.local.entity.RecentFileEntity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

@Database(entities = [RecentFileEntity::class], version = 1, exportSchema = false)
@Database(entities = [RecentFileEntity::class, PageTurnEventEntity::class, AnnotationEntity::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun recentFileDao(): RecentFileDao
abstract fun pageTurnEventDao(): PageTurnEventDao

abstract fun annotationDao(): AnnotationDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.iguana.data.local.entity

import androidx.room.Entity
import androidx.room.PrimaryKey


@Entity(tableName = "annotations")
data class AnnotationEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val documentId: Long, // 외래 키로 사용될 문서 ID
val pageNumber: Int, // 주석이 있는 페이지 번호
val xPosition: Float, // x 좌표
val yPosition: Float, // y 좌표
val content: String, // 주석 텍스트
val width: Float, // 너비
val height: Float // 높이
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.iguana.data.local.entity

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "page_turn_events")
data class PageTurnEventEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val documentId: Long,
val prevPage: Int,
val nextPage: Int,
val timestamp: Double
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.io.File
import javax.inject.Inject

class RecordingFileStorage @Inject constructor(
private val baseDir: File, // 내부 저장소 경로 (context.filesDir 등을 사용할 수 있음)
private val baseDir: File
) {

// 로컬 스토리지에 녹음 파일 저장
Expand All @@ -16,16 +16,17 @@ class RecordingFileStorage @Inject constructor(
}

// 페이지 이동 이벤트 저장
fun savePageTurnEvents(recordingId: Long, events: List<PageTurnEventDto>) {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
file.writeText(events.joinToString(separator = "\n") { event ->
fun savePageTurnEvents(documentId: Long, events: List<PageTurnEventDto>) {
val file = File(baseDir, "page_turn_events_$documentId.txt")
// 기존 파일 내용에 이어서 새 이벤트를 추가
file.appendText(events.joinToString(separator = "\n") { event ->
"${event.prevPage},${event.nextPage},${event.timestamp}"
})
} + "\n")
}

// 로컬 스토리지에서 페이지 이동 이벤트 삭제
fun deletePageTurnEvents(recordingId: Long) {
val file = File(baseDir, "page_turn_events_$recordingId.txt")
fun deletePageTurnEvents(documentId: Long) {
val file = File(baseDir, "page_turn_events_$documentId.txt")
if (file.exists()) {
file.delete()
Result.success(Unit)
Expand All @@ -39,4 +40,20 @@ class RecordingFileStorage @Inject constructor(
val file = File(filePath)
return file.exists()
}

// 페이지 이동 이벤트 로드
fun loadPageTurnEvents(documentId: Long): List<PageTurnEventDto> {
val file = File(baseDir, "page_turn_events_$documentId.txt")
if (!file.exists()) throw AppError.FileNotFound

return file.readLines().map { line ->
val (prevPage, nextPage, timestamp) = line.split(",")
PageTurnEventDto(
prevPage = prevPage.toInt(),
nextPage = nextPage.toInt(),
timestamp = timestamp.toDouble()
)
}
}

}
Loading