Merge pull request #4731 from nextcloud/migrateDiagnosisScreenToCompose

migrate diagnosis screen to compose
This commit is contained in:
Sowjanya Kota 2025-03-06 09:37:46 +01:00 committed by GitHub
commit aef0bf07d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 432 additions and 339 deletions

View File

@ -29,8 +29,8 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.components.filebrowser.models.BrowserFile import com.nextcloud.talk.filebrowser.models.BrowserFile
import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation import com.nextcloud.talk.filebrowser.webdav.ReadFilesystemOperation
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
import com.nextcloud.talk.extensions.loadChangelogBotAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar

View File

@ -33,7 +33,7 @@ import coil.decode.SvgDecoder
import coil.memory.MemoryCache import coil.memory.MemoryCache
import coil.util.DebugLogger import coil.util.DebugLogger
import com.nextcloud.talk.BuildConfig 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.BusModule
import com.nextcloud.talk.dagger.modules.ContextModule import com.nextcloud.talk.dagger.modules.ContextModule
import com.nextcloud.talk.dagger.modules.DaosModule import com.nextcloud.talk.dagger.modules.DaosModule

View File

@ -6,7 +6,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
package com.nextcloud.talk.contacts.components package com.nextcloud.talk.components
import android.app.Activity import android.app.Activity
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme

View File

@ -0,0 +1,86 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2025 Your Name <your@email.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.components
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 StandardAppBar(title: String, menuItems: List<Pair<String, () -> Unit>>?) {
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
var expanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text(text = title) },
navigationIcon = {
IconButton(
onClick = { backDispatcher?.onBackPressed() }
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back_button)
)
}
},
actions = {
Box {
IconButton(onClick = { expanded = true }) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.nc_common_more_options)
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.background(color = colorResource(id = R.color.bg_default))
) {
menuItems?.forEach { (label, action) ->
DropdownMenuItem(
text = { Text(label) },
onClick = {
action()
expanded = false
}
)
}
}
}
}
)
}
@Preview(showBackground = true)
@Composable
fun AppBarPreview() {
StandardAppBar("title", null)
}

View File

@ -19,7 +19,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.application.NextcloudTalkApplication 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 com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import javax.inject.Inject import javax.inject.Inject

View File

