mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3662 Chats | Enhancement | Introduce system widget "Chat" + navigation changes (#2420)
This commit is contained in:
parent
d7946bd54d
commit
5bddcd640c
21 changed files with 175 additions and 82 deletions
|
@ -31,7 +31,7 @@ object WidgetAnalytics {
|
|||
const val WIDGET_SOURCE_SETS = "Sets"
|
||||
const val WIDGET_SOURCE_BIN = "Bin"
|
||||
const val WIDGET_SOURCE_ALL_OBJECTS = "AllObjects"
|
||||
const val WIDGET_SOURCE_COLLECTIONS = "Sets"
|
||||
const val WIDGET_SOURCE_CHAT = "Chat"
|
||||
|
||||
const val CUSTOM_OBJECT_TYPE = "custom"
|
||||
|
||||
|
|
|
@ -63,16 +63,6 @@ class Navigator : AppNavigation {
|
|||
)
|
||||
}
|
||||
|
||||
override fun openDiscussion(target: Id, space: Id) {
|
||||
navController?.navigate(
|
||||
R.id.chatScreen,
|
||||
ChatFragment.args(
|
||||
ctx = target,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun openModalTemplateSelect(
|
||||
template: Id,
|
||||
templateTypeId: Id,
|
||||
|
|
|
@ -464,7 +464,7 @@ class HomeScreenFragment : BaseComposeFragment(),
|
|||
)
|
||||
}
|
||||
is Navigation.OpenChat -> runCatching {
|
||||
navigation().openDiscussion(
|
||||
navigation().openChat(
|
||||
target = destination.ctx,
|
||||
space = destination.space
|
||||
)
|
||||
|
|
|
@ -617,4 +617,5 @@ fun Widget.Source.Bundled.res(): Int = when (this) {
|
|||
Widget.Source.Bundled.RecentLocal -> R.string.recently_opened
|
||||
Widget.Source.Bundled.Bin -> R.string.bin
|
||||
Widget.Source.Bundled.AllObjects -> R.string.all_content
|
||||
Widget.Source.Bundled.Chat -> R.string.chat
|
||||
}
|
|
@ -5,6 +5,7 @@ import com.anytypeio.anytype.core_models.ext.typeOf
|
|||
import com.anytypeio.anytype.core_models.multiplayer.ParticipantStatus
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceType
|
||||
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
|
||||
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
|
||||
|
||||
|
@ -331,6 +332,14 @@ sealed class ObjectWrapper {
|
|||
.firstOrNull { it.code == code?.toInt() }
|
||||
}
|
||||
|
||||
val spaceType: SpaceType?
|
||||
get() {
|
||||
val code = getValue<Double?>(Relations.SPACE_TYPE)
|
||||
return SpaceType
|
||||
.entries
|
||||
.firstOrNull { it.code == code?.toInt() }
|
||||
}
|
||||
|
||||
val writersLimit: Double? by default
|
||||
val readersLimit: Double? by default
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ object Relations {
|
|||
const val FEATURED_RELATIONS = "featuredRelations"
|
||||
const val SNIPPET = "snippet"
|
||||
const val SPACE_ID = "spaceId"
|
||||
const val SPACE_TYPE = "spaceType"
|
||||
const val TARGET_SPACE_ID = "targetSpaceId"
|
||||
const val SET_OF = "setOf"
|
||||
const val URL = "url"
|
||||
|
|
|
@ -55,6 +55,11 @@ enum class SpaceAccessType(val code: Int) {
|
|||
SHARED(2)
|
||||
}
|
||||
|
||||
enum class SpaceType(val code: Int) {
|
||||
DATA(0),
|
||||
CHAT(1)
|
||||
}
|
||||
|
||||
sealed class SpaceInviteError : Exception() {
|
||||
class SpaceDeleted : SpaceInviteError()
|
||||
class InvalidInvite : SpaceInviteError()
|
||||
|
|
|
@ -6,6 +6,7 @@ object BundledWidgetSourceIds {
|
|||
const val RECENT_LOCAL = "recentOpen"
|
||||
const val BIN = "bin"
|
||||
const val ALL_OBJECTS = "allObjects"
|
||||
const val CHAT = "chat"
|
||||
|
||||
val ids = listOf(FAVORITE, RECENT, RECENT_LOCAL, BIN, ALL_OBJECTS)
|
||||
val ids = listOf(FAVORITE, RECENT, RECENT_LOCAL, BIN, ALL_OBJECTS, CHAT)
|
||||
}
|
|
@ -273,6 +273,13 @@ class BundledWidgetSourceHolder(
|
|||
ivIcon.setBackgroundResource(R.drawable.ic_widget_system_all_objects)
|
||||
}
|
||||
}
|
||||
BundledWidgetSourceView.Chat -> {
|
||||
with(binding) {
|
||||
tvTitle.setText(R.string.chat)
|
||||
tvSubtitle.gone()
|
||||
// TODO DROID-3662 Set icon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ interface SpaceViewSubscriptionContainer {
|
|||
subscription = GLOBAL_SUBSCRIPTION,
|
||||
keys = listOf(
|
||||
Relations.ID,
|
||||
Relations.SPACE_TYPE,
|
||||
Relations.TARGET_SPACE_ID,
|
||||
Relations.CHAT_ID,
|
||||
Relations.SPACE_ACCOUNT_STATUS,
|
||||
|
|
|
@ -120,7 +120,8 @@ class ChatViewModel @Inject constructor(
|
|||
icon = view.spaceIcon(
|
||||
builder = urlBuilder,
|
||||
spaceGradientProvider = SpaceGradientProvider.Default
|
||||
)
|
||||
),
|
||||
showIcon = false
|
||||
)
|
||||
}.collect {
|
||||
header.value = it
|
||||
|
@ -1159,7 +1160,8 @@ class ChatViewModel @Inject constructor(
|
|||
data object Init : HeaderView()
|
||||
data class Default(
|
||||
val icon: SpaceIconView,
|
||||
val title: String
|
||||
val title: String,
|
||||
val showIcon: Boolean
|
||||
) : HeaderView()
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
|
@ -75,26 +76,30 @@ fun ChatTopToolbar(
|
|||
textAlign = TextAlign.Center,
|
||||
style = Title1
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(60.dp)
|
||||
.fillMaxHeight()
|
||||
.noRippleClickable {
|
||||
onSpaceIconClicked()
|
||||
}
|
||||
) {
|
||||
SpaceIconView(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
mainSize = 28.dp,
|
||||
icon = when(header) {
|
||||
is ChatViewModel.HeaderView.Default -> header.icon
|
||||
is ChatViewModel.HeaderView.Init -> SpaceIconView.Loading
|
||||
},
|
||||
onSpaceIconClick = {
|
||||
onSpaceIconClicked()
|
||||
}
|
||||
if (header is ChatViewModel.HeaderView.Default && header.showIcon) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(60.dp)
|
||||
.fillMaxHeight()
|
||||
.noRippleClickable {
|
||||
onSpaceIconClicked()
|
||||
}
|
||||
) {
|
||||
SpaceIconView(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
mainSize = 28.dp,
|
||||
icon = header.icon,
|
||||
onSpaceIconClick = {
|
||||
onSpaceIconClicked()
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Spacer(
|
||||
modifier = Modifier.width(60.dp)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +109,8 @@ fun ChatTopToolbarPreview() {
|
|||
ChatTopToolbar(
|
||||
header = ChatViewModel.HeaderView.Default(
|
||||
title = LoremIpsum(words = 10).values.joinToString(),
|
||||
icon = SpaceIconView.Placeholder(name = "Us")
|
||||
icon = SpaceIconView.Placeholder(name = "Us"),
|
||||
showIcon = true
|
||||
),
|
||||
onSpaceIconClicked = {},
|
||||
onBackButtonClicked = {}
|
||||
|
|
|
@ -1666,6 +1666,12 @@ fun CoroutineScope.sendChangeWidgetSourceEvent(
|
|||
BundledWidgetSourceView.AllObjects -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
|
||||
}
|
||||
BundledWidgetSourceView.AllObjects -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_CHAT)
|
||||
}
|
||||
BundledWidgetSourceView.Chat -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_CHAT)
|
||||
}
|
||||
}
|
||||
if (isForNewWidget)
|
||||
put(WidgetAnalytics.ROUTE, WidgetAnalytics.ROUTE_ADD_WIDGET)
|
||||
|
@ -1769,6 +1775,9 @@ fun CoroutineScope.sendDeleteWidgetEvent(
|
|||
Widget.Source.Bundled.AllObjects -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
|
||||
}
|
||||
Widget.Source.Bundled.Chat -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_CHAT)
|
||||
}
|
||||
}
|
||||
if (isInEditMode)
|
||||
put(WidgetAnalytics.CONTEXT, WidgetAnalytics.CONTEXT_EDITOR)
|
||||
|
@ -1814,6 +1823,9 @@ fun CoroutineScope.sendClickWidgetTitleEvent(
|
|||
Widget.Source.Bundled.AllObjects -> {
|
||||
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
|
||||
}
|
||||
Widget.Source.Bundled.Chat -> {
|
||||
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_CHAT)
|
||||
}
|
||||
}
|
||||
|
||||
isAutoCreated?.let {
|
||||
|
@ -1902,6 +1914,9 @@ fun CoroutineScope.sendReorderWidgetEvent(
|
|||
Widget.Source.Bundled.AllObjects -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
|
||||
}
|
||||
Widget.Source.Bundled.Chat -> {
|
||||
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_CHAT)
|
||||
}
|
||||
}
|
||||
|
||||
isAutoCreated?.let {
|
||||
|
|
|
@ -136,6 +136,7 @@ import com.anytypeio.anytype.presentation.widgets.WidgetId
|
|||
import com.anytypeio.anytype.presentation.widgets.WidgetSessionStateHolder
|
||||
import com.anytypeio.anytype.presentation.widgets.WidgetView
|
||||
import com.anytypeio.anytype.presentation.widgets.collection.Subscription
|
||||
import com.anytypeio.anytype.presentation.widgets.forceChatPosition
|
||||
import com.anytypeio.anytype.presentation.widgets.hasValidLayout
|
||||
import com.anytypeio.anytype.presentation.widgets.parseActiveViews
|
||||
import com.anytypeio.anytype.presentation.widgets.parseWidgets
|
||||
|
@ -503,7 +504,8 @@ class HomeScreenViewModel(
|
|||
viewModelScope.launch {
|
||||
widgets.filterNotNull().map { widgets ->
|
||||
val currentlyDisplayedViews = views.value
|
||||
widgets.filter { widget -> widget.hasValidLayout() }.map { widget ->
|
||||
|
||||
widgets.forceChatPosition().filter { widget -> widget.hasValidLayout() }.map { widget ->
|
||||
when (widget) {
|
||||
is Widget.Link -> LinkWidgetContainer(
|
||||
widget = widget,
|
||||
|
@ -738,6 +740,7 @@ class HomeScreenViewModel(
|
|||
if (
|
||||
dispatch.source == BundledWidgetSourceView.AllObjects.id
|
||||
|| dispatch.source == BundledWidgetSourceView.Bin.id
|
||||
|| dispatch.source == BundledWidgetSourceView.Chat.id
|
||||
) {
|
||||
// Applying link layout automatically to all-objects widget
|
||||
proceedWithCreatingWidget(
|
||||
|
@ -1105,6 +1108,26 @@ class HomeScreenViewModel(
|
|||
)
|
||||
}
|
||||
}
|
||||
is Widget.Source.Bundled.Chat -> {
|
||||
viewModelScope.launch {
|
||||
if (mode.value == InteractionMode.Edit) {
|
||||
return@launch
|
||||
}
|
||||
val space = spaceManager.get()
|
||||
val view = spaceViewSubscriptionContainer.get(SpaceId(space))
|
||||
val chat = view?.chatId
|
||||
if (chat != null) {
|
||||
navigation(
|
||||
Navigation.OpenChat(
|
||||
ctx = chat,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Timber.w("Failed to open chat from widget: chat not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2487,41 +2510,46 @@ class HomeScreenViewModel(
|
|||
viewModelScope.launch {
|
||||
val source = view.source
|
||||
if (source is Widget.Source.Default) {
|
||||
if (source.obj.layout == ObjectType.Layout.OBJECT_TYPE) {
|
||||
val wrapper = ObjectWrapper.Type(source.obj.map)
|
||||
val space = SpaceId(spaceManager.get())
|
||||
val startTime = System.currentTimeMillis()
|
||||
createObject.async(
|
||||
params = CreateObject.Param(
|
||||
space = space,
|
||||
type = TypeKey(wrapper.uniqueKey),
|
||||
prefilled = mapOf(Relations.IS_FAVORITE to true)
|
||||
)
|
||||
).onSuccess { result ->
|
||||
sendAnalyticsObjectCreateEvent(
|
||||
objType = wrapper.uniqueKey,
|
||||
analytics = analytics,
|
||||
route = EventsDictionary.Routes.widget,
|
||||
startTime = startTime,
|
||||
view = null,
|
||||
spaceParams = provideParams(space.id)
|
||||
)
|
||||
proceedWithNavigation(result.obj.navigation())
|
||||
when (source.obj.layout) {
|
||||
ObjectType.Layout.OBJECT_TYPE -> {
|
||||
val wrapper = ObjectWrapper.Type(source.obj.map)
|
||||
val space = SpaceId(spaceManager.get())
|
||||
val startTime = System.currentTimeMillis()
|
||||
createObject.async(
|
||||
params = CreateObject.Param(
|
||||
space = space,
|
||||
type = TypeKey(wrapper.uniqueKey),
|
||||
prefilled = mapOf(Relations.IS_FAVORITE to true)
|
||||
)
|
||||
).onSuccess { result ->
|
||||
sendAnalyticsObjectCreateEvent(
|
||||
objType = wrapper.uniqueKey,
|
||||
analytics = analytics,
|
||||
route = EventsDictionary.Routes.widget,
|
||||
startTime = startTime,
|
||||
view = null,
|
||||
spaceParams = provideParams(space.id)
|
||||
)
|
||||
proceedWithNavigation(result.obj.navigation())
|
||||
}
|
||||
}
|
||||
ObjectType.Layout.COLLECTION -> {
|
||||
onCreateDataViewObject(
|
||||
widget = view.id,
|
||||
view = null,
|
||||
navigate = true
|
||||
)
|
||||
}
|
||||
ObjectType.Layout.SET -> {
|
||||
onCreateDataViewObject(
|
||||
widget = view.id,
|
||||
view = null,
|
||||
navigate = true
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Timber.w("Unexpected source layout: ${source.obj.layout}")
|
||||
}
|
||||
} else if (source.obj.layout == ObjectType.Layout.COLLECTION) {
|
||||
onCreateDataViewObject(
|
||||
widget = view.id,
|
||||
view = null,
|
||||
navigate = true
|
||||
)
|
||||
} else if (source.obj.layout == ObjectType.Layout.SET) {
|
||||
onCreateDataViewObject(
|
||||
widget = view.id,
|
||||
view = null,
|
||||
navigate = true
|
||||
)
|
||||
} else {
|
||||
Timber.w("Unexpected source layout: ${source.obj.layout}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ interface AppNavigation {
|
|||
)
|
||||
fun openChat(target: Id, space: Id)
|
||||
fun openDocument(target: Id, space: Id)
|
||||
fun openDiscussion(target: Id, space: Id)
|
||||
fun openModalTemplateSelect(
|
||||
template: Id,
|
||||
templateTypeId: Id,
|
||||
|
@ -98,7 +97,7 @@ interface AppNavigation {
|
|||
val space: Id
|
||||
) : Command()
|
||||
|
||||
object OpenSettings : Command()
|
||||
data object OpenSettings : Command()
|
||||
|
||||
data class OpenShareScreen(
|
||||
val space: SpaceId
|
||||
|
@ -132,7 +131,7 @@ interface AppNavigation {
|
|||
|
||||
data class LaunchObjectSet(val target: Id, val space: Id) : Command()
|
||||
|
||||
object OpenUpdateAppScreen : Command()
|
||||
data object OpenUpdateAppScreen : Command()
|
||||
|
||||
data class DeletedAccountScreen(val deadline: Long) : Command()
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.anytypeio.anytype.core_models.ObjectTypeIds.COLLECTION
|
|||
import com.anytypeio.anytype.core_models.SupportedLayouts
|
||||
import com.anytypeio.anytype.core_models.exceptions.AccountMigrationNeededException
|
||||
import com.anytypeio.anytype.core_models.exceptions.NeedToUpdateApplicationException
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceType
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
|
||||
|
@ -257,7 +258,7 @@ class SplashViewModel(
|
|||
Command.NavigateToObjectSet(
|
||||
id = target,
|
||||
space = spaceId,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
@ -265,7 +266,7 @@ class SplashViewModel(
|
|||
Command.NavigateToObject(
|
||||
id = target,
|
||||
space = spaceId,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -317,7 +318,7 @@ class SplashViewModel(
|
|||
Command.NavigateToObjectSet(
|
||||
id = id,
|
||||
space = space,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
ObjectType.Layout.DATE -> {
|
||||
|
@ -325,7 +326,7 @@ class SplashViewModel(
|
|||
Command.NavigateToDateObject(
|
||||
id = id,
|
||||
space = space,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -334,7 +335,7 @@ class SplashViewModel(
|
|||
Command.NavigateToObjectType(
|
||||
id = id,
|
||||
space = space,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -343,7 +344,7 @@ class SplashViewModel(
|
|||
Command.NavigateToObject(
|
||||
id = id,
|
||||
space = space,
|
||||
chat = view.chatId
|
||||
chat = if (view.spaceType == SpaceType.CHAT) view.chatId else null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -398,7 +399,7 @@ class SplashViewModel(
|
|||
deeplink = deeplink
|
||||
)
|
||||
)
|
||||
} else {
|
||||
} else if (view.spaceType == SpaceType.CHAT) {
|
||||
commands.emit(
|
||||
Command.NavigateToSpaceLevelChat(
|
||||
space = space.id,
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.anytypeio.anytype.core_models.Event
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Wallpaper
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceType
|
||||
import com.anytypeio.anytype.core_models.primitives.Space
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
|
@ -147,7 +148,8 @@ class VaultViewModel(
|
|||
onSuccess = {
|
||||
proceedWithSavingCurrentSpace(
|
||||
targetSpace = targetSpace,
|
||||
chat = view.space.chatId?.ifEmpty { null }
|
||||
chat = view.space.chatId?.ifEmpty { null },
|
||||
spaceType = view.space.spaceType
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -252,7 +254,8 @@ class VaultViewModel(
|
|||
|
||||
private suspend fun proceedWithSavingCurrentSpace(
|
||||
targetSpace: String,
|
||||
chat: Id?
|
||||
chat: Id?,
|
||||
spaceType: SpaceType?
|
||||
) {
|
||||
saveCurrentSpace.async(
|
||||
SaveCurrentSpace.Params(SpaceId(targetSpace))
|
||||
|
@ -261,7 +264,7 @@ class VaultViewModel(
|
|||
Timber.e(it, "Error while saving current space on vault screen")
|
||||
},
|
||||
onSuccess = {
|
||||
if (chat != null && ChatConfig.isChatAllowed(space = targetSpace)) {
|
||||
if (spaceType == SpaceType.CHAT && chat != null && ChatConfig.isChatAllowed(space = targetSpace)) {
|
||||
commands.emit(
|
||||
Command.EnterSpaceLevelChat(
|
||||
space = Space(targetSpace),
|
||||
|
|
|
@ -130,6 +130,9 @@ class SelectWidgetSourceViewModel(
|
|||
if (contains(BundledWidgetSourceIds.ALL_OBJECTS)) {
|
||||
add(BundledWidgetSourceView.AllObjects)
|
||||
}
|
||||
if (contains(BundledWidgetSourceIds.CHAT)) {
|
||||
add(BundledWidgetSourceView.Chat)
|
||||
}
|
||||
if (contains(BundledWidgetSourceIds.RECENT)) {
|
||||
add(BundledWidgetSourceView.Recent)
|
||||
}
|
||||
|
@ -270,6 +273,7 @@ class SelectWidgetSourceViewModel(
|
|||
if (
|
||||
view is BundledWidgetSourceView.AllObjects
|
||||
|| view is BundledWidgetSourceView.Bin
|
||||
|| view is BundledWidgetSourceView.Chat
|
||||
) {
|
||||
isDismissed.value = true
|
||||
}
|
||||
|
|
|
@ -109,10 +109,24 @@ sealed class Widget {
|
|||
override val id: Id = BundledWidgetSourceIds.ALL_OBJECTS
|
||||
override val type: Id? = null
|
||||
}
|
||||
|
||||
data object Chat : Bundled() {
|
||||
override val id: Id = BundledWidgetSourceIds.CHAT
|
||||
override val type: Id? = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<Widget>.forceChatPosition(): List<Widget> {
|
||||
// Partition the list into chat widgets and the rest
|
||||
val (chatWidgets, otherWidgets) = partition { widget ->
|
||||
widget.source is Widget.Source.Bundled.Chat
|
||||
}
|
||||
// Place chat widgets first, followed by the others
|
||||
return chatWidgets + otherWidgets
|
||||
}
|
||||
|
||||
fun Widget.hasValidLayout(): Boolean = when (val widgetSource = source) {
|
||||
is Widget.Source.Default -> isSupportedForWidgets(widgetSource.obj.layout)
|
||||
is Widget.Source.Bundled -> true
|
||||
|
@ -246,6 +260,7 @@ fun Id.bundled() : Widget.Source.Bundled = when (this) {
|
|||
BundledWidgetSourceIds.FAVORITE -> Widget.Source.Bundled.Favorites
|
||||
BundledWidgetSourceIds.BIN -> Widget.Source.Bundled.Bin
|
||||
BundledWidgetSourceIds.ALL_OBJECTS -> Widget.Source.Bundled.AllObjects
|
||||
BundledWidgetSourceIds.CHAT -> Widget.Source.Bundled.Chat
|
||||
else -> throw IllegalStateException("Widget bundled id can't be $this")
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ sealed class WidgetView {
|
|||
val canCreateObjectOfType : Boolean get() {
|
||||
return when(source) {
|
||||
Widget.Source.Bundled.AllObjects -> false
|
||||
Widget.Source.Bundled.Chat -> false
|
||||
Widget.Source.Bundled.Bin -> false
|
||||
Widget.Source.Bundled.Favorites -> true
|
||||
Widget.Source.Bundled.Recent -> false
|
||||
|
|
|
@ -29,6 +29,10 @@ sealed class BundledWidgetSourceView : DefaultSearchItem {
|
|||
data object AllObjects : BundledWidgetSourceView() {
|
||||
override val id: Id get() = BundledWidgetSourceIds.ALL_OBJECTS
|
||||
}
|
||||
|
||||
data object Chat : BundledWidgetSourceView() {
|
||||
override val id: Id get() = BundledWidgetSourceIds.CHAT
|
||||
}
|
||||
}
|
||||
|
||||
data class SuggestWidgetObjectType(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue