Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ithub.com:anyproto/anytype-kotlin into droid-3185-file-layout-hide-file-block
  • Loading branch information
konstantiniiv committed Dec 23, 2024
2 parents 88fbd06 + 2c3784c commit 45e692e
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.anytypeio.anytype.di.feature.discussions

import android.content.Context
import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
Expand All @@ -21,11 +22,14 @@ import com.anytypeio.anytype.feature_discussions.presentation.DiscussionViewMode
import com.anytypeio.anytype.feature_discussions.presentation.DiscussionViewModelFactory
import com.anytypeio.anytype.middleware.EventProxy
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
import com.anytypeio.anytype.presentation.util.DefaultCopyFileToCacheDirectory
import com.anytypeio.anytype.ui.home.HomeScreenFragment
import dagger.Binds
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import dagger.Provides

@Component(
dependencies = [DiscussionComponentDependencies::class],
Expand Down Expand Up @@ -68,6 +72,14 @@ interface SpaceLevelChatComponent {

@Module
object DiscussionModule {

@JvmStatic
@Provides
@PerScreen
fun provideCopyFileToCache(
context: Context
): CopyFileToCacheDirectory = DefaultCopyFileToCacheDirectory(context)

@Module
interface Declarations {
@PerScreen
Expand All @@ -93,4 +105,5 @@ interface DiscussionComponentDependencies : ComponentDependencies {
fun members(): ActiveSpaceMemberSubscriptionContainer
fun spaceViewSubscriptionContainer(): SpaceViewSubscriptionContainer
fun storeOfObjectTypes(): StoreOfObjectTypes
fun context(): Context
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.fragment.findNavController
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.features.multiplayer.SpaceListScreen
import com.anytypeio.anytype.core_ui.foundation.Warning
Expand All @@ -29,6 +30,7 @@ import com.anytypeio.anytype.presentation.spaces.SpaceListViewModel
import com.anytypeio.anytype.ui.settings.typography
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber

class SpaceListFragment : BaseBottomSheetComposeFragment() {

Expand All @@ -53,7 +55,16 @@ class SpaceListFragment : BaseBottomSheetComposeFragment() {
state = vm.state.collectAsStateWithLifecycle().value,
onDeleteSpaceClicked = vm::onDeleteSpaceClicked,
onLeaveSpaceClicked = vm::onLeaveSpaceClicked,
onCancelJoinRequestClicked = vm::onCancelJoinSpaceClicked
onCancelJoinRequestClicked = vm::onCancelJoinSpaceClicked,
onCreateSpaceClicked = {
runCatching {
findNavController().navigate(
R.id.actionCreateSpaceFromVault
)
}.onFailure {
Timber.e(it, "Error while opening create-space screen from vault")
}
}
)
}

Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/navigation/graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,11 @@
<dialog
android:id="@+id/spaceListScreen"
android:name="com.anytypeio.anytype.ui.spaces.SpaceListFragment"
android:label="SpaceListScreen"/>
android:label="SpaceListScreen">
<action
android:id="@+id/actionCreateSpaceFromVault"
app:destination="@id/createSpaceScreen" />
</dialog>

<dialog
android:id="@+id/objectSetIconPickerScreenForSpace"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
import com.anytypeio.anytype.core_ui.features.SpaceIconView
import com.anytypeio.anytype.core_ui.foundation.Divider
import com.anytypeio.anytype.core_ui.foundation.Dragger
import com.anytypeio.anytype.core_ui.foundation.Header
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
import com.anytypeio.anytype.core_ui.views.BodyRegular
import com.anytypeio.anytype.core_ui.views.ButtonSecondary
import com.anytypeio.anytype.core_ui.views.ButtonSize
import com.anytypeio.anytype.core_ui.views.Relations2
import com.anytypeio.anytype.core_ui.views.Relations3
import com.anytypeio.anytype.core_ui.views.Title2
Expand All @@ -57,7 +60,8 @@ fun SpaceListScreen(
state: ViewState<List<SpaceListItemView>>,
onDeleteSpaceClicked: (SpaceListItemView) -> Unit,
onLeaveSpaceClicked: (SpaceListItemView) -> Unit,
onCancelJoinRequestClicked: (SpaceListItemView) -> Unit
onCancelJoinRequestClicked: (SpaceListItemView) -> Unit,
onCreateSpaceClicked: () -> Unit,
) {
Column(
modifier = Modifier
Expand All @@ -71,7 +75,9 @@ fun SpaceListScreen(
)
Header(text = stringResource(id = R.string.multiplayer_spaces))
LazyColumn(
modifier = Modifier.fillMaxWidth().weight(1.0f)
modifier = Modifier
.fillMaxWidth()
.weight(1.0f)
) {
if (state is ViewState.Success) {
itemsIndexed(
Expand Down Expand Up @@ -102,11 +108,49 @@ fun SpaceListScreen(
},
key = { _, item -> "space-list-item-${item.space.id}" }
)
if (state.data.isEmpty()) {
item {
SpaceListEmptyState(
onCreateSpaceClicked = onCreateSpaceClicked,
modifier = Modifier.fillParentMaxSize()
)
}
}
}
}
}
}

@Composable
fun SpaceListEmptyState(
modifier: Modifier = Modifier,
onCreateSpaceClicked: () -> Unit
) {
Box(modifier = modifier) {
Column(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.space_list_empty_state_it_is_empty_here),
color = colorResource(R.color.text_primary)
)
Text(
text = stringResource(R.string.space_list_empty_state_create_your_first_space_to_get_started),
color = colorResource(R.color.text_secondary)
)
Spacer(modifier = Modifier.height(16.dp))
ButtonSecondary(
onClick = onCreateSpaceClicked,
text = "Create space",
size = ButtonSize.SmallSecondary
)
}
}
}

@Composable
fun SpaceListCardItem(
spaceName: String,
Expand Down Expand Up @@ -357,7 +401,8 @@ private fun SpaceListScreenPreview() {
state = ViewState.Loading,
onCancelJoinRequestClicked = {},
onDeleteSpaceClicked = {},
onLeaveSpaceClicked = {}
onLeaveSpaceClicked = {},
onCreateSpaceClicked = {}
)
}

Expand All @@ -376,5 +421,12 @@ private fun SpaceCardItemPreview() {
)
}

@DefaultPreviews
@Composable
private fun SpaceListEmptyStatePreview() {
SpaceListEmptyState(
onCreateSpaceClicked = {}
)
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.anytypeio.anytype.core_utils.common

data class DefaultFileInfo(
val name: String,
val uri: String,
val size: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ sealed interface DiscussionView {
val uri: String
): ChatBoxAttachment()
data class File(
val uri: String
val uri: String,
val name: String,
val size: Int
): ChatBoxAttachment()
data class Link(
val target: Id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.chats.Chat
import com.anytypeio.anytype.core_models.primitives.Space
import com.anytypeio.anytype.core_ui.text.splitByMarks
import com.anytypeio.anytype.core_utils.common.DefaultFileInfo
import com.anytypeio.anytype.core_utils.ext.withLatestFrom
import com.anytypeio.anytype.domain.auth.interactor.GetAccount
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
Expand All @@ -35,6 +36,7 @@ import com.anytypeio.anytype.presentation.home.navigation
import com.anytypeio.anytype.presentation.mapper.objectIcon
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import com.anytypeio.anytype.presentation.search.GlobalSearchItemView
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
import java.sql.Types
import javax.inject.Inject
import kotlinx.coroutines.delay
Expand All @@ -44,6 +46,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.combineLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber

class DiscussionViewModel @Inject constructor(
Expand All @@ -61,7 +64,8 @@ class DiscussionViewModel @Inject constructor(
private val spaceViews: SpaceViewSubscriptionContainer,
private val dispatchers: AppCoroutineDispatchers,
private val uploadFile: UploadFile,
private val storeOfObjectTypes: StoreOfObjectTypes
private val storeOfObjectTypes: StoreOfObjectTypes,
private val copyFileToCacheDirectory: CopyFileToCacheDirectory
) : BaseViewModel() {

val name = MutableStateFlow<String?>(null)
Expand Down Expand Up @@ -265,18 +269,26 @@ class DiscussionViewModel @Inject constructor(
}
}
is DiscussionView.Message.ChatBoxAttachment.File -> {
uploadFile.async(
UploadFile.Params(
space = vmParams.space,
path = attachment.uri
)
).onSuccess { file ->
add(
Chat.Message.Attachment(
target = file.id,
type = Chat.Message.Attachment.Type.Image
val path = withContext(dispatchers.io) {
copyFileToCacheDirectory.copy(attachment.uri)
}
if (path != null) {
uploadFile.async(
UploadFile.Params(
space = vmParams.space,
path = path
)
)
).onSuccess { file ->
// TODO delete file.
add(
Chat.Message.Attachment(
target = file.id,
type = Chat.Message.Attachment.Type.File
)
)
}.onFailure {
Timber.e(it, "Error while uploading file as attachment")
}
}
}
}
Expand Down Expand Up @@ -469,11 +481,13 @@ class DiscussionViewModel @Inject constructor(
}
}

fun onChatBoxFilePicked(uris: List<String>) {
Timber.d("onChatBoxFilePicked: $uris")
chatBoxAttachments.value = chatBoxAttachments.value + uris.map {
fun onChatBoxFilePicked(infos: List<DefaultFileInfo>) {
Timber.d("onChatBoxFilePicked: $infos")
chatBoxAttachments.value = chatBoxAttachments.value + infos.map { info ->
DiscussionView.Message.ChatBoxAttachment.File(
uri = it
uri = info.uri,
name = info.name,
size = info.size
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.anytypeio.anytype.domain.`object`.OpenObject
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
import javax.inject.Inject

class DiscussionViewModelFactory @Inject constructor(
Expand All @@ -35,7 +36,8 @@ class DiscussionViewModelFactory @Inject constructor(
private val spaceViews: SpaceViewSubscriptionContainer,
private val dispatchers: AppCoroutineDispatchers,
private val uploadFile: UploadFile,
private val storeOfObjectTypes: StoreOfObjectTypes
private val storeOfObjectTypes: StoreOfObjectTypes,
private val copyFileToCacheDirectory: CopyFileToCacheDirectory
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = DiscussionViewModel(
Expand All @@ -53,6 +55,7 @@ class DiscussionViewModelFactory @Inject constructor(
spaceViews = spaceViews,
dispatchers = dispatchers,
uploadFile = uploadFile,
storeOfObjectTypes = storeOfObjectTypes
storeOfObjectTypes = storeOfObjectTypes,
copyFileToCacheDirectory = copyFileToCacheDirectory
) as T
}
Loading

0 comments on commit 45e692e

Please sign in to comment.