@ -9,24 +9,25 @@ package com.nextcloud.talk.diagnose
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Build.MANUFACTURER import android.os.Build.MANUFACTURER
import android.os.Build.MODEL import android.os.Build.MODEL
import android.os.Bundle import android.os.Bundle
import android.text.SpannableStringBuilder 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 android.widget.Toast
import androidx.core.text.bold import androidx.activity.compose.setContent
import androidx.core.view.updateLayoutParams 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 autodagger.AutoInjector
import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R import com.nextcloud.talk.R
@ -34,7 +35,8 @@ import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
import com.nextcloud.talk.databinding.ActivityDiagnoseBinding import com.nextcloud.talk.components.StandardAppBar
import com.nextcloud.talk.components.SetStatusBarColor
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.BrandingUtils import com.nextcloud.talk.utils.BrandingUtils
import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.ClosedInterfaceImpl
@ -50,7 +52,6 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
class DiagnoseActivity : BaseActivity() { class DiagnoseActivity : BaseActivity() {
private lateinit var binding: ActivityDiagnoseBinding
@Inject @Inject
lateinit var arbitraryStorageManager: ArbitraryStorageManager lateinit var arbitraryStorageManager: ArbitraryStorageManager
@ -66,16 +67,60 @@ class DiagnoseActivity : BaseActivity() {
private var isGooglePlayServicesAvailable: Boolean = false 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<DiagnoseElement>()
private val diagnoseDataState = mutableStateOf(emptyList<DiagnoseElement>())
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ActivityDiagnoseBinding.inflate(layoutInflater) val colorScheme = viewThemeUtils.getColorScheme(this)
setupActionBar()
setContentView(binding.root) setContent {
setupSystemColors() 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 = {
StandardAppBar(
title = stringResource(R.string.nc_settings_diagnose_title),
menuItems
)
},
content = {
Column(
Modifier
.padding(it)
.background(backgroundColor)
.fillMaxSize()
) {
DiagnoseContentComposable(diagnoseDataState)
}
}
)
}
SetStatusBarColor()
}
} }
override fun onResume() { override fun onResume() {
@ -84,69 +129,13 @@ class DiagnoseActivity : BaseActivity() {
isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable
markdownText.clear() diagnoseData.clear()
setupMetaValues() setupMetaValues()
setupPhoneValues() setupPhoneValues()
setupAppValues() setupAppValues()
setupAccountValues() setupAccountValues()
createLayoutFromMarkdown() diagnoseDataState.value = diagnoseData.toList()
}
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)
}
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(markdownText.toString())
true
}
R.id.share -> {
shareToOtherApps(markdownText.toString())
true
}
R.id.send_mail -> {
composeEmail(markdownText.toString())
true
}
R.id.create_issue -> {
createGithubIssue(markdownText.toString())
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
} }
private fun shareToOtherApps(message: String) { private fun shareToOtherApps(message: String) {
@ -185,7 +174,7 @@ class DiagnoseActivity : BaseActivity() {
private fun copyToClipboard(text: String) { private fun copyToClipboard(text: String) {
val clipboardManager = val clipboardManager =
getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText( val clipData = ClipData.newPlainText(
resources?.getString(R.string.nc_app_product_name), resources?.getString(R.string.nc_app_product_name),
text text
@ -201,25 +190,35 @@ class DiagnoseActivity : BaseActivity() {
private fun setupMetaValues() { private fun setupMetaValues() {
addHeadline(context.resources.getString(R.string.nc_diagnose_meta_category_title)) addHeadline(context.resources.getString(R.string.nc_diagnose_meta_category_title))
addKey(context.resources.getString(R.string.nc_diagnose_meta_system_report_date)) addDiagnosisEntry(
addValue(DisplayUtils.unixTimeToHumanReadable(System.currentTimeMillis())) key = context.resources.getString(R.string.nc_diagnose_meta_system_report_date),
value = DisplayUtils.unixTimeToHumanReadable(System.currentTimeMillis())
)
} }
private fun setupPhoneValues() { private fun setupPhoneValues() {
addHeadline(context.resources.getString(R.string.nc_diagnose_phone_category_title)) addHeadline(context.resources.getString(R.string.nc_diagnose_phone_category_title))
addKey(context.resources.getString(R.string.nc_diagnose_device_name_title)) addDiagnosisEntry(
addValue(getDeviceName()) key = context.resources.getString(R.string.nc_diagnose_device_name_title),
value = getDeviceName()
)
addKey(context.resources.getString(R.string.nc_diagnose_android_version_title)) addDiagnosisEntry(
addValue(Build.VERSION.SDK_INT.toString()) key = context.resources.getString(R.string.nc_diagnose_android_version_title),
value = Build.VERSION.SDK_INT.toString()
)
if (isGooglePlayServicesAvailable) { if (isGooglePlayServicesAvailable) {
addKey(context.resources.getString(R.string.nc_diagnose_gplay_available_title)) addDiagnosisEntry(
addValue(context.resources.getString(R.string.nc_diagnose_gplay_available_yes)) key = context.resources.getString(R.string.nc_diagnose_gplay_available_title),
value = context.resources.getString(R.string.nc_diagnose_gplay_available_yes)
)
} else { } else {
addKey(context.resources.getString(R.string.nc_diagnose_gplay_available_title)) addDiagnosisEntry(
addValue(context.resources.getString(R.string.nc_diagnose_gplay_available_no)) key = context.resources.getString(R.string.nc_diagnose_gplay_available_title),
value = context.resources.getString(R.string.nc_diagnose_gplay_available_no)
)
} }
} }
@ -228,81 +227,101 @@ class DiagnoseActivity : BaseActivity() {
private fun setupAppValues() { private fun setupAppValues() {
addHeadline(context.resources.getString(R.string.nc_diagnose_app_category_title)) addHeadline(context.resources.getString(R.string.nc_diagnose_app_category_title))
addKey(context.resources.getString(R.string.nc_diagnose_app_name_title)) addDiagnosisEntry(
addValue(context.resources.getString(R.string.nc_app_product_name)) 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)) addDiagnosisEntry(
addValue(String.format("v" + BuildConfig.VERSION_NAME)) 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)) addDiagnosisEntry(
addValue(BuildConfig.FLAVOR) key = context.resources.getString(R.string.nc_diagnose_flavor),
value = BuildConfig.FLAVOR
)
if (isGooglePlayServicesAvailable) { if (isGooglePlayServicesAvailable) {
setupAppValuesForGooglePlayServices() setupAppValuesForGooglePlayServices()
} }
addKey(context.resources.getString(R.string.nc_diagnose_app_users_amount)) addDiagnosisEntry(
addValue(userManager.users.blockingGet().size.toString()) key = context.resources.getString(R.string.nc_diagnose_app_users_amount),
value = userManager.users.blockingGet().size.toString()
)
} }
@Suppress("Detekt.LongMethod")
private fun setupAppValuesForGooglePlayServices() { private fun setupAppValuesForGooglePlayServices() {
addKey(context.resources.getString(R.string.nc_diagnose_battery_optimization_title)) addDiagnosisEntry(
key = context.resources.getString(R.string.nc_diagnose_battery_optimization_title),
if (PowerManagerUtils().isIgnoringBatteryOptimizations()) { value = if (PowerManagerUtils().isIgnoringBatteryOptimizations()) {
addValue(context.resources.getString(R.string.nc_diagnose_battery_optimization_ignored)) context.resources.getString(R.string.nc_diagnose_battery_optimization_ignored)
} else { } else {
addValue(context.resources.getString(R.string.nc_diagnose_battery_optimization_not_ignored)) context.resources.getString(R.string.nc_diagnose_battery_optimization_not_ignored)
} }
)
// handle notification permission on API level >= 33 // handle notification permission on API level >= 33
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
addKey(context.resources.getString(R.string.nc_diagnose_notification_permission)) addDiagnosisEntry(
if (platformPermissionUtil.isPostNotificationsPermissionGranted()) { key = context.resources.getString(R.string.nc_diagnose_notification_permission),
addValue(context.resources.getString(R.string.nc_settings_notifications_granted)) value = if (platformPermissionUtil.isPostNotificationsPermissionGranted()) {
} else { context.resources.getString(R.string.nc_settings_notifications_granted)
addValue(context.resources.getString(R.string.nc_settings_notifications_declined)) } else {
} context.resources.getString(R.string.nc_settings_notifications_declined)
}
)
} }
addKey(context.resources.getString(R.string.nc_diagnose_notification_calls_channel_permission)) addDiagnosisEntry(
addValue( key = context.resources.getString(R.string.nc_diagnose_notification_calls_channel_permission),
value =
translateBoolean( translateBoolean(
NotificationUtils.isCallsNotificationChannelEnabled(this) NotificationUtils.isCallsNotificationChannelEnabled(this)
) )
) )
addKey(context.resources.getString(R.string.nc_diagnose_notification_messages_channel_permission)) addDiagnosisEntry(
addValue( key = context.resources.getString(R.string.nc_diagnose_notification_messages_channel_permission),
value =
translateBoolean( translateBoolean(
NotificationUtils.isMessagesNotificationChannelEnabled(this) NotificationUtils.isMessagesNotificationChannelEnabled(this)
) )
) )
addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_title)) addDiagnosisEntry(
if (appPreferences.pushToken.isNullOrEmpty()) { key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_title),
addValue(context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing)) value = if (appPreferences.pushToken.isNullOrEmpty()) {
} else { context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing)
addValue("${appPreferences.pushToken.substring(0, PUSH_TOKEN_PREFIX_END)}...") } else {
} "${appPreferences.pushToken.substring(0, PUSH_TOKEN_PREFIX_END)}..."
}
)
addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated)) addDiagnosisEntry(
if (appPreferences.pushTokenLatestGeneration != null && appPreferences.pushTokenLatestGeneration != 0L) { key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated),
addValue( value = if (appPreferences.pushTokenLatestGeneration != null &&
appPreferences.pushTokenLatestGeneration != 0L
) {
DisplayUtils.unixTimeToHumanReadable( DisplayUtils.unixTimeToHumanReadable(
appPreferences appPreferences
.pushTokenLatestGeneration .pushTokenLatestGeneration
) )
) } else {
} else { context.resources.getString(R.string.nc_common_unknown)
addValue(context.resources.getString(R.string.nc_common_unknown)) }
} )
addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_fetch)) addDiagnosisEntry(
if (appPreferences.pushTokenLatestFetch != null && appPreferences.pushTokenLatestFetch != 0L) { key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_fetch),
addValue(DisplayUtils.unixTimeToHumanReadable(appPreferences.pushTokenLatestFetch)) value = if (appPreferences.pushTokenLatestFetch != null && appPreferences.pushTokenLatestFetch != 0L) {
} else { DisplayUtils.unixTimeToHumanReadable(appPreferences.pushTokenLatestFetch)
addValue(context.resources.getString(R.string.nc_common_unknown)) } else {
} context.resources.getString(R.string.nc_common_unknown)
}
)
} }
private fun setupAccountValues() { private fun setupAccountValues() {
@ -310,21 +329,29 @@ class DiagnoseActivity : BaseActivity() {
addHeadline(context.resources.getString(R.string.nc_diagnose_account_category_title)) addHeadline(context.resources.getString(R.string.nc_diagnose_account_category_title))
addKey(context.resources.getString(R.string.nc_diagnose_account_server)) addDiagnosisEntry(
addValue(currentUser.baseUrl!!) key = context.resources.getString(R.string.nc_diagnose_account_server),
value =
currentUser.baseUrl!!
)
addKey(context.resources.getString(R.string.nc_diagnose_account_user_name)) addDiagnosisEntry(
addValue(currentUser.displayName!!) 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)) addDiagnosisEntry(
addValue( key = context.resources.getString(R.string.nc_diagnose_account_user_status_enabled),
value =
translateBoolean( translateBoolean(
(currentUser.capabilities?.userStatusCapability?.enabled) (currentUser.capabilities?.userStatusCapability?.enabled)
) )
) )
addKey(context.resources.getString(R.string.nc_diagnose_account_server_notification_app)) addDiagnosisEntry(
addValue( key = context.resources.getString(R.string.nc_diagnose_account_server_notification_app),
value =
translateBoolean(currentUser.capabilities?.notificationsCapability?.features?.isNotEmpty()) translateBoolean(currentUser.capabilities?.notificationsCapability?.features?.isNotEmpty())
) )
@ -332,19 +359,27 @@ class DiagnoseActivity : BaseActivity() {
setupPushRegistrationDiagnose() setupPushRegistrationDiagnose()
} }
addKey(context.resources.getString(R.string.nc_diagnose_server_version)) addDiagnosisEntry(
addValue(currentUser.serverVersion?.versionString!!) 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)) addDiagnosisEntry(
addValue(currentUser.capabilities?.spreedCapability?.version!!) 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)) addDiagnosisEntry(
key = context.resources.getString(R.string.nc_diagnose_signaling_mode_title),
if (currentUser.externalSignalingServer?.externalSignalingServer?.isNotEmpty() == true) { value =
addValue(context.resources.getString(R.string.nc_diagnose_signaling_mode_extern)) if (currentUser.externalSignalingServer?.externalSignalingServer?.isNotEmpty() == true) {
} else { context.resources.getString(R.string.nc_diagnose_signaling_mode_extern)
addValue(context.resources.getString(R.string.nc_diagnose_signaling_mode_intern)) } else {
} context.resources.getString(R.string.nc_diagnose_signaling_mode_intern)
}
)
} }
private fun setupPushRegistrationDiagnose() { private fun setupPushRegistrationDiagnose() {
@ -356,12 +391,14 @@ class DiagnoseActivity : BaseActivity() {
"" ""
).blockingGet()?.value ).blockingGet()?.value
addKey(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server)) addDiagnosisEntry(
if (latestPushRegistrationAtServer.isNullOrEmpty()) { key = context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server),
addValue(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server_fail)) if (latestPushRegistrationAtServer.isNullOrEmpty()) {
} else { context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_server_fail)
addValue(DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtServer.toLong())) } else {
} DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtServer.toLong())
}
)
val latestPushRegistrationAtPushProxy = arbitraryStorageManager.getStorageSetting( val latestPushRegistrationAtPushProxy = arbitraryStorageManager.getStorageSetting(
accountId, accountId,
@ -369,12 +406,14 @@ class DiagnoseActivity : BaseActivity() {
"" ""
).blockingGet()?.value ).blockingGet()?.value
addKey(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy)) addDiagnosisEntry(
if (latestPushRegistrationAtPushProxy.isNullOrEmpty()) { key = context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy),
addValue(context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy_fail)) value = if (latestPushRegistrationAtPushProxy.isNullOrEmpty()) {
} else { context.resources.getString(R.string.nc_diagnose_latest_push_registration_at_push_proxy_fail)
addValue(DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtPushProxy.toLong())) } else {
} DisplayUtils.unixTimeToHumanReadable(latestPushRegistrationAtPushProxy.toLong())
}
)
} }
private fun getDeviceName(): String = private fun getDeviceName(): String =
@ -392,72 +431,33 @@ class DiagnoseActivity : BaseActivity() {
} }
} }
@Suppress("MagicNumber") private fun List<DiagnoseElement>.toMarkdownString(): String {
private fun createLayoutFromMarkdown() { val markdownText = SpannableStringBuilder()
val standardMargin = 16
val halfMargin = 8
val standardPadding = 16
binding.diagnoseContentWrapper.removeAllViews() this.forEach {
when (it) {
markdownText.lines().forEach { is DiagnoseElement.DiagnoseHeadline -> {
if (it.startsWith(MARKDOWN_HEADLINE)) { markdownText.append("$MARKDOWN_HEADLINE ${it.headline}")
val headline = TextView(context, null, 0) markdownText.append("\n\n")
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<ViewGroup.MarginLayoutParams> {
setMargins(0, standardMargin, 0, standardMargin)
} }
headline.setPadding(0, standardPadding, 0, standardPadding)
viewThemeUtils.platform.colorTextView(headline) is DiagnoseElement.DiagnoseEntry -> {
} else if (it.startsWith(MARKDOWN_BOLD)) { markdownText.append("$MARKDOWN_BOLD${it.key}$MARKDOWN_BOLD")
val key = TextView(context, null, 0) markdownText.append("\n\n")
key.setTextColor(resources.getColor(R.color.high_emphasis_text, null)) markdownText.append(it.value)
key.setTypeface(null, Typeface.BOLD) markdownText.append("\n\n")
key.text = it.replace(MARKDOWN_BOLD, "")
binding.diagnoseContentWrapper.addView(key)
key.updateLayoutParams<ViewGroup.MarginLayoutParams> {
setMargins(0, 0, 0, halfMargin)
} }
} 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<ViewGroup.MarginLayoutParams> {
setMargins(0, 0, 0, standardMargin)
}
value.setPadding(0, 0, 0, standardPadding)
} }
} }
return markdownText.toString()
} }
private fun addHeadline(text: String) { private fun addHeadline(text: String) {
markdownText.append("$MARKDOWN_HEADLINE $text") diagnoseData.add(DiagnoseElement.DiagnoseHeadline(text))
markdownText.append("\n\n")
} }
private fun addKey(text: String) { private fun addDiagnosisEntry(key: String, value: String) {
markdownText.bold { append("$MARKDOWN_BOLD$text$MARKDOWN_BOLD") } diagnoseData.add(DiagnoseElement.DiagnoseEntry(key, value))
markdownText.append("\n\n")
}
private fun addValue(text: String) {
markdownText.append(text)
markdownText.append("\n\n")
} }
companion object { companion object {
@ -465,6 +465,5 @@ class DiagnoseActivity : BaseActivity() {
private const val MARKDOWN_HEADLINE = "###" private const val MARKDOWN_HEADLINE = "###"
private const val MARKDOWN_BOLD = "**" private const val MARKDOWN_BOLD = "**"
private const val PUSH_TOKEN_PREFIX_END: Int = 5 private const val PUSH_TOKEN_PREFIX_END: Int = 5
private const val ORIGINAL_NEXTCLOUD_TALK_APPLICATION_ID = "com.nextcloud.talk2"
} }
} }

