Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
31b55a6
Merge pull request #690 from Daily-DAYO/main
yuni-ju Sep 15, 2025
6303757
#692 [bug] Replace Scaffold with BottomSheetScaffold
yuni-ju Oct 3, 2025
b8aec68
#692 [bug] Migrate to BottomSheetScaffold for bottom sheet
yuni-ju Oct 16, 2025
1c47c8b
#691 [feature] Add isMine flag to FolderScreen
yuni-ju Oct 22, 2025
65532b1
[layout] Add vertical alignment to FolderSortSelector
yuni-ju Oct 22, 2025
e919253
Merge pull request #693 from Daily-DAYO/bug/issue-692
yuni-ju Oct 26, 2025
d4716df
Merge pull request #694 from Daily-DAYO/bug/issue-691
yuni-ju Oct 26, 2025
65ca619
#695 [feature] Double back press to exit app on MainScreen
yuni-ju Oct 26, 2025
f771dd2
Merge pull request #697 from Daily-DAYO/feature/issue-695
yuni-ju Oct 27, 2025
fe70055
Update Sentry to version supporting 16KB page size
DongJun-H Oct 27, 2025
8a7cf1f
#696 [bug] Fix Search and Result screen overlapping status bar
yuni-ju Oct 27, 2025
3c7a36f
#696 [bug] Add aspectRatio to SearchResult ImageView
yuni-ju Oct 28, 2025
6cff078
#696 [feature] Add sorting feature to hashtag search results
yuni-ju Oct 28, 2025
fb48056
#698 [bug] Add systemBarsPadding to AccountScreen
yuni-ju Oct 28, 2025
5c683b8
#698 [bug] Fix unwanted default background color showing
yuni-ju Oct 28, 2025
36b49b8
Merge pull request #700 from Daily-DAYO/enhancement/issue-699
DongJun-H Oct 29, 2025
29e2ac1
Merge pull request #701 from Daily-DAYO/bug/issue-696
yuni-ju Oct 29, 2025
39d4a9e
Merge pull request #702 from Daily-DAYO/bug/issue-698
yuni-ju Oct 29, 2025
e9509bd
[release] v2.1.0
yuni-ju Oct 29, 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
12 changes: 7 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ android {
applicationId "com.daily.dayo"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 20000
versionName "2.0.0"
versionCode 21000
versionName "2.1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -102,7 +102,7 @@ dependencies {
implementation project(':domain')
implementation project(':data')

def sentry_version = "7.16.0"
def sentry_version = "8.24.0"
def glide_version = "4.15.1"

// Hilt
Expand All @@ -114,8 +114,10 @@ dependencies {
implementation "com.github.bumptech.glide:glide:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
// Sentry
implementation "io.sentry:sentry-android:$sentry_version"
implementation 'org.slf4j:slf4j-nop:1.7.25'
implementation platform("io.sentry:sentry-bom:$sentry_version")
implementation('io.sentry:sentry-android')
implementation('io.sentry:sentry-android-fragment')
implementation 'org.slf4j:slf4j-nop:2.0.17'
// Firebase
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import retrofit2.http.Query

interface SearchApiService {

@GET("/api/v1/search")
@GET("/api/v2/search")
suspend fun requestSearchTag(
@Query("tag") tag: String,
@Query("end") end: Int
@Query("end") end: Int,
@Query("order") order: String
): NetworkResponse<SearchResultResponse>

@GET("/api/v1/search/member")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import androidx.paging.PagingState
import daily.dayo.data.mapper.toSearch
import daily.dayo.domain.model.NetworkResponse
import daily.dayo.domain.model.Search
import daily.dayo.domain.model.SearchOrder

class SearchPagingSource(
private val apiService: SearchApiService,
private val size: Int,
private val tag: String
private val tag: String,
private val searchOrder: SearchOrder
) : PagingSource<Int, Search>() {

override suspend fun load(
params: LoadParams<Int>
): LoadResult<Int, Search> {
val nextPageNumber = params.key ?: 0
apiService.requestSearchTag(tag = tag, end = nextPageNumber).let { ApiResponse ->
apiService.requestSearchTag(tag = tag, end = nextPageNumber, order = searchOrder.toString()).let { ApiResponse ->
return try {
when (ApiResponse) {
is NetworkResponse.Success -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import androidx.paging.PagingData
import daily.dayo.data.datasource.local.SharedManager
import daily.dayo.data.datasource.remote.search.SearchApiService
import daily.dayo.data.datasource.remote.search.SearchFollowUserPagingSource
import daily.dayo.data.datasource.remote.search.SearchUserPagingSource
import daily.dayo.data.datasource.remote.search.SearchPagingSource
import daily.dayo.data.datasource.remote.search.SearchUserPagingSource
import daily.dayo.domain.model.NetworkResponse
import daily.dayo.domain.model.Search
import daily.dayo.domain.model.SearchHistory
import daily.dayo.domain.model.SearchHistoryDetail
import daily.dayo.domain.model.SearchHistoryType
import daily.dayo.domain.model.SearchOrder
import daily.dayo.domain.model.SearchUser
import daily.dayo.domain.repository.SearchRepository
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -47,10 +48,11 @@ class SearchRepositoryImpl @Inject constructor(
override fun updateSearchKeywordRecentList(keyword: String, requestSearchType: SearchHistoryType) {
SharedManager(context = context).updateSearchHistory(
SearchHistoryDetail(
history = keyword,
searchHistoryType = requestSearchType,
searchId = 0
))
history = keyword,
searchHistoryType = requestSearchType,
searchId = 0
)
)
}

override fun requestSearchUser(nickname: String): Flow<PagingData<SearchUser>> = Pager(PagingConfig(pageSize = SEARCH_PAGE_SIZE)) {
Expand All @@ -61,35 +63,43 @@ class SearchRepositoryImpl @Inject constructor(
SearchFollowUserPagingSource(searchApiService, SEARCH_PAGE_SIZE, nickname)
}.flow

override fun requestSearchTag(tag: String): Flow<PagingData<Search>> = Pager(PagingConfig(pageSize = SEARCH_PAGE_SIZE)) {
SearchPagingSource(searchApiService, SEARCH_PAGE_SIZE, tag)
override fun requestSearchTag(tag: String, searchOrder: SearchOrder): Flow<PagingData<Search>> = Pager(PagingConfig(pageSize = SEARCH_PAGE_SIZE)) {
SearchPagingSource(searchApiService, SEARCH_PAGE_SIZE, tag, searchOrder)
}.flow

override suspend fun requestSearchTotalCount(tag: String, end: Int, searchHistoryType: SearchHistoryType) : Int =
when (searchHistoryType) {
SearchHistoryType.TAG -> {
searchApiService.requestSearchTag(tag, end).let { ApiResponse ->
when(ApiResponse) {
is NetworkResponse.Success -> {
return ApiResponse.body!!.totalCount
}
else -> return 0
override suspend fun requestSearchTotalCount(
tag: String,
end: Int,
searchHistoryType: SearchHistoryType,
searchOrder: SearchOrder
): Int = when (searchHistoryType) {
SearchHistoryType.TAG -> {
searchApiService.requestSearchTag(tag, end, searchOrder.toString()).let { ApiResponse ->
when (ApiResponse) {
is NetworkResponse.Success -> {
return ApiResponse.body!!.totalCount
}

else -> return 0
}
}
SearchHistoryType.USER -> {
searchApiService.requestSearchUser(tag, end).let { ApiResponse ->
when(ApiResponse) {
is NetworkResponse.Success -> {
return ApiResponse.body!!.totalCount
}
else -> return 0
}

SearchHistoryType.USER -> {
searchApiService.requestSearchUser(tag, end).let { ApiResponse ->
when (ApiResponse) {
is NetworkResponse.Success -> {
return ApiResponse.body!!.totalCount
}

else -> return 0
}
}
else -> 0
}

else -> 0
}

companion object {
private const val SEARCH_PAGE_SIZE = 10
}
Expand Down
10 changes: 9 additions & 1 deletion domain/src/main/java/daily/dayo/domain/model/Search.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ data class SearchHistoryDetail(
enum class SearchHistoryType {
USER,
TAG
}
}

enum class SearchOrder {
NEW, OLD;

override fun toString(): String {
return name.lowercase()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import androidx.paging.PagingData
import daily.dayo.domain.model.Search
import daily.dayo.domain.model.SearchHistory
import daily.dayo.domain.model.SearchHistoryType
import daily.dayo.domain.model.SearchOrder
import daily.dayo.domain.model.SearchUser
import kotlinx.coroutines.flow.Flow

interface SearchRepository {
fun requestSearchTag(tag: String): Flow<PagingData<Search>>
fun requestSearchTag(tag: String, searchOrder: SearchOrder): Flow<PagingData<Search>>
fun requestSearchUser(nickname: String): Flow<PagingData<SearchUser>>
fun requestSearchFollowUser(nickname: String): Flow<PagingData<SearchUser>>
fun requestSearchKeywordRecentList(): SearchHistory
Expand All @@ -22,6 +23,7 @@ interface SearchRepository {
suspend fun requestSearchTotalCount(
tag: String,
end: Int,
searchHistoryType: SearchHistoryType
searchHistoryType: SearchHistoryType,
searchOrder: SearchOrder
): Int
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package daily.dayo.domain.usecase.search

import daily.dayo.domain.model.SearchOrder
import daily.dayo.domain.repository.SearchRepository
import javax.inject.Inject

class RequestSearchTagUseCase @Inject constructor(
private val searchRepository: SearchRepository
) {
operator fun invoke(tag: String) = searchRepository.requestSearchTag(tag)
operator fun invoke(tag: String, searchOrder: SearchOrder) = searchRepository.requestSearchTag(tag, searchOrder)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package daily.dayo.domain.usecase.search

import daily.dayo.domain.model.SearchHistoryType
import daily.dayo.domain.model.SearchOrder
import daily.dayo.domain.repository.SearchRepository
import javax.inject.Inject

class RequestSearchTotalCountUseCase @Inject constructor(
private val searchRepository: SearchRepository
) {
suspend operator fun invoke(tag: String, searchHistoryType: SearchHistoryType) =
searchRepository.requestSearchTotalCount(tag, 0, searchHistoryType)
suspend operator fun invoke(
tag: String,
searchHistoryType: SearchHistoryType,
searchOrder: SearchOrder = SearchOrder.NEW
) = searchRepository.requestSearchTotalCount(tag, 0, searchHistoryType, searchOrder)
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class MainActivity : AppCompatActivity() {
MainScreen(
onAdRequest = { onRewardSuccess ->
showAdIfAvailable(onRewardSuccess)
}
},
onExit = { finish() }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,100 @@
package daily.dayo.presentation.screen.account

import android.annotation.SuppressLint
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetValue
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import daily.dayo.presentation.theme.Dark
import daily.dayo.presentation.view.dialog.getBottomSheetDialogState
import kotlinx.coroutines.launch

@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun AccountScreen(
navigator: AccountNavigator = rememberAccountNavigator()
) {
val coroutineScope = rememberCoroutineScope()
val snackBarHostState = remember { SnackbarHostState() }
var bottomSheetContent by remember { mutableStateOf<(@Composable () -> Unit)?>(null) }
val bottomSheetState = getBottomSheetDialogState()
var bottomSheet: (@Composable () -> Unit)? by remember { mutableStateOf(null) }
val bottomSheetContent: (@Composable () -> Unit) -> Unit = {
bottomSheet = it
val bottomSheetDimAlpha by remember {
derivedStateOf { if (bottomSheetState.bottomSheetState.currentValue == SheetValue.Expanded) 0.6f else 0f }
}
Scaffold(
snackbarHost = { SnackbarHost(hostState = snackBarHostState) }
) {
Scaffold(
bottomBar = { bottomSheet?.let { it() } }
) {
Scaffold(
content = { innerPadding ->
Box(Modifier.padding(innerPadding)) {
NavHost(
navController = navigator.navController,
startDestination = AccountScreen.SignIn.route
) {
signInNavGraph(
coroutineScope = coroutineScope,
snackBarHostState = snackBarHostState,
navController = navigator.navController,
onBackClick = { navigator.popBackStack() },
navigateToSignIn = { navigator.navigateSignIn() },
navigateToSignInEmail = { navigator.navigateSignInEmail() },
navigateToResetPassword = { navigator.navigateResetPassword() },
navigateToSignUpEmail = { navigator.navigateSignUpEmail() },
navigateToProfileSetting = { navigator.navigateProfileSetting() },
navigateToRules = { route -> navigator.navigateRules(route) },
bottomSheetState = bottomSheetState,
bottomSheetContent = bottomSheetContent
)
val animatedDimAlpha by animateFloatAsState(targetValue = bottomSheetDimAlpha)

BottomSheetScaffold(
modifier = Modifier.systemBarsPadding(),
scaffoldState = bottomSheetState,
sheetDragHandle = null,
sheetContent = {
Box(modifier = Modifier.navigationBarsPadding()) {
bottomSheetContent?.invoke()
}
},
sheetPeekHeight = 0.dp,
snackbarHost = {
SnackbarHost(
hostState = snackBarHostState,
modifier = Modifier.navigationBarsPadding()
)
},
content = { innerPadding ->
Box(Modifier.padding(innerPadding)) {
NavHost(
navController = navigator.navController,
startDestination = AccountScreen.SignIn.route
) {
signInNavGraph(
coroutineScope = coroutineScope,
snackBarHostState = snackBarHostState,
navController = navigator.navController,
onBackClick = { navigator.popBackStack() },
navigateToSignIn = { navigator.navigateSignIn() },
navigateToSignInEmail = { navigator.navigateSignInEmail() },
navigateToResetPassword = { navigator.navigateResetPassword() },
navigateToSignUpEmail = { navigator.navigateSignUpEmail() },
navigateToProfileSetting = { navigator.navigateProfileSetting() },
navigateToRules = { route -> navigator.navigateRules(route) },
bottomSheetState = bottomSheetState,
bottomSheetContent = { content ->
bottomSheetContent = content
}
}
})
)
}

if (animatedDimAlpha > 0f) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Dark.copy(alpha = animatedDimAlpha))
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) {
coroutineScope.launch { bottomSheetState.bottomSheetState.hide() }
}
)
}
}
}
}
)
}

sealed class AccountScreen(val route: String) {
Expand Down
Loading