Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ package com.wire.android.mapper
import com.wire.android.R
import com.wire.android.ui.home.conversations.findUser
import com.wire.android.ui.home.conversations.model.UIMessageContent
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.ConversationStartedWithMembers
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.FederationMemberRemoved
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.MemberAdded
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.MemberFailedToAdd
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.MemberJoined
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.MemberLeft
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.MemberRemoved
import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessage.TeamMemberRemoved
import com.wire.android.ui.home.conversations.selfdeletion.SelfDeletionMapper.toSelfDeletionDuration
import com.wire.android.util.formatFullDateShortTime
import com.wire.android.util.orDefault
Expand Down Expand Up @@ -245,9 +253,9 @@ class SystemMessageContentMapper @Inject constructor(
return when (content) {
is Added ->
if (isAuthorSelfAction) {
UIMessageContent.SystemMessage.MemberJoined(author = authorName, isSelfTriggered = isSelfTriggered)
MemberJoined(author = authorName, isSelfTriggered = isSelfTriggered)
} else {
UIMessageContent.SystemMessage.MemberAdded(
MemberAdded(
author = authorName,
memberNames = memberNameList,
isSelfTriggered = isSelfTriggered
Expand All @@ -256,20 +264,20 @@ class SystemMessageContentMapper @Inject constructor(

is Removed ->
if (isAuthorSelfAction) {
UIMessageContent.SystemMessage.MemberLeft(author = authorName, isSelfTriggered = isSelfTriggered)
MemberLeft(author = authorName, isSelfTriggered = isSelfTriggered)
} else {
UIMessageContent.SystemMessage.MemberRemoved(
MemberRemoved(
author = authorName,
memberNames = memberNameList,
isSelfTriggered = isSelfTriggered
)
}

is CreationAdded -> {
UIMessageContent.SystemMessage.ConversationStartedWithMembers(memberNames = memberNameList)
ConversationStartedWithMembers(memberNames = memberNameList)
}

is FailedToAdd -> UIMessageContent.SystemMessage.MemberFailedToAdd(
is FailedToAdd -> MemberFailedToAdd(
memberNames = memberNameList,
type = when (content.type) {
FailedToAdd.Type.Federation -> UIMessageContent.SystemMessage.MemberFailedToAdd.Type.Federation
Expand All @@ -279,11 +287,11 @@ class SystemMessageContentMapper @Inject constructor(
}
)

is MemberChange.FederationRemoved -> UIMessageContent.SystemMessage.FederationMemberRemoved(
is MemberChange.FederationRemoved -> FederationMemberRemoved(
memberNames = memberNameList
)

is MemberChange.RemovedFromTeam -> UIMessageContent.SystemMessage.TeamMemberRemoved(
is MemberChange.RemovedFromTeam -> TeamMemberRemoved(
author = authorName,
memberNames = memberNameList
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ fun String.getBaseRoute(): String {
val Direction.baseRoute: String
get() = (this as? Route)?.baseRoute ?: route.getBaseRoute()

fun Direction.handleNavigation(context: Context, handleOtherDirection: (Direction) -> Unit) = when (this) {
fun Direction.handleNavigation(
context: Context,
handleOtherDirection: (Direction) -> Unit
) = when (this) {
is ExternalUriDirection -> CustomTabsHelper.launchUri(context, this.uri)
is ExternalUriStringResDirection -> CustomTabsHelper.launchUri(context, this.getUri(context.resources))
is IntentDirection -> context.startActivity(this.intent(context))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ import com.ramcosta.composedestinations.spec.Direction
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.util.EmailComposer
import com.wire.android.util.externalShareChooserIntent
import com.wire.android.util.getDeviceIdString
import com.wire.android.util.getGitBuildId
import com.wire.android.util.getMimeType
import com.wire.android.util.getUrisOfFilesInDirectory
import com.wire.android.util.logging.LogFileWriter
import com.wire.android.util.multipleFileSharingIntent
import com.wire.android.util.sha256

/**
Expand Down Expand Up @@ -104,39 +101,13 @@ object GiveFeedbackDestination : IntentDirection {
)
)
intent.selector = Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mailto:"))
return Intent.createChooser(intent, context.getString(R.string.send_feedback_choose_email))
return context.externalShareChooserIntent(intent, context.getString(R.string.send_feedback_choose_email))
}

override val route: String
get() = "wire-intent:give-feedback"
}

object ReportBugDestination : IntentDirection {
override fun intent(context: Context): Intent {
val dir = LogFileWriter.logsDirectory(context)
val logsUris = context.getUrisOfFilesInDirectory(dir)
val intent = context.multipleFileSharingIntent(logsUris)
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(context.getString(R.string.send_bug_report_email)))
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.send_bug_report_subject))
intent.putExtra(
Intent.EXTRA_TEXT,
EmailComposer.reportBugEmailTemplate(
context.getDeviceIdString()?.sha256(),
context.getGitBuildId()
)
)
val mimeTypes = logsUris.mapNotNull { it.getMimeType(context) }.toSet()
if (mimeTypes.isNotEmpty()) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes.toTypedArray())
}
intent.type = "*/*"
return Intent.createChooser(intent, context.getString(R.string.send_feedback_choose_email))
}

override val route: String
get() = "wire-intent:report-bug"
}

object WelcomeToNewAndroidAppDestination : ExternalUriStringResDirection {
override val uriStringRes: Int
get() = R.string.url_welcome_to_new_android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.ramcosta.composedestinations.generated.app.destinations.OtherUserProf
import com.ramcosta.composedestinations.generated.app.destinations.WelcomeScreenDestination
import com.wire.android.ui.authentication.login.LoginPasswordPath
import com.wire.android.ui.newauthentication.login.NewLoginViewModel
import com.wire.android.ui.sharing.ImportMediaNavArgs
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
Expand Down Expand Up @@ -86,10 +87,10 @@ private fun openConversation(action: OpenConversation, navigator: Navigator) {

private fun openImportMediaScreen(navigator: Navigator) {
navigator.navigate(
NavigationCommand(
ImportMediaScreenDestination,
BackStackMode.UPDATE_EXISTED
)
NavigationCommand(
ImportMediaScreenDestination(ImportMediaNavArgs(arrayListOf())),
BackStackMode.UPDATE_EXISTED
)
)
}

Expand Down
77 changes: 50 additions & 27 deletions app/src/main/kotlin/com/wire/android/ui/debug/DebugScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@

package com.wire.android.ui.debug

import com.wire.android.navigation.annotation.app.WireRootDestination
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
Expand All @@ -48,25 +47,24 @@ import com.wire.android.di.hiltViewModelScoped
import com.wire.android.model.Clickable
import com.wire.android.navigation.NavigationCommand
import com.wire.android.navigation.Navigator
import com.wire.android.navigation.annotation.app.WireRootDestination
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.scaffold.WireScaffold
import com.wire.android.ui.common.topappbar.NavigationIconType
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
import com.ramcosta.composedestinations.generated.app.destinations.ConversationCryptoStatsScreenDestination
import com.ramcosta.composedestinations.generated.app.destinations.DebugFeatureFlagsScreenDestination
import com.ramcosta.composedestinations.generated.app.destinations.ImportMediaScreenDestination
import com.wire.android.ui.common.rowitem.SectionHeader
import com.wire.android.ui.home.settings.SettingsItem
import com.wire.android.ui.home.settings.backup.BackupAndRestoreDialog
import com.wire.android.ui.home.settings.backup.rememberBackUpAndRestoreStateHolder
import com.wire.android.ui.sharing.ImportMediaNavArgs
import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.AppNameUtil
import com.wire.android.util.getMimeType
import com.wire.android.util.getUrisOfFilesInDirectory
import com.wire.android.util.multipleFileSharingIntent
import com.wire.android.util.logging.LogShareLauncher
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.launch
import java.io.File

@WireRootDestination
Expand All @@ -87,7 +85,14 @@ fun DebugScreen(
},
onShowCryptoStats = {
navigator.navigate(NavigationCommand(ConversationCryptoStatsScreenDestination))
}
},
onShareLogsViaWire = { uri ->
navigator.navigate(
NavigationCommand(
ImportMediaScreenDestination(ImportMediaNavArgs(arrayListOf(uri)))
)
)
},
)
}

Expand All @@ -99,6 +104,7 @@ internal fun UserDebugContent(
onDatabaseLoggerEnabledChanged: (Boolean) -> Unit,
onDeleteLogs: () -> Unit,
onFlushLogs: () -> Deferred<Unit>,
onShareLogsViaWire: (Uri) -> Unit,
onShowFeatureFlags: () -> Unit,
onShowCryptoStats: () -> Unit,
) {
Expand All @@ -125,7 +131,8 @@ internal fun UserDebugContent(
isLoggingEnabled = isLoggingEnabled,
onLoggingEnabledChange = onLoggingEnabledChange,
onDeleteLogs = onDeleteLogs,
onShareLogs = { debugContentState.shareLogs(onFlushLogs) },
onShareLogsExternally = { debugContentState.shareLogsExternally(onFlushLogs) },
onShareLogsViaWire = { debugContentState.shareLogsViaWire(onFlushLogs, onShareLogsViaWire) },
isDBLoggerEnabled = state.isDBLoggingEnabled,
onDBLoggerEnabledChange = onDatabaseLoggerEnabledChanged,
isPrivateBuild = BuildConfig.PRIVATE_BUILD,
Expand Down Expand Up @@ -193,14 +200,24 @@ fun rememberDebugContentState(logPath: String): DebugContentState {
val clipboardManager = LocalClipboardManager.current
val scrollState = rememberScrollState()
val coroutineScope = rememberCoroutineScope()
val shareLogsFailureMessage = stringResource(R.string.label_share_logs_failed)
val logShareLauncher = remember(context, coroutineScope, shareLogsFailureMessage) {
LogShareLauncher(
context = context,
coroutineScope = coroutineScope,
onFailure = {
Toast.makeText(context, shareLogsFailureMessage, Toast.LENGTH_SHORT).show()
}
)
}

return remember {
return remember(context, clipboardManager, logPath, scrollState, logShareLauncher) {
DebugContentState(
context,
clipboardManager,
logPath,
scrollState,
coroutineScope
logShareLauncher
)
}
}
Expand All @@ -210,7 +227,7 @@ data class DebugContentState(
val clipboardManager: ClipboardManager,
val logPath: String,
val scrollState: ScrollState,
val coroutineScope: CoroutineScope
val logShareLauncher: LogShareLauncher
) {
fun copyToClipboard(text: String) {
clipboardManager.setText(AnnotatedString(text))
Expand All @@ -221,21 +238,26 @@ data class DebugContentState(
).show()
}

fun shareLogs(onFlushLogs: () -> Deferred<Unit>) {
coroutineScope.launch {
// Flush any buffered logs before sharing to ensure completeness
onFlushLogs().await()
val dir = File(logPath).parentFile
val fileUris =
if (dir != null && dir.exists()) context.getUrisOfFilesInDirectory(dir) else arrayListOf()
val intent = context.multipleFileSharingIntent(fileUris)
// The first log file is simply text, not compressed. Get its mime type separately
// and set it as the mime type for the intent.
intent.type = fileUris.firstOrNull()?.getMimeType(context) ?: "text/plain"
// Get all other mime types and add them
val mimeTypes = fileUris.drop(1).mapNotNull { it.getMimeType(context) }
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes.toSet().toTypedArray())
context.startActivity(intent)
fun shareLogsExternally(onFlushLogs: () -> Deferred<Unit>) {
val dir = File(logPath).parentFile
if (dir != null && dir.exists()) {
logShareLauncher.shareLogs(dir) {
// Flush any buffered logs before sharing to ensure completeness.
onFlushLogs().await()
}
}
}

fun shareLogsViaWire(onFlushLogs: () -> Deferred<Unit>, onShareUri: (Uri) -> Unit) {
val dir = File(logPath).parentFile
if (dir != null && dir.exists()) {
logShareLauncher.shareLogsViaWire(
logsDirectory = dir,
onShareUri = onShareUri
) {
// Flush any buffered logs before sharing to ensure completeness.
onFlushLogs().await()
}
}
}
}
Expand All @@ -252,6 +274,7 @@ internal fun PreviewUserDebugContent() = WireTheme {
onLoggingEnabledChange = {},
onDeleteLogs = {},
onFlushLogs = { CompletableDeferred(Unit) },
onShareLogsViaWire = {},
onDatabaseLoggerEnabledChanged = {},
onShowFeatureFlags = {},
onShowCryptoStats = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package com.wire.android.ui.debug

import com.ramcosta.composedestinations.generated.app.destinations.ImportMediaScreenDestination
import com.wire.android.navigation.annotation.app.WireRootDestination
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -27,11 +28,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import com.wire.android.R
import com.wire.android.navigation.NavigationCommand
import com.wire.android.navigation.Navigator
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.scaffold.WireScaffold
import com.wire.android.ui.common.topappbar.NavigationIconType
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
import com.wire.android.ui.sharing.ImportMediaNavArgs

@WireRootDestination
@Composable
Expand Down Expand Up @@ -64,7 +67,16 @@ fun LogManagementScreen(
isLoggingEnabled = state.isLoggingEnabled,
onLoggingEnabledChange = viewModel::setLoggingEnabledState,
onDeleteLogs = viewModel::deleteLogs,
onShareLogs = { contentState.shareLogs(viewModel::flushLogs) },
onShareLogsExternally = { contentState.shareLogsExternally(viewModel::flushLogs) },
onShareLogsViaWire = {
contentState.shareLogsViaWire(viewModel::flushLogs) { uri ->
navigator.navigate(
NavigationCommand(
ImportMediaScreenDestination(ImportMediaNavArgs(arrayListOf(uri)))
)
)
}
},
isDBLoggerEnabled = false,
onDBLoggerEnabledChange = {},
isPrivateBuild = false
Expand Down
Loading
Loading