View File

@ -0,0 +1,77 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2025 Marcel Hibbe <dev@mhibbe.de>
* 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<List<DiagnoseActivity.DiagnoseElement>>) {
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)
}

View File

@ -4,7 +4,7 @@
* SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.net.Uri
import android.os.Parcelable 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
import at.bitfire.dav4jvm.property.ResourceType.Companion.COLLECTION import at.bitfire.dav4jvm.property.ResourceType.Companion.COLLECTION
import com.bluelinelabs.logansquare.annotation.JsonObject import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission import com.nextcloud.talk.filebrowser.models.properties.NCPermission
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview import com.nextcloud.talk.filebrowser.models.properties.NCPreview
import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite import com.nextcloud.talk.filebrowser.models.properties.OCFavorite
import com.nextcloud.talk.components.filebrowser.models.properties.OCId import com.nextcloud.talk.filebrowser.models.properties.OCId
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize import com.nextcloud.talk.filebrowser.models.properties.OCSize
import com.nextcloud.talk.utils.Mimetype.FOLDER import com.nextcloud.talk.utils.Mimetype.FOLDER
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.io.File import java.io.File

View File

@ -4,7 +4,7 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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; import at.bitfire.dav4jvm.Response;

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -6,14 +6,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.text.TextUtils
import android.util.Log import android.util.Log
import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils.readText 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.XmlPullParser
import org.xmlpull.v1.XmlPullParserException import org.xmlpull.v1.XmlPullParserException
import java.io.IOException import java.io.IOException

