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

Feature/#92 add api #95

Merged
merged 14 commits into from
Jul 16, 2024
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ dependencies {
implementation(projects.data.oauth)
implementation(projects.data.video)
implementation(projects.data.user)
implementation(projects.data.keyword)
implementation(projects.local.auth)
implementation(projects.remote.auth)
implementation(projects.remote.user)
implementation(projects.remote.video)
implementation(projects.remote.keyword)
implementation(projects.feature.navigator)
implementation(libs.kakao.login)
}
7 changes: 7 additions & 0 deletions core/model/src/main/java/com/record/model/Page.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.record.model

data class Page<T>(
val hasNext: Boolean,
val page: Int,
val data: List<T>,
)
12 changes: 12 additions & 0 deletions data/keyword/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
alias(libs.plugins.recordy.data)
alias(libs.plugins.kotlin.serialization)
}

android {
namespace = "com.record.keyword"
}

dependencies {
implementation(projects.domain.keyword)
}
4 changes: 4 additions & 0 deletions data/keyword/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.record.keyword.di

import com.record.keyword.repository.KeywordRepository
import com.record.keyword.repository.KeywordRepositoryImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindsKeywordRepository(keywordRepositoryImpl: KeywordRepositoryImpl): KeywordRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.record.keyword.repository

import com.record.keyword.model.PreferenceKeyword
import com.record.keyword.source.RemoteKeywordDataSource
import com.record.model.exception.ApiError
import retrofit2.HttpException
import javax.inject.Inject

