From 84ce5df2d7577a909fdf81c91ce683a76f9e45aa Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Fri, 14 Feb 2025 13:34:49 +0100 Subject: [PATCH 1/6] migrate diagnosis screen to compose Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/diagnose/AppBar.kt | 47 +++ .../talk/diagnose/DiagnoseActivity.kt | 378 ++++++++++-------- .../diagnose/DiagnoseContentComposable.kt | 77 ++++ app/src/main/res/layout/activity_diagnose.xml | 46 --- 4 files changed, 326 insertions(+), 222 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt create mode 100644 app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt delete mode 100644 app/src/main/res/layout/activity_diagnose.xml diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt b/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt new file mode 100644 index 000000000..cf9216a69 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt @@ -0,0 +1,47 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Marcel Hibbe + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.diagnose + +import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import com.nextcloud.talk.R + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AppBar(title: String) { + val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher + + TopAppBar( + title = { Text(text = title) }, + navigationIcon = { + IconButton( + onClick = { backDispatcher?.onBackPressed() } + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back_button) + ) + } + } + ) +} + +@Preview(showBackground = true) +@Composable +fun AppBarPreview() { + AppBar("title") +} diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt index bbf8bb240..b8104995e 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -9,24 +9,27 @@ package com.nextcloud.talk.diagnose import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager -import android.content.Context import android.content.Intent -import android.graphics.Typeface -import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Build import android.os.Build.MANUFACTURER import android.os.Build.MODEL import android.os.Bundle import android.text.SpannableStringBuilder -import android.util.TypedValue import android.view.Menu import android.view.MenuItem -import android.view.ViewGroup -import android.widget.TextView import android.widget.Toast -import androidx.core.text.bold -import androidx.core.view.updateLayoutParams +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.stringResource import autodagger.AutoInjector import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R @@ -34,7 +37,6 @@ import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager -import com.nextcloud.talk.databinding.ActivityDiagnoseBinding import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.BrandingUtils import com.nextcloud.talk.utils.ClosedInterfaceImpl @@ -50,7 +52,6 @@ import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @Suppress("TooManyFunctions") class DiagnoseActivity : BaseActivity() { - private lateinit var binding: ActivityDiagnoseBinding @Inject lateinit var arbitraryStorageManager: ArbitraryStorageManager @@ -66,16 +67,44 @@ class DiagnoseActivity : BaseActivity() { private var isGooglePlayServicesAvailable: Boolean = false - private val markdownText = SpannableStringBuilder() + sealed class DiagnoseElement { + data class DiagnoseHeadline(val headline: String) : DiagnoseElement() + data class DiagnoseEntry(val key: String, val value: String) : DiagnoseElement() + } + + private val diagnoseData = mutableListOf() + private val diagnoseDataState = mutableStateOf(emptyList()) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) - binding = ActivityDiagnoseBinding.inflate(layoutInflater) - setupActionBar() - setContentView(binding.root) - setupSystemColors() + val colorScheme = viewThemeUtils.getColorScheme(this) + + setContent { + val backgroundColor = colorResource(id = R.color.bg_default) + MaterialTheme( + colorScheme = colorScheme + ) { + Scaffold( + topBar = { + AppBar( + title = stringResource(R.string.nc_settings_diagnose_title) + ) + }, + content = { + Column( + Modifier + .padding(it) + .background(backgroundColor) + .fillMaxSize() + ) { + DiagnoseContentComposable(diagnoseDataState) + } + } + ) + } + } } override fun onResume() { @@ -84,25 +113,13 @@ class DiagnoseActivity : BaseActivity() { isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable - markdownText.clear() + diagnoseData.clear() setupMetaValues() setupPhoneValues() setupAppValues() setupAccountValues() - createLayoutFromMarkdown() - } - - private fun setupActionBar() { - setSupportActionBar(binding.settingsToolbar) - binding.settingsToolbar.setNavigationOnClickListener { - onBackPressedDispatcher.onBackPressed() - } - supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setDisplayShowHomeEnabled(true) - supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent, null))) - supportActionBar?.title = context.getString(R.string.nc_settings_diagnose_title) - viewThemeUtils.material.themeToolbar(binding.settingsToolbar) + diagnoseDataState.value = diagnoseData.toList() } override fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -124,22 +141,22 @@ class DiagnoseActivity : BaseActivity() { } R.id.copy -> { - copyToClipboard(markdownText.toString()) + copyToClipboard(diagnoseData.toMarkdownString()) true } R.id.share -> { - shareToOtherApps(markdownText.toString()) + shareToOtherApps(diagnoseData.toMarkdownString()) true } R.id.send_mail -> { - composeEmail(markdownText.toString()) + composeEmail(diagnoseData.toMarkdownString()) true } R.id.create_issue -> { - createGithubIssue(markdownText.toString()) + createGithubIssue(diagnoseData.toMarkdownString()) true } @@ -185,7 +202,7 @@ class DiagnoseActivity : BaseActivity() { private fun copyToClipboard(text: String) { val clipboardManager = - getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + getSystemService(CLIPBOARD_SERVICE) as ClipboardManager val clipData = ClipData.newPlainText( resources?.getString(R.string.nc_app_product_name), text @@ -201,25 +218,35 @@ class DiagnoseActivity : BaseActivity() { private fun setupMetaValues() { addHeadline(context.resources.getString(R.string.nc_diagnose_meta_category_title)) - addKey(context.resources.getString(R.string.nc_diagnose_meta_system_report_date)) - addValue(DisplayUtils.unixTimeToHumanReadable(System.currentTimeMillis())) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_meta_system_report_date), + value = DisplayUtils.unixTimeToHumanReadable(System.currentTimeMillis()) + ) } private fun setupPhoneValues() { addHeadline(context.resources.getString(R.string.nc_diagnose_phone_category_title)) - addKey(context.resources.getString(R.string.nc_diagnose_device_name_title)) - addValue(getDeviceName()) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_device_name_title), + value = getDeviceName() + ) - addKey(context.resources.getString(R.string.nc_diagnose_android_version_title)) - addValue(Build.VERSION.SDK_INT.toString()) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_android_version_title), + value = Build.VERSION.SDK_INT.toString() + ) if (isGooglePlayServicesAvailable) { - addKey(context.resources.getString(R.string.nc_diagnose_gplay_available_title)) - addValue(context.resources.getString(R.string.nc_diagnose_gplay_available_yes)) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_gplay_available_title), + value = context.resources.getString(R.string.nc_diagnose_gplay_available_yes) + ) } else { - addKey(context.resources.getString(R.string.nc_diagnose_gplay_available_title)) - addValue(context.resources.getString(R.string.nc_diagnose_gplay_available_no)) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_gplay_available_title), + value = context.resources.getString(R.string.nc_diagnose_gplay_available_no) + ) } } @@ -228,81 +255,101 @@ class DiagnoseActivity : BaseActivity() { private fun setupAppValues() { addHeadline(context.resources.getString(R.string.nc_diagnose_app_category_title)) - addKey(context.resources.getString(R.string.nc_diagnose_app_name_title)) - addValue(context.resources.getString(R.string.nc_app_product_name)) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_app_name_title), + value = context.resources.getString(R.string.nc_app_product_name) + ) - addKey(context.resources.getString(R.string.nc_diagnose_app_version_title)) - addValue(String.format("v" + BuildConfig.VERSION_NAME)) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_app_version_title), + value = String.format("v" + BuildConfig.VERSION_NAME) + ) - addKey(context.resources.getString(R.string.nc_diagnose_flavor)) - addValue(BuildConfig.FLAVOR) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_flavor), + value = BuildConfig.FLAVOR + ) if (isGooglePlayServicesAvailable) { setupAppValuesForGooglePlayServices() } - addKey(context.resources.getString(R.string.nc_diagnose_app_users_amount)) - addValue(userManager.users.blockingGet().size.toString()) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_app_users_amount), + value = userManager.users.blockingGet().size.toString() + ) } + @Suppress("Detekt.LongMethod") private fun setupAppValuesForGooglePlayServices() { - addKey(context.resources.getString(R.string.nc_diagnose_battery_optimization_title)) - - if (PowerManagerUtils().isIgnoringBatteryOptimizations()) { - addValue(context.resources.getString(R.string.nc_diagnose_battery_optimization_ignored)) - } else { - addValue(context.resources.getString(R.string.nc_diagnose_battery_optimization_not_ignored)) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_battery_optimization_title), + value = if (PowerManagerUtils().isIgnoringBatteryOptimizations()) { + context.resources.getString(R.string.nc_diagnose_battery_optimization_ignored) + } else { + context.resources.getString(R.string.nc_diagnose_battery_optimization_not_ignored) + } + ) // handle notification permission on API level >= 33 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - addKey(context.resources.getString(R.string.nc_diagnose_notification_permission)) - if (platformPermissionUtil.isPostNotificationsPermissionGranted()) { - addValue(context.resources.getString(R.string.nc_settings_notifications_granted)) - } else { - addValue(context.resources.getString(R.string.nc_settings_notifications_declined)) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_notification_permission), + value = if (platformPermissionUtil.isPostNotificationsPermissionGranted()) { + context.resources.getString(R.string.nc_settings_notifications_granted) + } else { + context.resources.getString(R.string.nc_settings_notifications_declined) + } + ) } - addKey(context.resources.getString(R.string.nc_diagnose_notification_calls_channel_permission)) - addValue( + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_notification_calls_channel_permission), + value = translateBoolean( NotificationUtils.isCallsNotificationChannelEnabled(this) ) ) - addKey(context.resources.getString(R.string.nc_diagnose_notification_messages_channel_permission)) - addValue( + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_notification_messages_channel_permission), + value = translateBoolean( NotificationUtils.isMessagesNotificationChannelEnabled(this) ) ) - addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_title)) - if (appPreferences.pushToken.isNullOrEmpty()) { - addValue(context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing)) - } else { - addValue("${appPreferences.pushToken.substring(0, PUSH_TOKEN_PREFIX_END)}...") - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_title), + value = if (appPreferences.pushToken.isNullOrEmpty()) { + context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing) + } else { + "${appPreferences.pushToken.substring(0, PUSH_TOKEN_PREFIX_END)}..." + } + ) - addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated)) - if (appPreferences.pushTokenLatestGeneration != null && appPreferences.pushTokenLatestGeneration != 0L) { - addValue( + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated), + value = if (appPreferences.pushTokenLatestGeneration != null && + appPreferences.pushTokenLatestGeneration != 0L + ) { DisplayUtils.unixTimeToHumanReadable( appPreferences .pushTokenLatestGeneration ) - ) - } else { - addValue(context.resources.getString(R.string.nc_common_unknown)) - } + } else { + context.resources.getString(R.string.nc_common_unknown) + } + ) - addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_fetch)) - if (appPreferences.pushTokenLatestFetch != null && appPreferences.pushTokenLatestFetch != 0L) { - addValue(DisplayUtils.unixTimeToHumanReadable(appPreferences.pushTokenLatestFetch)) - } else { - addValue(context.resources.getString(R.string.nc_common_unknown)) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_fetch), + value = if (appPreferences.pushTokenLatestFetch != null && appPreferences.pushTokenLatestFetch != 0L) { + DisplayUtils.unixTimeToHumanReadable(appPreferences.pushTokenLatestFetch) + } else { + context.resources.getString(R.string.nc_common_unknown) + } + ) } private fun setupAccountValues() { @@ -310,21 +357,29 @@ class DiagnoseActivity : BaseActivity() { addHeadline(context.resources.getString(R.string.nc_diagnose_account_category_title)) - addKey(context.resources.getString(R.string.nc_diagnose_account_server)) - addValue(currentUser.baseUrl!!) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_account_server), + value = + currentUser.baseUrl!! + ) - addKey(context.resources.getString(R.string.nc_diagnose_account_user_name)) - addValue(currentUser.displayName!!) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_account_user_name), + value = + currentUser.displayName!! + ) - addKey(context.resources.getString(R.string.nc_diagnose_account_user_status_enabled)) - addValue( + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_account_user_status_enabled), + value = translateBoolean( (currentUser.capabilities?.userStatusCapability?.enabled) ) ) - addKey(context.resources.getString(R.string.nc_diagnose_account_server_notification_app)) - addValue( + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_account_server_notification_app), + value = translateBoolean(currentUser.capabilities?.notificationsCapability?.features?.isNotEmpty()) ) @@ -332,19 +387,27 @@ class DiagnoseActivity : BaseActivity() { setupPushRegistrationDiagnose() } - addKey(context.resources.getString(R.string.nc_diagnose_server_version)) - addValue(currentUser.serverVersion?.versionString!!) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_server_version), + value = + currentUser.serverVersion?.versionString!! + ) - addKey(context.resources.getString(R.string.nc_diagnose_server_talk_version)) - addValue(currentUser.capabilities?.spreedCapability?.version!!) + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_server_talk_version), + value = + currentUser.capabilities?.spreedCapability?.version!! + ) - addKey(context.resources.getString(R.string.nc_diagnose_signaling_mode_title)) - - if (currentUser.externalSignalingServer?.externalSignalingServer?.isNotEmpty() == true) { - addValue(context.resources.getString(R.string.nc_diagnose_signaling_mode_extern)) - } else { - addValue(context.resources.getString(R.string.nc_diagnose_signaling_mode_intern)) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_signaling_mode_title), + value = + if (currentUser.externalSignalingServer?.externalSignalingServer?.isNotEmpty() == true) { + context.resources.getString(R.string.nc_diagnose_signaling_mode_extern) + } else { + context.resources.getString(R.string.nc_diagnose_signaling_mode_intern) + } + ) } private fun setupPushRegistrationDiagnose() { @@ -356,12 +419,14 @@ class DiagnoseActivity : BaseActivity() { "" ).blockingGet()?.value - addKey(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server)) - if (latestPushRegistrationAtServer.isNullOrEmpty()) { - addValue(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server_fail)) - } else { - addValue(DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtServer.toLong())) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server), + if (latestPushRegistrationAtServer.isNullOrEmpty()) { + context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server_fail) + } else { + DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtServer.toLong()) + } + ) val latestPushRegistrationAtPushProxy = arbitraryStorageManager.getStorageSetting( accountId, @@ -369,12 +434,14 @@ class DiagnoseActivity : BaseActivity() { "" ).blockingGet()?.value - addKey(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy)) - if (latestPushRegistrationAtPushProxy.isNullOrEmpty()) { - addValue(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy_fail)) - } else { - addValue(DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtPushProxy.toLong())) - } + addDiagnosisEntry( + key = context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy), + value = if (latestPushRegistrationAtPushProxy.isNullOrEmpty()) { + context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy_fail) + } else { + DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtPushProxy.toLong()) + } + ) } private fun getDeviceName(): String = @@ -392,72 +459,32 @@ class DiagnoseActivity : BaseActivity() { } } - @Suppress("MagicNumber") - private fun createLayoutFromMarkdown() { - val standardMargin = 16 - val halfMargin = 8 - val standardPadding = 16 + private fun List.toMarkdownString(): String { + val markdownText = SpannableStringBuilder() - binding.diagnoseContentWrapper.removeAllViews() - - markdownText.lines().forEach { - if (it.startsWith(MARKDOWN_HEADLINE)) { - val headline = TextView(context, null, 0) - headline.textSize = 2.0f - headline.setTextSize( - TypedValue.COMPLEX_UNIT_PX, - context.resources.getDimension(R.dimen.headline_text_size) - ) - headline.setTypeface(null, Typeface.BOLD) - headline.text = it.removeRange(0, 4) - - binding.diagnoseContentWrapper.addView(headline) - - headline.updateLayoutParams { - setMargins(0, standardMargin, 0, standardMargin) + this.forEach { + when (it) { + is DiagnoseElement.DiagnoseHeadline -> { + markdownText.append("$MARKDOWN_HEADLINE ${it.headline}") + markdownText.append("\n\n") } - headline.setPadding(0, standardPadding, 0, standardPadding) - - viewThemeUtils.platform.colorTextView(headline) - } else if (it.startsWith(MARKDOWN_BOLD)) { - val key = TextView(context, null, 0) - key.setTextColor(resources.getColor(R.color.high_emphasis_text, null)) - key.setTypeface(null, Typeface.BOLD) - key.text = it.replace(MARKDOWN_BOLD, "") - - binding.diagnoseContentWrapper.addView(key) - - key.updateLayoutParams { - setMargins(0, 0, 0, halfMargin) + is DiagnoseElement.DiagnoseEntry -> { + markdownText.append("$MARKDOWN_BOLD${it.key}$MARKDOWN_BOLD") + markdownText.append("\n\n") + markdownText.append(it.value) + markdownText.append("\n\n") } - } else if (it.isNotEmpty()) { - val value = TextView(context, null, 0) - value.setTextColor(resources.getColor(R.color.high_emphasis_text, null)) - value.text = it - - binding.diagnoseContentWrapper.addView(value) - - value.updateLayoutParams { - setMargins(0, 0, 0, standardMargin) - } - value.setPadding(0, 0, 0, standardPadding) } } + return markdownText.toString() } private fun addHeadline(text: String) { - markdownText.append("$MARKDOWN_HEADLINE $text") - markdownText.append("\n\n") + diagnoseData.add(DiagnoseElement.DiagnoseHeadline(text)) } - private fun addKey(text: String) { - markdownText.bold { append("$MARKDOWN_BOLD$text$MARKDOWN_BOLD") } - markdownText.append("\n\n") - } - - private fun addValue(text: String) { - markdownText.append(text) - markdownText.append("\n\n") + private fun addDiagnosisEntry(key: String, value: String) { + diagnoseData.add(DiagnoseElement.DiagnoseEntry(key, value)) } companion object { @@ -465,6 +492,5 @@ class DiagnoseActivity : BaseActivity() { private const val MARKDOWN_HEADLINE = "###" private const val MARKDOWN_BOLD = "**" private const val PUSH_TOKEN_PREFIX_END: Int = 5 - private const val ORIGINAL_NEXTCLOUD_TALK_APPLICATION_ID = "com.nextcloud.talk2" } } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt new file mode 100644 index 000000000..7a3737af5 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -0,0 +1,77 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Marcel Hibbe + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.diagnose + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.nextcloud.talk.R + +@Composable +fun DiagnoseContentComposable(data: State>) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + .verticalScroll(rememberScrollState()) + ) { + data.value.forEach { element -> + when (element) { + is DiagnoseActivity.DiagnoseElement.DiagnoseHeadline -> Text( + modifier = Modifier.padding(vertical = 16.dp), + text = element.headline, + color = MaterialTheme.colorScheme.primary, + fontSize = LocalDensity.current.run { dimensionResource(R.dimen.headline_text_size).toPx().toSp() }, + fontWeight = FontWeight.Bold + ) + + is DiagnoseActivity.DiagnoseElement.DiagnoseEntry -> { + Text( + text = element.key, + color = colorResource(R.color.high_emphasis_text), + fontWeight = FontWeight.Bold + ) + Text( + modifier = Modifier.padding(bottom = 16.dp), + text = element.value, + color = colorResource(R.color.high_emphasis_text) + ) + } + } + } + } +} + +@Preview(showBackground = true) +@Composable +fun DiagnoseContentPreview() { + val state = remember { + mutableStateOf( + listOf( + DiagnoseActivity.DiagnoseElement.DiagnoseHeadline("Headline"), + DiagnoseActivity.DiagnoseElement.DiagnoseEntry("Key", "Value") + ) + ) + } + DiagnoseContentComposable(state) +} diff --git a/app/src/main/res/layout/activity_diagnose.xml b/app/src/main/res/layout/activity_diagnose.xml deleted file mode 100644 index 301af309f..000000000 --- a/app/src/main/res/layout/activity_diagnose.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file From 6ed17603d6fa8f8f8d0b248784a07a5223036754 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Mar 2025 15:09:19 +0100 Subject: [PATCH 2/6] migrate dropdown menu Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/diagnose/AppBar.kt | 40 +++++++++++- .../talk/diagnose/DiagnoseActivity.kt | 63 +++++-------------- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt b/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt index cf9216a69..3beaf8191 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt @@ -8,23 +8,36 @@ package com.nextcloud.talk.diagnose import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.nextcloud.talk.R @OptIn(ExperimentalMaterial3Api::class) @Composable -fun AppBar(title: String) { +fun AppBar(title: String, menuItems: List Unit>>?) { val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher + var expanded by remember { mutableStateOf(false) } + TopAppBar( title = { Text(text = title) }, navigationIcon = { @@ -36,6 +49,29 @@ fun AppBar(title: String) { contentDescription = stringResource(R.string.back_button) ) } + }, + actions = { + Box { + IconButton(onClick = { expanded = true }) { + Icon(Icons.Default.MoreVert, contentDescription = "More Options") + } + + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + Modifier.background(colorResource(id = R.color.bg_default)) + ) { + menuItems?.forEach { (label, action) -> + DropdownMenuItem( + text = { Text(label) }, + onClick = { + action() + expanded = false + } + ) + } + } + } } ) } @@ -43,5 +79,5 @@ fun AppBar(title: String) { @Preview(showBackground = true) @Composable fun AppBarPreview() { - AppBar("title") + AppBar("title", null) } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt index b8104995e..7c7e98d81 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -16,8 +16,6 @@ import android.os.Build.MANUFACTURER import android.os.Build.MODEL import android.os.Bundle import android.text.SpannableStringBuilder -import android.view.Menu -import android.view.MenuItem import android.widget.Toast import androidx.activity.compose.setContent import androidx.compose.foundation.background @@ -83,13 +81,27 @@ class DiagnoseActivity : BaseActivity() { setContent { val backgroundColor = colorResource(id = R.color.bg_default) + + val menuItems = mutableListOf( + stringResource(R.string.nc_common_copy) to { copyToClipboard(diagnoseData.toMarkdownString()) }, + stringResource(R.string.share) to { shareToOtherApps(diagnoseData.toMarkdownString()) }, + stringResource(R.string.send_email) to { composeEmail(diagnoseData.toMarkdownString()) } + ) + + if (BrandingUtils.isOriginalNextcloudClient(applicationContext)) { + menuItems.add( + stringResource(R.string.create_issue) to { createGithubIssue(diagnoseData.toMarkdownString()) } + ) + } + MaterialTheme( colorScheme = colorScheme ) { Scaffold( topBar = { AppBar( - title = stringResource(R.string.nc_settings_diagnose_title) + title = stringResource(R.string.nc_settings_diagnose_title), + menuItems ) }, content = { @@ -122,50 +134,6 @@ class DiagnoseActivity : BaseActivity() { diagnoseDataState.value = diagnoseData.toList() } - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.menu_diagnose, menu) - return true - } - - override fun onPrepareOptionsMenu(menu: Menu): Boolean { - super.onPrepareOptionsMenu(menu) - menu.findItem(R.id.create_issue).isVisible = BrandingUtils.isOriginalNextcloudClient(applicationContext) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - android.R.id.home -> { - onBackPressedDispatcher.onBackPressed() - true - } - - R.id.copy -> { - copyToClipboard(diagnoseData.toMarkdownString()) - true - } - - R.id.share -> { - shareToOtherApps(diagnoseData.toMarkdownString()) - true - } - - R.id.send_mail -> { - composeEmail(diagnoseData.toMarkdownString()) - true - } - - R.id.create_issue -> { - createGithubIssue(diagnoseData.toMarkdownString()) - true - } - - else -> { - super.onOptionsItemSelected(item) - } - } - } - private fun shareToOtherApps(message: String) { val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND @@ -468,6 +436,7 @@ class DiagnoseActivity : BaseActivity() { markdownText.append("$MARKDOWN_HEADLINE ${it.headline}") markdownText.append("\n\n") } + is DiagnoseElement.DiagnoseEntry -> { markdownText.append("$MARKDOWN_BOLD${it.key}$MARKDOWN_BOLD") markdownText.append("\n\n") From 3723599c68b6b2a319d1fa2d8e2cf581b4ab1d9f Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Mar 2025 17:21:23 +0100 Subject: [PATCH 3/6] move filebrowser package out of components package ... as "components" package should be used for jetpack compose components that can be shared for multiple screens Signed-off-by: Marcel Hibbe --- .../messages/PreviewMessageViewHolder.kt | 4 ++-- .../talk/application/NextcloudTalkApplication.kt | 2 +- .../filebrowser/models/BrowserFile.kt | 14 +++++++------- .../filebrowser/models/DavResponse.java | 2 +- .../filebrowser/models/properties/NCEncrypted.kt | 4 ++-- .../models/properties/NCPermission.kt | 4 ++-- .../filebrowser/models/properties/NCPreview.kt | 4 ++-- .../filebrowser/models/properties/OCFavorite.kt | 4 ++-- .../filebrowser/models/properties/OCId.kt | 4 ++-- .../filebrowser/models/properties/OCSize.kt | 4 ++-- .../filebrowser/webdav/DavUtils.java | 14 +++++++------- .../webdav/ReadFilesystemOperation.java | 6 +++--- .../webdav/ReadFolderListingOperation.kt | 16 ++++++++-------- .../RemoteFileBrowserItemsRepositoryImpl.kt | 2 +- .../talk/upload/chunked/ChunkedFileUploader.kt | 14 +++++++------- 15 files changed, 49 insertions(+), 49 deletions(-) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/BrowserFile.kt (87%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/DavResponse.java (97%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/NCEncrypted.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/NCPermission.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/NCPreview.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/OCFavorite.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/OCId.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/models/properties/OCSize.kt (91%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/webdav/DavUtils.java (88%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/webdav/ReadFilesystemOperation.java (94%) rename app/src/main/java/com/nextcloud/talk/{components => }/filebrowser/webdav/ReadFolderListingOperation.kt (91%) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt index a70173c05..a5df1b3a7 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt @@ -29,8 +29,8 @@ import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.chat.data.model.ChatMessage -import com.nextcloud.talk.components.filebrowser.models.BrowserFile -import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation +import com.nextcloud.talk.filebrowser.models.BrowserFile +import com.nextcloud.talk.filebrowser.webdav.ReadFilesystemOperation import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.extensions.loadChangelogBotAvatar diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt index 261e869f6..6614501e1 100644 --- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt +++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt @@ -33,7 +33,7 @@ import coil.decode.SvgDecoder import coil.memory.MemoryCache import coil.util.DebugLogger import com.nextcloud.talk.BuildConfig -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import com.nextcloud.talk.dagger.modules.BusModule import com.nextcloud.talk.dagger.modules.ContextModule import com.nextcloud.talk.dagger.modules.DaosModule diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/BrowserFile.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/BrowserFile.kt similarity index 87% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/BrowserFile.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/BrowserFile.kt index 8652823c7..594c6801d 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/BrowserFile.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/BrowserFile.kt @@ -4,7 +4,7 @@ * SPDX-FileCopyrightText: 2017-2018 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models +package com.nextcloud.talk.filebrowser.models import android.net.Uri import android.os.Parcelable @@ -17,12 +17,12 @@ import at.bitfire.dav4jvm.property.GetLastModified import at.bitfire.dav4jvm.property.ResourceType import at.bitfire.dav4jvm.property.ResourceType.Companion.COLLECTION import com.bluelinelabs.logansquare.annotation.JsonObject -import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted -import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission -import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview -import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite -import com.nextcloud.talk.components.filebrowser.models.properties.OCId -import com.nextcloud.talk.components.filebrowser.models.properties.OCSize +import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted +import com.nextcloud.talk.filebrowser.models.properties.NCPermission +import com.nextcloud.talk.filebrowser.models.properties.NCPreview +import com.nextcloud.talk.filebrowser.models.properties.OCFavorite +import com.nextcloud.talk.filebrowser.models.properties.OCId +import com.nextcloud.talk.filebrowser.models.properties.OCSize import com.nextcloud.talk.utils.Mimetype.FOLDER import kotlinx.parcelize.Parcelize import java.io.File diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/DavResponse.java b/app/src/main/java/com/nextcloud/talk/filebrowser/models/DavResponse.java similarity index 97% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/DavResponse.java rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/DavResponse.java index 96b10531c..16f50c208 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/DavResponse.java +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/DavResponse.java @@ -4,7 +4,7 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models; +package com.nextcloud.talk.filebrowser.models; import at.bitfire.dav4jvm.Response; diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCEncrypted.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCEncrypted.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCEncrypted.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCEncrypted.kt index ae03d0fd7..f0c15948b 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCEncrypted.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCEncrypted.kt @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPermission.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPermission.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPermission.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPermission.kt index d97ab0b6a..f00c17b2b 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPermission.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPermission.kt @@ -6,14 +6,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPreview.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPreview.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPreview.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPreview.kt index 888c4a4e5..1b0241fc0 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/NCPreview.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/NCPreview.kt @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCFavorite.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCFavorite.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCFavorite.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCFavorite.kt index af1e01eef..3be50321e 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCFavorite.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCFavorite.kt @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCId.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCId.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCId.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCId.kt index 448c90558..168dc92c5 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCId.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCId.kt @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCSize.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCSize.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCSize.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCSize.kt index b02816739..a30483d1d 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/models/properties/OCSize.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/models/properties/OCSize.kt @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.models.properties +package com.nextcloud.talk.filebrowser.models.properties import android.text.TextUtils import android.util.Log import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.XmlUtils.readText -import com.nextcloud.talk.components.filebrowser.webdav.DavUtils +import com.nextcloud.talk.filebrowser.webdav.DavUtils import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/DavUtils.java b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/DavUtils.java similarity index 88% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/DavUtils.java rename to app/src/main/java/com/nextcloud/talk/filebrowser/webdav/DavUtils.java index b2126aeed..347ea5a97 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/DavUtils.java +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/DavUtils.java @@ -5,14 +5,14 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.webdav; +package com.nextcloud.talk.filebrowser.webdav; -import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted; -import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission; -import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview; -import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite; -import com.nextcloud.talk.components.filebrowser.models.properties.OCId; -import com.nextcloud.talk.components.filebrowser.models.properties.OCSize; +import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted; +import com.nextcloud.talk.filebrowser.models.properties.NCPermission; +import com.nextcloud.talk.filebrowser.models.properties.NCPreview; +import com.nextcloud.talk.filebrowser.models.properties.OCFavorite; +import com.nextcloud.talk.filebrowser.models.properties.OCId; +import com.nextcloud.talk.filebrowser.models.properties.OCSize; import java.util.ArrayList; import java.util.List; diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFilesystemOperation.java similarity index 94% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java rename to app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFilesystemOperation.java index 910b9e388..618820f20 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFilesystemOperation.java +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFilesystemOperation.java @@ -4,12 +4,12 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.webdav; +package com.nextcloud.talk.filebrowser.webdav; import android.util.Log; -import com.nextcloud.talk.components.filebrowser.models.BrowserFile; -import com.nextcloud.talk.components.filebrowser.models.DavResponse; +import com.nextcloud.talk.filebrowser.models.BrowserFile; +import com.nextcloud.talk.filebrowser.models.DavResponse; import com.nextcloud.talk.dagger.modules.RestModule; import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.utils.ApiUtils; diff --git a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFolderListingOperation.kt b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFolderListingOperation.kt similarity index 91% rename from app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFolderListingOperation.kt rename to app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFolderListingOperation.kt index 2be5f84b5..4c757534c 100644 --- a/app/src/main/java/com/nextcloud/talk/components/filebrowser/webdav/ReadFolderListingOperation.kt +++ b/app/src/main/java/com/nextcloud/talk/filebrowser/webdav/ReadFolderListingOperation.kt @@ -5,7 +5,7 @@ * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.components.filebrowser.webdav +package com.nextcloud.talk.filebrowser.webdav import android.net.Uri import android.text.TextUtils @@ -19,13 +19,13 @@ import at.bitfire.dav4jvm.property.DisplayName import at.bitfire.dav4jvm.property.GetContentType import at.bitfire.dav4jvm.property.GetLastModified import at.bitfire.dav4jvm.property.ResourceType -import com.nextcloud.talk.components.filebrowser.models.DavResponse -import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted -import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission -import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview -import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite -import com.nextcloud.talk.components.filebrowser.models.properties.OCId -import com.nextcloud.talk.components.filebrowser.models.properties.OCSize +import com.nextcloud.talk.filebrowser.models.DavResponse +import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted +import com.nextcloud.talk.filebrowser.models.properties.NCPermission +import com.nextcloud.talk.filebrowser.models.properties.NCPreview +import com.nextcloud.talk.filebrowser.models.properties.OCFavorite +import com.nextcloud.talk.filebrowser.models.properties.OCId +import com.nextcloud.talk.filebrowser.models.properties.OCSize import com.nextcloud.talk.dagger.modules.RestModule.HttpAuthenticator import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem diff --git a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepositoryImpl.kt index d8862b852..ba01f2df1 100644 --- a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepositoryImpl.kt @@ -6,7 +6,7 @@ */ package com.nextcloud.talk.remotefilebrowser.repositories -import com.nextcloud.talk.components.filebrowser.webdav.ReadFolderListingOperation +import com.nextcloud.talk.filebrowser.webdav.ReadFolderListingOperation import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew diff --git a/app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.kt b/app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.kt index 48626ad4b..6419e200c 100644 --- a/app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.kt +++ b/app/src/main/java/com/nextcloud/talk/upload/chunked/ChunkedFileUploader.kt @@ -20,13 +20,13 @@ import at.bitfire.dav4jvm.property.GetLastModified import at.bitfire.dav4jvm.property.ResourceType import autodagger.AutoInjector import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.components.filebrowser.models.DavResponse -import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted -import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission -import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview -import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite -import com.nextcloud.talk.components.filebrowser.models.properties.OCId -import com.nextcloud.talk.components.filebrowser.models.properties.OCSize +import com.nextcloud.talk.filebrowser.models.DavResponse +import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted +import com.nextcloud.talk.filebrowser.models.properties.NCPermission +import com.nextcloud.talk.filebrowser.models.properties.NCPreview +import com.nextcloud.talk.filebrowser.models.properties.OCFavorite +import com.nextcloud.talk.filebrowser.models.properties.OCId +import com.nextcloud.talk.filebrowser.models.properties.OCSize import com.nextcloud.talk.dagger.modules.RestModule import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.jobs.ShareOperationWorker From c2177f689b2134fa3afb8f44a175c970fb9cdd53 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Mar 2025 17:25:25 +0100 Subject: [PATCH 4/6] move SetStatusBarColor component to component package on root level however, the color still needs to be fixed Signed-off-by: Marcel Hibbe --- .../talk/{contacts => }/components/SetStatusBarColor.kt | 2 +- .../com/nextcloud/talk/contacts/ContactsActivityCompose.kt | 2 +- .../main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) rename app/src/main/java/com/nextcloud/talk/{contacts => }/components/SetStatusBarColor.kt (95%) diff --git a/app/src/main/java/com/nextcloud/talk/contacts/components/SetStatusBarColor.kt b/app/src/main/java/com/nextcloud/talk/components/SetStatusBarColor.kt similarity index 95% rename from app/src/main/java/com/nextcloud/talk/contacts/components/SetStatusBarColor.kt rename to app/src/main/java/com/nextcloud/talk/components/SetStatusBarColor.kt index e341b0914..2dfb67e23 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/components/SetStatusBarColor.kt +++ b/app/src/main/java/com/nextcloud/talk/components/SetStatusBarColor.kt @@ -6,7 +6,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.contacts.components +package com.nextcloud.talk.components import android.app.Activity import androidx.compose.foundation.isSystemInDarkTheme diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt index f87eb65a4..f3cf47252 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -19,7 +19,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import autodagger.AutoInjector import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.contacts.components.SetStatusBarColor +import com.nextcloud.talk.components.SetStatusBarColor import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import javax.inject.Inject diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt index 7c7e98d81..bd24e39e5 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -35,6 +35,7 @@ import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager +import com.nextcloud.talk.components.SetStatusBarColor import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.BrandingUtils import com.nextcloud.talk.utils.ClosedInterfaceImpl @@ -116,6 +117,8 @@ class DiagnoseActivity : BaseActivity() { } ) } + + SetStatusBarColor() } } From 2b0a38240cc7a1e28faf0a2a82addbd39ee51985 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Mon, 3 Mar 2025 17:39:44 +0100 Subject: [PATCH 5/6] move AppBar component to component package on root level + add string + remove unused resources Signed-off-by: Marcel Hibbe --- .../StandardAppBar.kt} | 15 +++++++------ .../talk/diagnose/DiagnoseActivity.kt | 3 ++- app/src/main/res/menu/menu_diagnose.xml | 21 ------------------- app/src/main/res/values/strings.xml | 4 +--- 4 files changed, 12 insertions(+), 31 deletions(-) rename app/src/main/java/com/nextcloud/talk/{diagnose/AppBar.kt => components/StandardAppBar.kt} (83%) delete mode 100644 app/src/main/res/menu/menu_diagnose.xml diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt b/app/src/main/java/com/nextcloud/talk/components/StandardAppBar.kt similarity index 83% rename from app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt rename to app/src/main/java/com/nextcloud/talk/components/StandardAppBar.kt index 3beaf8191..102d9735f 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/AppBar.kt +++ b/app/src/main/java/com/nextcloud/talk/components/StandardAppBar.kt @@ -1,11 +1,11 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2025 Marcel Hibbe + * SPDX-FileCopyrightText: 2025 Your Name * SPDX-License-Identifier: GPL-3.0-or-later */ -package com.nextcloud.talk.diagnose +package com.nextcloud.talk.components import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.foundation.background @@ -33,7 +33,7 @@ import com.nextcloud.talk.R @OptIn(ExperimentalMaterial3Api::class) @Composable -fun AppBar(title: String, menuItems: List Unit>>?) { +fun StandardAppBar(title: String, menuItems: List Unit>>?) { val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher var expanded by remember { mutableStateOf(false) } @@ -53,13 +53,16 @@ fun AppBar(title: String, menuItems: List Unit>>?) { actions = { Box { IconButton(onClick = { expanded = true }) { - Icon(Icons.Default.MoreVert, contentDescription = "More Options") + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = stringResource(R.string.nc_common_more_options) + ) } DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, - Modifier.background(colorResource(id = R.color.bg_default)) + modifier = Modifier.background(color = colorResource(id = R.color.bg_default)) ) { menuItems?.forEach { (label, action) -> DropdownMenuItem( @@ -79,5 +82,5 @@ fun AppBar(title: String, menuItems: List Unit>>?) { @Preview(showBackground = true) @Composable fun AppBarPreview() { - AppBar("title", null) + StandardAppBar("title", null) } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt index bd24e39e5..84354b287 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -35,6 +35,7 @@ import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager +import com.nextcloud.talk.components.StandardAppBar import com.nextcloud.talk.components.SetStatusBarColor import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.BrandingUtils @@ -100,7 +101,7 @@ class DiagnoseActivity : BaseActivity() { ) { Scaffold( topBar = { - AppBar( + StandardAppBar( title = stringResource(R.string.nc_settings_diagnose_title), menuItems ) diff --git a/app/src/main/res/menu/menu_diagnose.xml b/app/src/main/res/menu/menu_diagnose.xml deleted file mode 100644 index fc7d69ef0..000000000 --- a/app/src/main/res/menu/menu_diagnose.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9c3afad46..4cea2cf2d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,6 +35,7 @@ How to translate with transifex: Disabled Copy Copied to clipboard + More options Settings @@ -66,7 +67,6 @@ How to translate with transifex: %1$s not available (not installed or restricted by admin) Could not store display name, aborting - Never joined Search Check out the certificate @@ -305,7 +305,6 @@ How to translate with transifex: Change audio output Toggle camera Toggle microphone - Advanced call options Hang up Answer as voice call only Answer as video call @@ -439,7 +438,6 @@ How to translate with transifex: Remote audio off Add attachment Recent - Backspace See %d similar message See %d similar messages From e84cb246a4e25f6e46e97507f7820b9f788009b2 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 5 Mar 2025 08:21:53 +0000 Subject: [PATCH 6/6] Analysis: update lint results to reflect reduced error/warning count Signed-off-by: github-actions --- scripts/analysis/lint-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index 8ec425503..26b9b13e0 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 9 errors and 103 warnings + Lint Report: 9 errors and 100 warnings