Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: share text to wire (WPB-1872) #2168

Merged
merged 5 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 12 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@
<data android:mimeType="audio/*" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
Expand All @@ -165,6 +171,12 @@
<data android:mimeType="audio/*" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.wire.kalium.logic.feature.asset.ScheduleNewAssetMessageResult
import com.wire.kalium.logic.feature.asset.ScheduleNewAssetMessageUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationListDetailsUseCase
import com.wire.kalium.logic.feature.message.SendTextMessageUseCase
import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase
import com.wire.kalium.logic.feature.selfDeletingMessages.PersistNewSelfDeletionTimerUseCase
import com.wire.kalium.logic.feature.selfDeletingMessages.SelfDeletionTimer
Expand Down Expand Up @@ -78,6 +79,7 @@
private val observeConversationListDetails: ObserveConversationListDetailsUseCase,
private val fileManager: FileManager,
private val sendAssetMessage: ScheduleNewAssetMessageUseCase,
private val sendTextMessage: SendTextMessageUseCase,

Check warning on line 82 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L82

Added line #L82 was not covered by tests
private val kaliumFileSystem: KaliumFileSystem,
private val getAssetSizeLimit: GetAssetSizeLimitUseCase,
private val persistNewSelfDeletionTimerUseCase: PersistNewSelfDeletionTimerUseCase,
Expand Down Expand Up @@ -260,8 +262,7 @@
appLogger.e("Received data from sharing intent ${incomingIntent.streamCount}")
importMediaState = importMediaState.copy(isImporting = true)
if (incomingIntent.streamCount == 0) {
// if stream count is 0 the type will be text, we check the type to double check if it is text
// todo : handle the text , we can get the text from incomingIntent.text
handleSharedText(incomingIntent.text.toString())

Check warning on line 265 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L265

Added line #L265 was not covered by tests
} else {
if (incomingIntent.isSingleShare) {
// ACTION_SEND
Expand All @@ -274,6 +275,10 @@
importMediaState = importMediaState.copy(isImporting = false)
}

private fun handleSharedText(text: String) {
importMediaState = importMediaState.copy(importedText = text)
}

Check warning on line 280 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L279-L280

Added lines #L279 - L280 were not covered by tests

private suspend fun handleSingleIntent(
incomingIntent: ShareCompat.IntentReader,
activity: AppCompatActivity
Expand Down Expand Up @@ -303,45 +308,58 @@
importMediaState = importMediaState.copy(importedAssets = importedMediaAssets)
}

fun checkRestrictionsAndSendImportedMedia(onSent: (ConversationId) -> Unit) = viewModelScope.launch(dispatchers.default()) {
val conversation = importMediaState.selectedConversationItem.firstOrNull() ?: return@launch
val assetsToSend = importMediaState.importedAssets
fun checkRestrictionsAndSendImportedMedia(onSent: (ConversationId) -> Unit) =
viewModelScope.launch(dispatchers.default()) {
val conversation =

Check warning on line 313 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L312-L313

Added lines #L312 - L313 were not covered by tests
importMediaState.selectedConversationItem.firstOrNull() ?: return@launch
val assetsToSend = importMediaState.importedAssets
val textToSend = importMediaState.importedText

Check warning on line 316 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L315-L316

Added lines #L315 - L316 were not covered by tests

if (assetsToSend.size > MAX_LIMIT_MEDIA_IMPORT) {
onSnackbarMessage(ImportMediaSnackbarMessages.MaxAmountOfAssetsReached)
} else {
val jobs: MutableCollection<Job> = mutableListOf()
assetsToSend.forEach { importedAsset ->
val isImage = importedAsset is ImportedMediaAsset.Image
val job = viewModelScope.launch {
sendAssetMessage(
if (assetsToSend.size > MAX_LIMIT_MEDIA_IMPORT) {
onSnackbarMessage(ImportMediaSnackbarMessages.MaxAmountOfAssetsReached)

Check warning on line 319 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L319

Added line #L319 was not covered by tests
} else {
val jobs: MutableCollection<Job> = mutableListOf()

Check warning on line 321 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L321

Added line #L321 was not covered by tests

textToSend?.let {
sendTextMessage(

Check warning on line 324 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L324

Added line #L324 was not covered by tests
conversationId = conversation.conversationId,
assetDataPath = importedAsset.dataPath,
assetName = importedAsset.name,
assetDataSize = importedAsset.size,
assetMimeType = importedAsset.mimeType,
assetWidth = if (isImage) (importedAsset as ImportedMediaAsset.Image).width else 0,
assetHeight = if (isImage) (importedAsset as ImportedMediaAsset.Image).height else 0,
audioLengthInMs = getAudioLengthInMs(
dataPath = importedAsset.dataPath,
mimeType = importedAsset.mimeType
)
).also {
if (it is ScheduleNewAssetMessageResult.Failure) {
appLogger.e("Failed to import asset message to conversationId=${conversation.conversationId.toLogString()} ")
} else {
appLogger.d("Success importing asset message to conversationId=${conversation.conversationId.toLogString()}")
text = it

Check warning on line 326 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L326

Added line #L326 was not covered by tests
)
} ?: assetsToSend.forEach { importedAsset ->
val isImage = importedAsset is ImportedMediaAsset.Image

Check warning on line 329 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L328-L329

Added lines #L328 - L329 were not covered by tests
val job = viewModelScope.launch {
sendAssetMessage(
conversationId = conversation.conversationId,
assetDataPath = importedAsset.dataPath,
assetName = importedAsset.name,
assetDataSize = importedAsset.size,
assetMimeType = importedAsset.mimeType,

Check warning on line 336 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L331-L336

Added lines #L331 - L336 were not covered by tests
assetWidth = if (isImage) (importedAsset as ImportedMediaAsset.Image).width else 0,
assetHeight = if (isImage) (importedAsset as ImportedMediaAsset.Image).height else 0,
audioLengthInMs = getAudioLengthInMs(
dataPath = importedAsset.dataPath,
mimeType = importedAsset.mimeType

Check warning on line 341 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L339-L341

Added lines #L339 - L341 were not covered by tests
)
).also {
val logConversationId = conversation.conversationId.toLogString()

Check warning on line 344 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L343-L344

Added lines #L343 - L344 were not covered by tests
if (it is ScheduleNewAssetMessageResult.Failure) {
appLogger.e("Failed to import asset message to " +
"conversationId=$logConversationId")

Check warning on line 347 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L346-L347

Added lines #L346 - L347 were not covered by tests
} else {
appLogger.d("Success importing asset message to " +
"conversationId=$logConversationId")

Check warning on line 350 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L349-L350

Added lines #L349 - L350 were not covered by tests
}
}
}
jobs.add(job)
}

Check warning on line 355 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L354-L355

Added lines #L354 - L355 were not covered by tests

jobs.joinAll()

Check warning on line 357 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L357

Added line #L357 was not covered by tests
withContext(dispatchers.main()) {
onSent(conversation.conversationId)

Check warning on line 359 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L359

Added line #L359 was not covered by tests
}
jobs.add(job)
}
jobs.joinAll()
withContext(dispatchers.main()) {
onSent(conversation.conversationId)
}
}
}

fun onNewConversationPicked(conversationId: ConversationId) = viewModelScope.launch {
importMediaState = importMediaState.copy(
Expand Down Expand Up @@ -455,6 +473,7 @@
data class ImportMediaAuthenticatedState(
val avatarAsset: ImageAsset.UserAvatarAsset? = null,
val importedAssets: List<ImportedMediaAsset> = emptyList(),
val importedText: String? = null,

Check warning on line 476 in app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt#L476

Added line #L476 was not covered by tests
val isImporting: Boolean = false,
val shareableConversationListState: ShareableConversationListState = ShareableConversationListState(),
val selectedConversationItem: List<ConversationItem> = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
Expand All @@ -34,8 +36,6 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.wire.android.R
Expand Down Expand Up @@ -69,8 +69,8 @@ import com.wire.android.util.CustomTabsHelper
import com.wire.android.util.extension.getActivity
import com.wire.android.util.ui.LinkText
import com.wire.android.util.ui.LinkTextData
import com.wire.kalium.logic.util.isPositiveNotNull
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.util.isPositiveNotNull
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
Expand All @@ -84,7 +84,8 @@ fun ImportMediaScreen(
) {
featureFlagNotificationViewModel.loadInitialSync()

when (val fileSharingRestrictedState = featureFlagNotificationViewModel.featureFlagState.fileSharingRestrictedState) {
when (val fileSharingRestrictedState =
featureFlagNotificationViewModel.featureFlagState.fileSharingRestrictedState) {
FeatureFlagState.SharingRestrictedState.NO_USER -> {
ImportMediaLoggedOutContent(
fileSharingRestrictedState = fileSharingRestrictedState,
Expand All @@ -109,7 +110,12 @@ fun ImportMediaScreen(
onConversationClicked = importMediaViewModel::onConversationClicked,
checkRestrictionsAndSendImportedMedia = {
importMediaViewModel.checkRestrictionsAndSendImportedMedia {
navigator.navigate(NavigationCommand(ConversationScreenDestination(it), BackStackMode.CLEAR_TILL_START))
navigator.navigate(
NavigationCommand(
ConversationScreenDestination(it),
BackStackMode.CLEAR_TILL_START
)
)
}
},
onNewSelfDeletionTimerPicked = importMediaViewModel::onNewSelfDeletionTimerPicked,
Expand All @@ -119,7 +125,8 @@ fun ImportMediaScreen(
val context = LocalContext.current
LaunchedEffect(importMediaViewModel.importMediaState.importedAssets) {
if (importMediaViewModel.importMediaState.importedAssets.isEmpty()) {
context.getActivity()?.let { importMediaViewModel.handleReceivedDataFromSharingIntent(it) }
context.getActivity()
?.let { importMediaViewModel.handleReceivedDataFromSharingIntent(it) }
}
}
}
Expand Down Expand Up @@ -271,11 +278,12 @@ fun FileSharingRestrictedContent(
.padding(internalPadding)
.padding(horizontal = dimensions().spacing48x)
) {
val textRes = if (sharingRestrictedState == FeatureFlagState.SharingRestrictedState.NO_USER) {
R.string.file_sharing_restricted_description_no_users
} else {
R.string.file_sharing_restricted_description_by_team
}
val textRes =
if (sharingRestrictedState == FeatureFlagState.SharingRestrictedState.NO_USER) {
R.string.file_sharing_restricted_description_no_users
} else {
R.string.file_sharing_restricted_description_by_team
}
Text(
text = stringResource(textRes),
textAlign = TextAlign.Center,
Expand Down Expand Up @@ -318,9 +326,11 @@ private fun ImportMediaBottomBar(
} else {
stringResource(id = R.string.import_media_send_button_title)
}
val buttonCount =
if (state.importedAssets.isNotEmpty() || state.importedText != null) state.selectedConversationItem.size else 0
SendContentButton(
mainButtonText = mainButtonText,
count = if (state.importedAssets.isNotEmpty()) state.selectedConversationItem.size else 0,
count = buttonCount,
onMainButtonClick = checkRestrictionsAndSendImportedMedia,
selfDeletionTimer = selfDeletionTimer,
onSelfDeletionTimerClicked = importMediaScreenState::showBottomSheetMenu,
Expand Down Expand Up @@ -348,9 +358,13 @@ private fun ImportMediaContent(
) {
val horizontalPadding = dimensions().spacing8x
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val itemWidth = if (isMultipleImport) dimensions().importedMediaAssetSize + horizontalPadding.times(2)
else screenWidth - (horizontalPadding * 2)
val contentPadding = PaddingValues(start = horizontalPadding, end = (screenWidth - itemWidth + horizontalPadding))
val itemWidth =
if (isMultipleImport) dimensions().importedMediaAssetSize + horizontalPadding.times(2)
else screenWidth - (horizontalPadding * 2)
val contentPadding = PaddingValues(
start = horizontalPadding,
end = (screenWidth - itemWidth + horizontalPadding)
)
val lazyListState = rememberLazyListState()
if (state.isImporting) {
Box(
Expand Down Expand Up @@ -379,7 +393,11 @@ private fun ImportMediaContent(
}
}
}
Divider(color = colorsScheme().outline, thickness = 1.dp, modifier = Modifier.padding(top = dimensions().spacing12x))
Divider(
color = colorsScheme().outline,
thickness = 1.dp,
modifier = Modifier.padding(top = dimensions().spacing12x)
)
Box(Modifier.padding(dimensions().spacing6x)) {
SearchTopBar(
isSearchActive = searchBarState.isSearchActive,
Expand Down Expand Up @@ -420,7 +438,10 @@ private fun ImportMediaContent(
}

@Composable
private fun SnackBarMessage(infoMessages: SharedFlow<SnackBarMessage>, snackbarHostState: SnackbarHostState) {
private fun SnackBarMessage(
infoMessages: SharedFlow<SnackBarMessage>,
snackbarHostState: SnackbarHostState
) {
val context = LocalContext.current
LaunchedEffect(Unit) {
infoMessages.collect { message ->
Expand All @@ -438,13 +459,23 @@ fun PreviewImportMediaScreenLoggedOut() {
@Preview(showBackground = true)
@Composable
fun PreviewImportMediaScreenRestricted() {
ImportMediaRestrictedContent(FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM, ImportMediaAuthenticatedState()) {}
ImportMediaRestrictedContent(
FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM,
ImportMediaAuthenticatedState()
) {}
}

@Preview(showBackground = true)
@Composable
fun PreviewImportMediaScreenRegular() {
ImportMediaRegularContent(ImportMediaAuthenticatedState(), {}, {}, {}, {}, MutableSharedFlow()) {}
ImportMediaRegularContent(
ImportMediaAuthenticatedState(),
{},
{},
{},
{},
MutableSharedFlow()
) {}
}

@Preview(showBackground = true)
Expand Down
Loading