class KeywordRepositoryImpl @Inject constructor(
private val remoteKeywordDataSource: RemoteKeywordDataSource,
) : KeywordRepository {
override suspend fun getKeywords(): Result<PreferenceKeyword> = runCatching {
remoteKeywordDataSource.getKeywords()
}.mapCatching {
PreferenceKeyword(keywords = it)
}.recoverCatching { exception ->
when (exception) {
is HttpException -> {
throw ApiError(exception.message())
}

else -> {
throw exception
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.record.keyword.source

interface RemoteKeywordDataSource {
suspend fun getKeywords(): List<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.record.user.model.remote.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseGetUserPreferenceDto(
@SerialName("preference")
val preference: List<List<String>>,
@SerialName("userId")
val userId: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.record.user.repository

import com.record.model.Cursor
import com.record.model.exception.ApiError
import com.record.user.model.Preference
import com.record.user.model.Profile
import com.record.user.model.User
import com.record.user.model.remote.response.toCore
Expand All @@ -13,7 +14,7 @@ import javax.inject.Inject
class UserRepositoryImpl @Inject constructor(
private val remoteUserDataSource: RemoteUserDataSource,
) : UserRepository {
override fun getFollowingList(cursorId: Long, size: Int): Result<Cursor<User>> = runCatching {
override suspend fun getFollowingList(cursorId: Long, size: Int): Result<Cursor<User>> = runCatching {
remoteUserDataSource.getFollowerList(cursorId, size)
}.mapCatching {
it.toCore()
Expand All @@ -29,7 +30,7 @@ class UserRepositoryImpl @Inject constructor(
}
}

override fun getFollowerList(cursorId: Long, size: Int): Result<Cursor<User>> = runCatching {
override suspend fun getFollowerList(cursorId: Long, size: Int): Result<Cursor<User>> = runCatching {
remoteUserDataSource.getFollowerList(cursorId, size)
}.mapCatching {
it.toCore()
Expand All @@ -45,10 +46,10 @@ class UserRepositoryImpl @Inject constructor(
}
}

override fun postFollow(followingId: Long): Result<Boolean> = runCatching {
override suspend fun postFollow(followingId: Long): Result<Boolean> = runCatching {
remoteUserDataSource.postFollow(followingId)
}.map {
it.isFollowing
it
}.recoverCatching { exception ->
when (exception) {
is HttpException -> {
Expand All @@ -61,7 +62,7 @@ class UserRepositoryImpl @Inject constructor(
}
}

override fun getUserProfile(userId: Long): Result<Profile> = runCatching {
override suspend fun getUserProfile(userId: Long): Result<Profile> = runCatching {
remoteUserDataSource.getUserProfile(userId)
}.mapCatching {
it.toDomain()
Expand All @@ -76,4 +77,24 @@ class UserRepositoryImpl @Inject constructor(
}
}
}

override suspend fun getUserPreference(): Result<Triple<Preference, Preference, Preference>> = runCatching {
remoteUserDataSource.getUserPreference().preference
}.mapCatching {
Triple(
Preference(it[0][0], it[0][1].toInt()),
Preference(it[1][0], it[1][1].toInt()),
Preference(it[2][0], it[2][1].toInt()),
)
}.recoverCatching { exception ->
when (exception) {
is HttpException -> {
throw ApiError(exception.message())
}

else -> {
throw exception
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@ package com.record.user.source.remote

import com.record.user.model.remote.response.ResponseGetFollowerListDto
import com.record.user.model.remote.response.ResponseGetFollowingListDto
import com.record.user.model.remote.response.ResponseGetUserPreferenceDto
import com.record.user.model.remote.response.ResponseGetUserProfileDto
import com.record.user.model.remote.response.ResponsePostFollowDto

interface RemoteUserDataSource {
fun getFollowingList(
suspend fun getFollowingList(
cursorId: Long,
size: Int,
): ResponseGetFollowingListDto

fun getFollowerList(
suspend fun getFollowerList(
cursorId: Long,
size: Int,
): ResponseGetFollowerListDto

fun postFollow(
suspend fun postFollow(
followingId: Long,
): ResponsePostFollowDto
): Boolean

fun getUserProfile(
suspend fun getUserProfile(
userId: Long,
): ResponseGetUserProfileDto

suspend fun getUserPreference(): ResponseGetUserPreferenceDto
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ data class RecordInfo(
val uploaderId: Int,
@SerialName("uploaderNickname")
val uploaderNickname: String,
@SerialName("isMine")
val isMine: Boolean,
)

@Serializable
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
package com.record.video.model.remote.response

import com.record.model.Page
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseGetPopularVideoDto(
data class ResponseGetPagingVideoDto(
@SerialName("content")
val content: List<ResponseGetVideoDto>,
@SerialName("hasNext")
val hasNext: Boolean,
@SerialName("pageNumber")
val pageNumber: Int,
)

fun ResponseGetPagingVideoDto.toCore() = Page(
hasNext = hasNext,
page = pageNumber,
data = content.map {
it.toDomain()
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseGetRecentVideoDto(
data class ResponseGetSliceVideoDto(
@SerialName("content")
val content: List<ResponseGetVideoDto>,
@SerialName("hasNext")
Expand All @@ -14,7 +14,7 @@ data class ResponseGetRecentVideoDto(
val nextCursor: Int,
)

fun ResponseGetRecentVideoDto.toCore() = Cursor(
fun ResponseGetSliceVideoDto.toCore() = Cursor(
hasNext = hasNext,
nextCursor = nextCursor,
data = content.map { content ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ fun ResponseGetVideoDto.toDomain() = VideoData(
location = recordInfo.location,
uploaderId = recordInfo.uploaderId,
nickname = recordInfo.uploaderNickname,
isMine = recordInfo.isMine,
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import javax.inject.Inject
class UploadRepositoryImpl @Inject constructor(
private val remoteUploadDataSource: RemoteUploadDataSource,
) : UploadRepository {
override fun getPresignedUrl(): Result<UploadInfo> = runCatching {
override suspend fun getPresignedUrl(): Result<UploadInfo> = runCatching {
remoteUploadDataSource.getUploadUrl()
}.mapCatching {
it.toCore()
Expand All @@ -29,7 +29,7 @@ class UploadRepositoryImpl @Inject constructor(
}
}

override fun uploadRecord(videoInfo: VideoInfo): Result<Unit> = runCatching {
override suspend fun uploadRecord(videoInfo: VideoInfo): Result<Unit> = runCatching {
remoteUploadDataSource.uploadRecord(videoInfo.toData())
}.recoverCatching { exception ->
when (exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import javax.inject.Inject
class VideoCoreRepositoryImpl @Inject constructor(
private val remoteVideoCoreDataSource: RemoteVideoCoreDataSource,
) : VideoCoreRepository {
override fun deleteVideo(id: Long): Result<Unit> = runCatching {
override suspend fun deleteVideo(id: Long): Result<Unit> = runCatching {
remoteVideoCoreDataSource.deleteVideo(id)
}.recoverCatching { exception ->
when (exception) {
Expand All @@ -22,7 +22,7 @@ class VideoCoreRepositoryImpl @Inject constructor(
}
}

override fun watchVideo(id: Long): Result<Unit> = runCatching {
override suspend fun watchVideo(id: Long): Result<Unit> = runCatching {
remoteVideoCoreDataSource.watchVideo(id)
}.recoverCatching { exception ->
when (exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1 @@
package com.record.video.repository

import com.record.common.util.toUTF8HexString
import com.record.model.Cursor
import com.record.model.exception.ApiError
import com.record.video.model.VideoData
import com.record.video.model.remote.response.toCore
import com.record.video.model.remote.response.toDomain
import com.record.video.source.remote.RemoteVideoDataSource
import retrofit2.HttpException
import javax.inject.Inject

class VideoRepositoryImpl @Inject constructor(
private val remoteVideoDataSource: RemoteVideoDataSource,
) : VideoRepository {
override fun getAllVideos(cursorId: Long, pageSize: Int): Result<List<VideoData>> = runCatching {
remoteVideoDataSource.getAllVideos(cursorId, pageSize)
}.mapCatching {
it.map { video -> video.toDomain() }
}.recoverCatching { exception ->
when (exception) {
is HttpException -> {
throw ApiError(exception.message())
}

else -> {
throw exception
}
}
}

override fun getRecentVideos(keywords: List<String>, pageNumber: Int, pageSize: Int): Result<Cursor<VideoData>> = runCatching {
val encodedKeywords = keywords.map { toUTF8HexString(it) }
remoteVideoDataSource.getRecentVideos(encodedKeywords, pageNumber, pageSize)
}.mapCatching {
it.toCore()
}.recoverCatching { exception ->
when (exception) {
is HttpException -> {
throw ApiError(exception.message())
}

else -> {
throw exception
}
}
}
}
package com.record.video.repositoryimport com.record.common.util.toUTF8HexStringimport com.record.model.Cursorimport com.record.model.Pageimport com.record.model.exception.ApiErrorimport com.record.video.model.VideoDataimport com.record.video.model.remote.response.toCoreimport com.record.video.model.remote.response.toDomainimport com.record.video.source.remote.RemoteVideoDataSourceimport retrofit2.HttpExceptionimport javax.inject.Injectclass VideoRepositoryImpl @Inject constructor( private val remoteVideoDataSource: RemoteVideoDataSource,) : VideoRepository { override suspend fun getAllVideos(cursorId: Long, pageSize: Int): Result<List<VideoData>> = runCatching { remoteVideoDataSource.getAllVideos(cursorId, pageSize) }.mapCatching { it.map { video -> video.toDomain() } }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun getRecentVideos(keywords: List<String>, pageNumber: Int, pageSize: Int): Result<Cursor<VideoData>> = runCatching { val encodedKeywords = keywords.map { toUTF8HexString(it) } remoteVideoDataSource.getRecentVideos(encodedKeywords, pageNumber, pageSize) }.mapCatching { it.toCore() }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun getPopularVideos(keywords: List<String>, pageNumber: Int, pageSize: Int): Result<Page<VideoData>> = runCatching { val encodedKeywords = keywords.map { toUTF8HexString(it) } remoteVideoDataSource.getPopularVideos(encodedKeywords, pageNumber, pageSize) }.mapCatching { it.toCore() }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun getUserVideos(otherUserId: Long, cursorId: Long, size: Int): Result<Cursor<VideoData>> = runCatching { remoteVideoDataSource.getUserVideos(otherUserId, cursorId, size) }.mapCatching { it.toCore() }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun getFollowingVideos(userId: Long, cursorId: Long, size: Int): Result<Cursor<VideoData>> = runCatching { remoteVideoDataSource.getFollowingVideos(userId, cursorId, size) }.mapCatching { it.toCore() }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun getBookmarkVideos(cursorId: Long, size: Int): Result<Cursor<VideoData>> = runCatching { remoteVideoDataSource.getBookmarkVideos(cursorId, size) }.mapCatching { it.toCore() }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } } override suspend fun bookmark(videoId: Long): Result<Boolean> = runCatching { remoteVideoDataSource.bookmark(videoId) }.recoverCatching { exception -> when (exception) { is HttpException -> { throw ApiError(exception.message()) } else -> { throw exception } } }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import com.record.video.model.remote.request.RequestPostVideoDto
import com.record.video.model.remote.response.ResponseGetPresignedUrlDto

interface RemoteUploadDataSource {
fun getUploadUrl(): ResponseGetPresignedUrlDto
fun uploadRecord(requestPostVideoDto: RequestPostVideoDto)
suspend fun getUploadUrl(): ResponseGetPresignedUrlDto
suspend fun uploadRecord(requestPostVideoDto: RequestPostVideoDto)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.record.video.source.remote

interface RemoteVideoCoreDataSource {
fun deleteVideo(recordId: Long)
fun watchVideo(recordId: Long)
suspend fun deleteVideo(recordId: Long)
suspend fun watchVideo(recordId: Long)
}
Loading