mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Droid 3622 add counters to space chat widget (#2449)
This commit is contained in:
parent
5fe1d8489d
commit
622b4ea27c
15 changed files with 249 additions and 103 deletions
|
@ -47,6 +47,7 @@ import com.anytypeio.anytype.domain.base.onSuccess
|
|||
import com.anytypeio.anytype.domain.bin.EmptyBin
|
||||
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
|
||||
import com.anytypeio.anytype.domain.block.interactor.Move
|
||||
import com.anytypeio.anytype.domain.chats.ChatPreviewContainer
|
||||
import com.anytypeio.anytype.domain.collections.AddObjectToCollection
|
||||
import com.anytypeio.anytype.domain.dashboard.interactor.SetObjectListIsFavorite
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
|
||||
|
@ -122,6 +123,7 @@ import com.anytypeio.anytype.presentation.widgets.DropDownMenuAction
|
|||
import com.anytypeio.anytype.presentation.widgets.LinkWidgetContainer
|
||||
import com.anytypeio.anytype.presentation.widgets.ListWidgetContainer
|
||||
import com.anytypeio.anytype.presentation.widgets.SpaceBinWidgetContainer
|
||||
import com.anytypeio.anytype.presentation.widgets.SpaceChatWidgetContainer
|
||||
import com.anytypeio.anytype.presentation.widgets.SpaceWidgetContainer
|
||||
import com.anytypeio.anytype.presentation.widgets.TreePath
|
||||
import com.anytypeio.anytype.presentation.widgets.TreeWidgetBranchStateHolder
|
||||
|
@ -233,7 +235,8 @@ class HomeScreenViewModel(
|
|||
private val getSpaceInviteLink: GetSpaceInviteLink,
|
||||
private val deleteSpace: DeleteSpace,
|
||||
private val spaceMembers: ActiveSpaceMemberSubscriptionContainer,
|
||||
private val setAsFavourite: SetObjectListIsFavorite
|
||||
private val setAsFavourite: SetObjectListIsFavorite,
|
||||
private val chatPreviews: ChatPreviewContainer
|
||||
) : NavigationViewModel<HomeScreenViewModel.Navigation>(),
|
||||
Reducer<ObjectView, Payload>,
|
||||
WidgetActiveViewStateHolder by widgetActiveViewStateHolder,
|
||||
|
@ -507,6 +510,10 @@ class HomeScreenViewModel(
|
|||
|
||||
widgets.forceChatPosition().filter { widget -> widget.hasValidLayout() }.map { widget ->
|
||||
when (widget) {
|
||||
is Widget.Chat -> SpaceChatWidgetContainer(
|
||||
widget = widget,
|
||||
container = chatPreviews
|
||||
)
|
||||
is Widget.Link -> LinkWidgetContainer(
|
||||
widget = widget,
|
||||
fieldParser = fieldParser
|
||||
|
@ -1192,7 +1199,7 @@ class HomeScreenViewModel(
|
|||
)
|
||||
)
|
||||
}
|
||||
WidgetView.SpaceChat.id -> {
|
||||
BundledWidgetSourceIds.CHAT -> {
|
||||
proceedWithSpaceChatWidgetHeaderClick()
|
||||
}
|
||||
else -> {
|
||||
|
@ -1315,6 +1322,7 @@ class HomeScreenViewModel(
|
|||
}
|
||||
// All-objects widget has link appearance.
|
||||
is Widget.AllObjects -> Command.ChangeWidgetType.TYPE_LINK
|
||||
is Widget.Chat -> Command.ChangeWidgetType.TYPE_LINK
|
||||
}
|
||||
|
||||
// TODO move to a separate reducer inject into this VM's constructor
|
||||
|
@ -2690,7 +2698,8 @@ class HomeScreenViewModel(
|
|||
private val getSpaceInviteLink: GetSpaceInviteLink,
|
||||
private val deleteSpace: DeleteSpace,
|
||||
private val activeSpaceMemberSubscriptionContainer: ActiveSpaceMemberSubscriptionContainer,
|
||||
private val setObjectListIsFavorite: SetObjectListIsFavorite
|
||||
private val setObjectListIsFavorite: SetObjectListIsFavorite,
|
||||
private val chatPreviews: ChatPreviewContainer
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T = HomeScreenViewModel(
|
||||
|
@ -2748,7 +2757,8 @@ class HomeScreenViewModel(
|
|||
getSpaceInviteLink = getSpaceInviteLink,
|
||||
deleteSpace = this@Factory.deleteSpace,
|
||||
spaceMembers = activeSpaceMemberSubscriptionContainer,
|
||||
setAsFavourite = setObjectListIsFavorite
|
||||
setAsFavourite = setObjectListIsFavorite,
|
||||
chatPreviews = chatPreviews
|
||||
) as T
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ class DataViewListWidgetContainer(
|
|||
)
|
||||
)
|
||||
}
|
||||
is Widget.Link, is Widget.Tree, is Widget.AllObjects -> {
|
||||
is Widget.Link, is Widget.Tree, is Widget.AllObjects, is Widget.Chat -> {
|
||||
throw IllegalStateException("Incompatible widget type.")
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ class DataViewListWidgetContainer(
|
|||
)
|
||||
)
|
||||
}
|
||||
is Widget.Tree, is Widget.Link, is Widget.AllObjects -> {
|
||||
is Widget.Tree, is Widget.Link, is Widget.AllObjects, is Widget.Chat -> {
|
||||
throw IllegalStateException("Incompatible widget type.")
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class DataViewListWidgetContainer(
|
|||
limit = when (widget) {
|
||||
is Widget.List -> widget.limit
|
||||
is Widget.View -> widget.limit
|
||||
is Widget.Tree, is Widget.Link, is Widget.AllObjects -> {
|
||||
is Widget.Tree, is Widget.Link, is Widget.AllObjects, is Widget.Chat -> {
|
||||
throw IllegalStateException("Incompatible widget type.")
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ class DataViewListWidgetContainer(
|
|||
prettyPrintName = fieldParser.getObjectPluralName(widget.source.obj)
|
||||
)
|
||||
)
|
||||
is Widget.Link, is Widget.Tree, is Widget.AllObjects -> {
|
||||
is Widget.Link, is Widget.Tree, is Widget.AllObjects, is Widget.Chat -> {
|
||||
throw IllegalStateException("Incompatible widget type.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,42 @@
|
|||
package com.anytypeio.anytype.presentation.widgets
|
||||
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.chats.ChatPreviewContainer
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class SpaceChatWidgetContainer : WidgetContainer {
|
||||
override val view: Flow<WidgetView> = flowOf(
|
||||
WidgetView.SpaceChat
|
||||
)
|
||||
class SpaceChatWidgetContainer @Inject constructor(
|
||||
private val widget: Widget,
|
||||
private val container: ChatPreviewContainer
|
||||
) : WidgetContainer {
|
||||
override val view: Flow<WidgetView> = flow {
|
||||
emitAll(
|
||||
container
|
||||
.observePreview(space = SpaceId(widget.config.space))
|
||||
.map { preview ->
|
||||
(preview?.state?.unreadMessages?.counter ?: 0) to (preview?.state?.unreadMentions?.counter ?: 0)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.map { (unreadMessageCount, unreadMentionCount) ->
|
||||
WidgetView.SpaceChat(
|
||||
id = widget.id,
|
||||
source = widget.source,
|
||||
unreadMessageCount = unreadMessageCount,
|
||||
unreadMentionCount = unreadMentionCount
|
||||
)
|
||||
}
|
||||
)
|
||||
}.catch {
|
||||
emit(
|
||||
WidgetView.SpaceChat(
|
||||
id = widget.id,
|
||||
source = widget.source
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -72,6 +72,13 @@ sealed class Widget {
|
|||
override val isAutoCreated: Boolean = false,
|
||||
) : Widget()
|
||||
|
||||
data class Chat(
|
||||
override val id: Id,
|
||||
override val source: Source.Bundled.Chat,
|
||||
override val config: Config,
|
||||
override val isAutoCreated: Boolean = false,
|
||||
) : Widget()
|
||||
|
||||
sealed class Source {
|
||||
|
||||
abstract val id: Id
|
||||
|
@ -172,69 +179,32 @@ fun List<Block>.parseWidgets(
|
|||
is Widget.Source.Default -> source.obj.isValid && source.obj.notDeletedNorArchived
|
||||
}
|
||||
if (hasValidSource && !WidgetConfig.excludedTypes.contains(source.type)) {
|
||||
if (source is Widget.Source.Bundled.AllObjects) {
|
||||
add(
|
||||
Widget.AllObjects(
|
||||
id = w.id,
|
||||
source = source,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
when (source) {
|
||||
is Widget.Source.Bundled.AllObjects -> {
|
||||
add(
|
||||
Widget.AllObjects(
|
||||
id = w.id,
|
||||
source = source,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
when (widgetContent.layout) {
|
||||
Block.Content.Widget.Layout.TREE -> {
|
||||
add(
|
||||
Widget.Tree(
|
||||
id = w.id,
|
||||
source = source,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
}
|
||||
is Widget.Source.Bundled.Chat -> {
|
||||
add(
|
||||
Widget.Chat(
|
||||
id = w.id,
|
||||
source = source,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.LINK -> {
|
||||
add(
|
||||
Widget.Link(
|
||||
id = w.id,
|
||||
source = source,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.LIST -> {
|
||||
add(
|
||||
Widget.List(
|
||||
id = w.id,
|
||||
source = source,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.COMPACT_LIST -> {
|
||||
add(
|
||||
Widget.List(
|
||||
id = w.id,
|
||||
source = source,
|
||||
isCompact = true,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.VIEW -> {
|
||||
if (source is Widget.Source.Default) {
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
when (widgetContent.layout) {
|
||||
Block.Content.Widget.Layout.TREE -> {
|
||||
add(
|
||||
Widget.View(
|
||||
Widget.Tree(
|
||||
id = w.id,
|
||||
source = source,
|
||||
limit = widgetContent.limit,
|
||||
|
@ -243,6 +213,56 @@ fun List<Block>.parseWidgets(
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.LINK -> {
|
||||
add(
|
||||
Widget.Link(
|
||||
id = w.id,
|
||||
source = source,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.LIST -> {
|
||||
add(
|
||||
Widget.List(
|
||||
id = w.id,
|
||||
source = source,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.COMPACT_LIST -> {
|
||||
add(
|
||||
Widget.List(
|
||||
id = w.id,
|
||||
source = source,
|
||||
isCompact = true,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Block.Content.Widget.Layout.VIEW -> {
|
||||
if (source is Widget.Source.Default) {
|
||||
add(
|
||||
Widget.View(
|
||||
id = w.id,
|
||||
source = source,
|
||||
limit = widgetContent.limit,
|
||||
config = config,
|
||||
isAutoCreated = widgetContent.isAutoAdded
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,10 +174,13 @@ sealed class WidgetView {
|
|||
override val isLoading: Boolean = false
|
||||
}
|
||||
|
||||
data object SpaceChat : WidgetView() {
|
||||
private const val SPACE_CHAT_WIDGET_ID = "bundled-widget.space-chat"
|
||||
data class SpaceChat(
|
||||
override val id: Id,
|
||||
val source: Widget.Source,
|
||||
val unreadMessageCount: Int = 0,
|
||||
val unreadMentionCount: Int = 0
|
||||
) : WidgetView() {
|
||||
override val isLoading: Boolean = false
|
||||
override val id: Id = SPACE_CHAT_WIDGET_ID
|
||||
}
|
||||
|
||||
sealed class SpaceWidget: WidgetView() {
|
||||
|
@ -200,7 +203,7 @@ sealed class WidgetView {
|
|||
}
|
||||
}
|
||||
|
||||
object EmptyState : WidgetView() {
|
||||
data object EmptyState : WidgetView() {
|
||||
override val id: Id get() = "id.widgets.empty.state"
|
||||
override val isLoading: Boolean = false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue