Skip to content

Commit 8a49bcb

Browse files
committed
Add UI components
# Conflicts: # sharedUI/src/commonMain/kotlin/com/prof18/feedflow/shared/ui/home/components/HomeScreenContent.kt
1 parent d7b7829 commit 8a49bcb

8 files changed

Lines changed: 376 additions & 97 deletions

File tree

androidApp/src/main/kotlin/com/prof18/feedflow/android/home/HomeScreen.android.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import androidx.compose.runtime.setValue
1818
import androidx.compose.ui.Modifier
1919
import androidx.compose.ui.platform.LocalContext
2020
import androidx.lifecycle.compose.collectAsStateWithLifecycle
21+
import androidx.window.core.layout.WindowWidthSizeClass
2122
import com.prof18.feedflow.android.BrowserManager
2223
import com.prof18.feedflow.android.categoryselection.EditCategorySheet
2324
import com.prof18.feedflow.android.openShareSheet
@@ -29,11 +30,15 @@ import com.prof18.feedflow.core.model.LinkOpeningPreference
2930
import com.prof18.feedflow.core.model.shouldOpenInBrowser
3031
import com.prof18.feedflow.shared.presentation.ChangeFeedCategoryViewModel
3132
import com.prof18.feedflow.shared.presentation.HomeViewModel
33+
import com.prof18.feedflow.shared.presentation.model.NextFeedPreviewState
34+
import com.prof18.feedflow.shared.presentation.model.NextFeedPreviewState.NextFeedPreviewDisabledState
35+
import com.prof18.feedflow.shared.presentation.model.NextFeedPreviewState.NextFeedPreviewEnabledState
3236
import com.prof18.feedflow.shared.presentation.model.UIErrorState
3337
import com.prof18.feedflow.shared.ui.home.AdaptiveHomeView
3438
import com.prof18.feedflow.shared.ui.home.FeedListActions
3539
import com.prof18.feedflow.shared.ui.home.FeedManagementActions
3640
import com.prof18.feedflow.shared.ui.home.HomeDisplayState
41+
import com.prof18.feedflow.shared.ui.home.NextFeedDisplayState
3742
import com.prof18.feedflow.shared.ui.home.ShareBehavior
3843
import com.prof18.feedflow.shared.ui.home.WindowSizeClass
3944
import com.prof18.feedflow.shared.ui.home.components.LoadingOperationDialog
@@ -49,8 +54,9 @@ internal fun HomeScreen(
4954
onSearchClick: () -> Unit,
5055
onAccountsClick: () -> Unit,
5156
onEditFeedClick: (FeedSource) -> Unit,
52-
onImportExportClick: () -> Unit = {},
5357
onFeedSuggestionsClick: () -> Unit,
58+
onNavigateToNextFeed: () -> Unit,
59+
onImportExportClick: () -> Unit = {},
5460
) {
5561
val browserManager = koinInject<BrowserManager>()
5662
val changeFeedCategoryViewModel: ChangeFeedCategoryViewModel = koinInject()
@@ -59,6 +65,7 @@ internal fun HomeScreen(
5965
val feedState by homeViewModel.feedState.collectAsStateWithLifecycle()
6066
val navDrawerState by homeViewModel.navDrawerState.collectAsStateWithLifecycle()
6167
val currentFeedFilter by homeViewModel.currentFeedFilter.collectAsStateWithLifecycle()
68+
val nextFeedPreviewState: NextFeedPreviewState by homeViewModel.nextFeedPreviewState.collectAsStateWithLifecycle()
6269
val unReadCount by homeViewModel.unreadCountFlow.collectAsStateWithLifecycle(initialValue = 0)
6370
val feedFontSizes by homeViewModel.feedFontSizeState.collectAsStateWithLifecycle()
6471
val swipeActions by homeViewModel.swipeActions.collectAsStateWithLifecycle()
@@ -130,6 +137,7 @@ internal fun HomeScreen(
130137
swipeActions = swipeActions,
131138
feedLayout = feedLayout,
132139
isSyncUploadRequired = isSyncUploadRequired,
140+
nextFeedDisplayState = nextFeedPreviewState.asDisplayState(),
133141
)
134142

135143
val feedListActions = FeedListActions(
@@ -168,8 +176,8 @@ internal fun HomeScreen(
168176

169177
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
170178
val adaptiveWindowSizeClass = when (windowSizeClass.windowWidthSizeClass) {
171-
androidx.window.core.layout.WindowWidthSizeClass.COMPACT -> WindowSizeClass.Compact
172-
androidx.window.core.layout.WindowWidthSizeClass.MEDIUM -> WindowSizeClass.Medium
179+
WindowWidthSizeClass.COMPACT -> WindowSizeClass.Compact
180+
WindowWidthSizeClass.MEDIUM -> WindowSizeClass.Medium
173181
else -> WindowSizeClass.Expanded
174182
}
175183

@@ -208,6 +216,7 @@ internal fun HomeScreen(
208216
onEmptyStateClick = {
209217
showNoFeedsBottomSheet = true
210218
},
219+
onNavigateToNextFeed = onNavigateToNextFeed,
211220
)
212221

213222
if (showChangeCategorySheet) {
@@ -278,3 +287,8 @@ private fun openUrl(
278287
}
279288
}
280289
}
290+
291+
fun NextFeedPreviewState.asDisplayState(): NextFeedDisplayState = when (this) {
292+
is NextFeedPreviewDisabledState -> NextFeedDisplayState.NextFeedDisplayDisabledState()
293+
is NextFeedPreviewEnabledState -> NextFeedDisplayState.NextFeedDisplayEnabledState(this.title)
294+
}

desktopApp/src/jvmMain/kotlin/com/prof18/feedflow/desktop/home/HomeScreen.desktop.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.prof18.feedflow.shared.presentation.model.UIErrorState
3232
import com.prof18.feedflow.shared.ui.home.FeedListActions
3333
import com.prof18.feedflow.shared.ui.home.FeedManagementActions
3434
import com.prof18.feedflow.shared.ui.home.HomeDisplayState
35+
import com.prof18.feedflow.shared.ui.home.NextFeedDisplayState.NextFeedDisplayDisabledState
3536
import com.prof18.feedflow.shared.ui.home.ShareBehavior
3637
import com.prof18.feedflow.shared.ui.home.components.LoadingOperationDialog
3738
import com.prof18.feedflow.shared.ui.utils.LocalFeedFlowStrings
@@ -132,6 +133,7 @@ internal fun HomeScreen(
132133
currentFeedFilter = currentFeedFilter,
133134
swipeActions = swipeActions,
134135
feedLayout = feedLayout,
136+
nextFeedDisplayState = NextFeedDisplayDisabledState(),
135137
)
136138

137139
val openReaderArticle: (FeedItemUrlInfo) -> Unit = { article ->

shared/src/commonMain/kotlin/com/prof18/feedflow/shared/presentation/GetNextFeedFilterOrNullUseCase.kt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package com.prof18.feedflow.shared.presentation
22

33
import com.prof18.feedflow.core.model.FeedFilter
4-
import com.prof18.feedflow.core.model.FeedSourceCategory
5-
import com.prof18.feedflow.core.model.FeedSourceWithUnreadCount
64
import com.prof18.feedflow.shared.domain.feed.FeedSourcesRepository
7-
import kotlinx.coroutines.flow.filterNotNull
85
import kotlinx.coroutines.flow.first
9-
import kotlin.math.max
106

117
class GetNextFeedFilterOrNullUseCase internal constructor(
128
private val feedSourcesRepository: FeedSourcesRepository,
@@ -15,7 +11,6 @@ class GetNextFeedFilterOrNullUseCase internal constructor(
1511
suspend operator fun invoke(
1612
currentFeedFilter: FeedFilter,
1713
): FeedFilter? {
18-
1914
when (currentFeedFilter) {
2015
is FeedFilter.Category -> {
2116
val unreadCategoryList = feedSourcesRepository
@@ -33,7 +28,7 @@ class GetNextFeedFilterOrNullUseCase internal constructor(
3328
feedCategory = unreadCategoryList
3429
.drop(currentCategoryIndex + 1)
3530
.firstOrNull()
36-
?: return null
31+
?: return null,
3732
)
3833
}
3934
is FeedFilter.Source -> {
@@ -46,17 +41,17 @@ class GetNextFeedFilterOrNullUseCase internal constructor(
4641
it.feedSource.id == currentFeedFilter.feedSource.id
4742
}
4843

49-
if (currentSourceIndex == -1) return null
44+
if (currentSourceIndex == -1) return null
5045

5146
val nextUnreadSource = feedSources
5247
.drop(currentSourceIndex + 1)
5348
.firstOrNull { it.unreadCount > 0 }
5449

5550
return FeedFilter.Source(
56-
feedSource = nextUnreadSource?.feedSource ?: return null
51+
feedSource = nextUnreadSource?.feedSource ?: return null,
5752
)
5853
}
5954
else -> return null
6055
}
6156
}
62-
}
57+
}

sharedUI/src/commonMain/kotlin/com/prof18/feedflow/shared/ui/home/AdaptiveHomeView.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ fun AdaptiveHomeView(
4242
onBackupClick: () -> Unit = {},
4343
onFeedSuggestionsClick: () -> Unit = {},
4444
onEmptyStateClick: (() -> Unit)? = null,
45+
onNavigateToNextFeed: (() -> Unit) = {},
4546
) {
4647
val scope = rememberCoroutineScope()
4748
val reduceMotionEnabled = LocalReduceMotion.current
@@ -71,6 +72,7 @@ fun AdaptiveHomeView(
7172
shareBehavior = shareBehavior,
7273
onBackupClick = onBackupClick,
7374
onEmptyStateClick = onEmptyStateClick,
75+
onNavigateToNextFeed = onNavigateToNextFeed,
7476
)
7577
}
7678

sharedUI/src/commonMain/kotlin/com/prof18/feedflow/shared/ui/home/HomeParameters.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ class HomeDisplayState(
2525
val feedUpdateStatus: FeedUpdateStatus,
2626
val feedFontSizes: FeedFontSizes,
2727
val currentFeedFilter: FeedFilter,
28+
val nextFeedDisplayState: NextFeedDisplayState,
2829
val swipeActions: SwipeActions,
2930
val feedLayout: FeedLayout,
3031
val isSyncUploadRequired: Boolean = false,
3132
)
3233

34+
@Stable
35+
sealed class NextFeedDisplayState {
36+
class NextFeedDisplayEnabledState(
37+
val title: String,
38+
) : NextFeedDisplayState()
39+
40+
class NextFeedDisplayDisabledState : NextFeedDisplayState()
41+
}
42+
3343
@Stable
3444
class FeedListActions(
3545
val onClearOldArticlesClicked: () -> Unit,

sharedUI/src/commonMain/kotlin/com/prof18/feedflow/shared/ui/home/components/HomeScreenContent.kt

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ fun HomeScreenContent(
6565
toolbarElevation: Dp = 0.dp,
6666
topToolbarContentFadeHeight: Dp = 0.dp,
6767
toolbarExpandedHeight: Dp = TopAppBarDefaults.TopAppBarExpandedHeight,
68+
onNavigateToNextFeed: () -> Unit = { },
6869
) {
6970
val scope = rememberCoroutineScope()
7071
val reduceMotionEnabled = LocalReduceMotion.current
@@ -190,31 +191,32 @@ fun HomeScreenContent(
190191
feedItems = displayState.feedItems,
191192
listState = listState,
192193
feedFontSize = displayState.feedFontSizes,
193-
shareCommentsMenuLabel = shareBehavior.shareCommentsTitle,
194-
shareMenuLabel = shareBehavior.shareLinkTitle,
195-
currentFeedFilter = displayState.currentFeedFilter,
196-
swipeActions = displayState.swipeActions,
197-
requestMoreItems = feedListActions.requestNewData,
198-
onFeedItemClick = { feedInfo ->
199-
feedListActions.openUrl(feedInfo)
200-
feedListActions.markAsRead(FeedItemId(feedInfo.id))
201-
},
202-
onBookmarkClick = feedListActions.updateBookmarkStatus,
203-
onReadStatusClick = feedListActions.updateReadStatus,
204-
onCommentClick = { feedInfo ->
205-
feedListActions.openUrl(feedInfo)
206-
feedListActions.markAsRead(FeedItemId(feedInfo.id))
207-
},
208-
updateReadStatus = feedListActions.markAsReadOnScroll,
209-
markAllAsRead = feedListActions.markAllRead,
210-
onShareClick = shareBehavior.onShareClick,
211-
onOpenFeedSettings = feedManagementActions.onEditFeedClick,
212-
onOpenFeedWebsite = feedManagementActions.onOpenWebsite,
213-
feedLayout = displayState.feedLayout,
214-
onMarkAllAboveAsRead = feedListActions.markAllAboveAsRead,
215-
onMarkAllBelowAsRead = feedListActions.markAllBelowAsRead,
216-
)
217-
}
194+
nextFeedState = displayState.nextFeedDisplayState,
195+
shareCommentsMenuLabel = shareBehavior.shareCommentsTitle,
196+
shareMenuLabel = shareBehavior.shareLinkTitle,
197+
currentFeedFilter = displayState.currentFeedFilter,
198+
swipeActions = displayState.swipeActions,
199+
requestMoreItems = feedListActions.requestNewData,
200+
onFeedItemClick = { feedInfo ->
201+
feedListActions.openUrl(feedInfo)
202+
feedListActions.markAsRead(FeedItemId(feedInfo.id))
203+
},
204+
onBookmarkClick = feedListActions.updateBookmarkStatus,
205+
onReadStatusClick = feedListActions.updateReadStatus,
206+
onCommentClick = { feedInfo ->
207+
feedListActions.openUrl(feedInfo)
208+
feedListActions.markAsRead(FeedItemId(feedInfo.id))
209+
},
210+
updateReadStatus = feedListActions.markAsReadOnScroll,
211+
markAllAsRead = feedListActions.markAllRead,
212+
onShareClick = shareBehavior.onShareClick,
213+
onOpenFeedSettings = feedManagementActions.onEditFeedClick,
214+
onOpenFeedWebsite = feedManagementActions.onOpenWebsite,
215+
feedLayout = displayState.feedLayout,
216+
onMarkAllAboveAsRead = feedListActions.markAllAboveAsRead,
217+
onMarkAllBelowAsRead = feedListActions.markAllBelowAsRead,
218+
onNavigateNext = { onNavigateToNextFeed() },
219+
)}
218220

219221
if (topToolbarContentFadeHeight > 0.dp) {
220222
TopToolbarContentFade(

0 commit comments

Comments
 (0)