View File

@ -5,14 +5,14 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.filebrowser.models.properties.NCEncrypted;
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission; import com.nextcloud.talk.filebrowser.models.properties.NCPermission;
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview; import com.nextcloud.talk.filebrowser.models.properties.NCPreview;
import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite; import com.nextcloud.talk.filebrowser.models.properties.OCFavorite;
import com.nextcloud.talk.components.filebrowser.models.properties.OCId; import com.nextcloud.talk.filebrowser.models.properties.OCId;
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize; import com.nextcloud.talk.filebrowser.models.properties.OCSize;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -4,12 +4,12 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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 android.util.Log;
import com.nextcloud.talk.components.filebrowser.models.BrowserFile; import com.nextcloud.talk.filebrowser.models.BrowserFile;
import com.nextcloud.talk.components.filebrowser.models.DavResponse; import com.nextcloud.talk.filebrowser.models.DavResponse;
import com.nextcloud.talk.dagger.modules.RestModule; import com.nextcloud.talk.dagger.modules.RestModule;
import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.data.user.model.User;
import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.ApiUtils;

View File

@ -5,7 +5,7 @@
* SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com> * SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: GPL-3.0-or-later * 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.net.Uri
import android.text.TextUtils 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.GetContentType
import at.bitfire.dav4jvm.property.GetLastModified import at.bitfire.dav4jvm.property.GetLastModified
import at.bitfire.dav4jvm.property.ResourceType import at.bitfire.dav4jvm.property.ResourceType
import com.nextcloud.talk.components.filebrowser.models.DavResponse import com.nextcloud.talk.filebrowser.models.DavResponse
import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission import com.nextcloud.talk.filebrowser.models.properties.NCPermission
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview import com.nextcloud.talk.filebrowser.models.properties.NCPreview
import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite import com.nextcloud.talk.filebrowser.models.properties.OCFavorite
import com.nextcloud.talk.components.filebrowser.models.properties.OCId import com.nextcloud.talk.filebrowser.models.properties.OCId
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize import com.nextcloud.talk.filebrowser.models.properties.OCSize
import com.nextcloud.talk.dagger.modules.RestModule.HttpAuthenticator import com.nextcloud.talk.dagger.modules.RestModule.HttpAuthenticator
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem

View File

@ -6,7 +6,7 @@
*/ */
package com.nextcloud.talk.remotefilebrowser.repositories 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.data.user.model.User
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew

View File

@ -20,13 +20,13 @@ import at.bitfire.dav4jvm.property.GetLastModified
import at.bitfire.dav4jvm.property.ResourceType import at.bitfire.dav4jvm.property.ResourceType
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.components.filebrowser.models.DavResponse import com.nextcloud.talk.filebrowser.models.DavResponse
import com.nextcloud.talk.components.filebrowser.models.properties.NCEncrypted import com.nextcloud.talk.filebrowser.models.properties.NCEncrypted
import com.nextcloud.talk.components.filebrowser.models.properties.NCPermission import com.nextcloud.talk.filebrowser.models.properties.NCPermission
import com.nextcloud.talk.components.filebrowser.models.properties.NCPreview import com.nextcloud.talk.filebrowser.models.properties.NCPreview
import com.nextcloud.talk.components.filebrowser.models.properties.OCFavorite import com.nextcloud.talk.filebrowser.models.properties.OCFavorite
import com.nextcloud.talk.components.filebrowser.models.properties.OCId import com.nextcloud.talk.filebrowser.models.properties.OCId
import com.nextcloud.talk.components.filebrowser.models.properties.OCSize import com.nextcloud.talk.filebrowser.models.properties.OCSize
import com.nextcloud.talk.dagger.modules.RestModule import com.nextcloud.talk.dagger.modules.RestModule
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.jobs.ShareOperationWorker import com.nextcloud.talk.jobs.ShareOperationWorker

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud Talk - Android Client
~
~ SPDX-FileCopyrightText: 2024 Marcel Hibbe <dev@mhibbe.de>
~ SPDX-License-Identifier: GPL-3.0-or-later
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/settings_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/settings_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/appbar"
android:theme="?attr/actionBarPopupTheme"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIconTint="@color/fontAppbar"
app:popupTheme="@style/appActionBarPopupMenu"
app:titleTextColor="@color/fontAppbar"
tools:title="@string/nc_app_product_name" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/diagnose_content_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/standard_padding">
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud Talk - Android Client
~
~ SPDX-FileCopyrightText: 2024 Marcel Hibbe <dev@mhibbe.de>
~ SPDX-License-Identifier: GPL-3.0-or-later
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/copy"
android:title="@string/nc_common_copy" />
<item
android:id="@+id/share"
android:title="@string/share" />
<item
android:id="@+id/send_mail"
android:title="@string/send_email" />
<item
android:id="@+id/create_issue"
android:title="@string/create_issue" />
</menu>

View File

@ -35,6 +35,7 @@ How to translate with transifex:
<string name="nc_common_disabled">Disabled</string> <string name="nc_common_disabled">Disabled</string>
<string name="nc_common_copy">Copy</string> <string name="nc_common_copy">Copy</string>
<string name="nc_common_copy_success">Copied to clipboard</string> <string name="nc_common_copy_success">Copied to clipboard</string>
<string name="nc_common_more_options">More options</string>
<!-- Bottom Navigation --> <!-- Bottom Navigation -->
<string name="nc_settings">Settings</string> <string name="nc_settings">Settings</string>
@ -66,7 +67,6 @@ How to translate with transifex:
<string name="nc_nextcloud_talk_app_not_installed">%1$s not available (not installed or restricted by admin)</string> <string name="nc_nextcloud_talk_app_not_installed">%1$s not available (not installed or restricted by admin)</string>
<string name="nc_display_name_not_stored">Could not store display name, aborting</string> <string name="nc_display_name_not_stored">Could not store display name, aborting</string>
<string name="nc_never">Never joined</string>
<string name="nc_search">Search</string> <string name="nc_search">Search</string>
<string name="nc_certificate_dialog_title">Check out the certificate</string> <string name="nc_certificate_dialog_title">Check out the certificate</string>
@ -305,7 +305,6 @@ How to translate with transifex:
<string name="nc_call_button_content_description_audio_output">Change audio output</string> <string name="nc_call_button_content_description_audio_output">Change audio output</string>
<string name="nc_call_button_content_description_camera">Toggle camera</string> <string name="nc_call_button_content_description_camera">Toggle camera</string>
<string name="nc_call_button_content_description_microphone">Toggle microphone</string> <string name="nc_call_button_content_description_microphone">Toggle microphone</string>
<string name="nc_call_button_content_description_advanced">Advanced call options</string>
<string name="nc_call_button_content_description_hangup">Hang up</string> <string name="nc_call_button_content_description_hangup">Hang up</string>
<string name="nc_call_button_content_description_answer_voice_only">Answer as voice call only</string> <string name="nc_call_button_content_description_answer_voice_only">Answer as voice call only</string>
<string name="nc_call_button_content_description_answer_video_call">Answer as video call</string> <string name="nc_call_button_content_description_answer_video_call">Answer as video call</string>
@ -439,7 +438,6 @@ How to translate with transifex:
<string name="nc_remote_audio_off">Remote audio off</string> <string name="nc_remote_audio_off">Remote audio off</string>
<string name="nc_add_attachment">Add attachment</string> <string name="nc_add_attachment">Add attachment</string>
<string name="emoji_category_recent">Recent</string> <string name="emoji_category_recent">Recent</string>
<string name="emoji_backspace">Backspace</string>
<plurals name="see_similar_system_messages"> <plurals name="see_similar_system_messages">
<item quantity="one">See %d similar message</item> <item quantity="one">See %d similar message</item>
<item quantity="other">See %d similar messages</item> <item quantity="other">See %d similar messages</item>

View File

@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE DO NOT TOUCH; GENERATED BY DRONE
<span class="mdl-layout-title">Lint Report: 9 errors and 103 warnings</span> <span class="mdl-layout-title">Lint Report: 9 errors and 100 warnings</span>