From 99b61f5331bbd55ce6f49b32f8f0b74acc084350 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Fri, 28 Mar 2025 15:54:24 +0100 Subject: [PATCH 1/9] test push notification Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/api/NcApiCoroutines.kt | 7 + .../talk/dagger/modules/ViewModelModule.kt | 6 + .../talk/diagnose/DiagnoseActivity.kt | 18 +- .../diagnose/DiagnoseContentComposable.kt | 163 +++++++++++++++--- .../talk/diagnose/DiagnoseViewModel.kt | 59 +++++++ .../testNotification/TestNotificationData.kt | 24 +++ .../testNotification/TestNotificationOCS.kt | 26 +++ .../TestNotificationOverall.kt | 23 +++ .../java/com/nextcloud/talk/utils/ApiUtils.kt | 4 + app/src/main/res/values/strings.xml | 1 + 10 files changed, 305 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt create mode 100644 app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt index 08cc2f469..834c575ee 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt +++ b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt @@ -17,6 +17,7 @@ import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.participants.AddParticipantOverall import com.nextcloud.talk.models.json.participants.TalkBan import com.nextcloud.talk.models.json.participants.TalkBanOverall +import com.nextcloud.talk.models.json.testNotification.TestNotificationOverall import com.nextcloud.talk.models.json.userAbsence.UserAbsenceOverall import okhttp3.MultipartBody import okhttp3.RequestBody @@ -238,6 +239,12 @@ interface NcApiCoroutines { @Url url: String ): UserAbsenceOverall + @POST + suspend fun testPushNotifications( + @Header("Authorization") authorization: String, + @Url url: String + ): TestNotificationOverall + @GET suspend fun getContextOfChatMessage( @Header("Authorization") authorization: String, diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt index a5626faf2..a514d5bbc 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt @@ -16,6 +16,7 @@ import com.nextcloud.talk.conversationcreation.ConversationCreationViewModel import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel import com.nextcloud.talk.conversationlist.viewmodels.ConversationsListViewModel +import com.nextcloud.talk.diagnose.DiagnoseViewModel import com.nextcloud.talk.invitation.viewmodels.InvitationsViewModel import com.nextcloud.talk.messagesearch.MessageSearchViewModel import com.nextcloud.talk.openconversations.viewmodels.OpenConversationsViewModel @@ -148,4 +149,9 @@ abstract class ViewModelModule { @IntoMap @ViewModelKey(ConversationCreationViewModel::class) abstract fun conversationCreationViewModel(viewModel: ConversationCreationViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DiagnoseViewModel::class) + abstract fun diagnoseViewModel(viewModel: DiagnoseViewModel): ViewModel } 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 191507ac1..67bc22653 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -10,6 +10,7 @@ import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager import android.content.Intent +import android.net.Uri import android.os.Build import android.os.Build.MANUFACTURER import android.os.Build.MODEL @@ -27,6 +28,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource +import androidx.lifecycle.ViewModelProvider import androidx.core.net.toUri import autodagger.AutoInjector import com.nextcloud.talk.BuildConfig @@ -35,8 +37,8 @@ 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.SetupSystemBars import com.nextcloud.talk.components.StandardAppBar +import com.nextcloud.talk.components.SetupSystemBars import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.BrandingUtils import com.nextcloud.talk.utils.ClosedInterfaceImpl @@ -56,6 +58,9 @@ class DiagnoseActivity : BaseActivity() { @Inject lateinit var arbitraryStorageManager: ArbitraryStorageManager + @Inject + lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject lateinit var ncApi: NcApi @@ -78,6 +83,10 @@ class DiagnoseActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + val diagnoseViewModel = ViewModelProvider( + this, + viewModelFactory + )[DiagnoseViewModel::class.java] val colorScheme = viewThemeUtils.getColorScheme(this) @@ -113,7 +122,7 @@ class DiagnoseActivity : BaseActivity() { .background(backgroundColor) .fillMaxSize() ) { - DiagnoseContentComposable(diagnoseDataState) + DiagnoseContentComposable(diagnoseDataState, diagnoseViewModel) } } ) @@ -132,6 +141,7 @@ class DiagnoseActivity : BaseActivity() { setupMetaValues() setupPhoneValues() setupAppValues() + testPushNotification() setupAccountValues() diagnoseDataState.value = diagnoseData.toList() @@ -187,6 +197,10 @@ class DiagnoseActivity : BaseActivity() { ).show() } + private fun testPushNotification() { + addHeadline(context.resources.getString(R.string.nc_test_push_button)) + } + private fun setupMetaValues() { addHeadline(context.resources.getString(R.string.nc_diagnose_meta_category_title)) addDiagnosisEntry( diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index 7a3737af5..65d2deac4 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -7,28 +7,53 @@ package com.nextcloud.talk.diagnose +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.widget.Toast +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext 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.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties import com.nextcloud.talk.R @Composable -fun DiagnoseContentComposable(data: State>) { +fun DiagnoseContentComposable( + data: State>, + diagnoseViewModel: DiagnoseViewModel +) { + val context = LocalContext.current + val message = diagnoseViewModel.notificationMessage + val isLoading = diagnoseViewModel.isLoading + val showDialog = diagnoseViewModel.showDialog Column( modifier = Modifier .fillMaxSize() @@ -37,13 +62,33 @@ fun DiagnoseContentComposable(data: State ) { 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.DiagnoseHeadline -> { + if (element.headline == "Test push notifications") { + Text( + text = element.headline, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + .clickable { diagnoseViewModel.fetchTestPushResult() }, + color = MaterialTheme.colorScheme.secondary, + fontSize = LocalDensity.current.run { + dimensionResource(R.dimen.headline_text_size).toPx().toSp() + }, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Start + ) + } else { + Text( + modifier = Modifier.fillMaxWidth().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( @@ -59,19 +104,89 @@ fun DiagnoseContentComposable(data: State } } } + if (isLoading.value) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator() + } + } + + if (showDialog.value) { + Dialog( + onDismissRequest = { diagnoseViewModel.dismissDialog() }, + properties = DialogProperties( + dismissOnClickOutside = true, + usePlatformDefaultWidth = false + ) + ) { + if (showDialog.value) { + Dialog( + onDismissRequest = { diagnoseViewModel.dismissDialog() }, + properties = DialogProperties( + dismissOnClickOutside = true, + usePlatformDefaultWidth = false + ) + ) { + Surface( + shape = MaterialTheme.shapes.medium, + tonalElevation = 8.dp, + modifier = Modifier + .wrapContentSize() + .padding(16.dp) + ) { + Column(modifier = Modifier.padding(16.dp)) { + Text("Push Test Result", style = MaterialTheme.typography.titleMedium) + Spacer(modifier = Modifier.height(12.dp)) + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f, fill = false) + .verticalScroll(rememberScrollState()) + ) { + Text(message.value) + } + Spacer(modifier = Modifier.height(16.dp)) + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxWidth() + ) { + TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { + Text("Cancel") + } + Spacer(modifier = Modifier.width(8.dp)) + TextButton(onClick = { + val clipboard = + context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("PushMessage", message.value) + clipboard.setPrimaryClip(clip) + Toast.makeText(context, "Message copied to clipboard", Toast.LENGTH_SHORT) + .show() + diagnoseViewModel.dismissDialog() + }) { + Text("Copy") + } + } + } + } + } + } + } + } } } -@Preview(showBackground = true) -@Composable -fun DiagnoseContentPreview() { - val state = remember { - mutableStateOf( - listOf( - DiagnoseActivity.DiagnoseElement.DiagnoseHeadline("Headline"), - DiagnoseActivity.DiagnoseElement.DiagnoseEntry("Key", "Value") - ) - ) - } - DiagnoseContentComposable(state) -} +// @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/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt new file mode 100644 index 000000000..d54e7667d --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt @@ -0,0 +1,59 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.diagnose + +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.nextcloud.talk.api.NcApiCoroutines +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew +import kotlinx.coroutines.launch +import javax.inject.Inject + +class DiagnoseViewModel @Inject constructor( + private val ncApiCoroutines: NcApiCoroutines, + private val currentUserProvider: CurrentUserProviderNew +) : ViewModel() { + private val _currentUser = currentUserProvider.currentUser.blockingGet() + val currentUser: User = _currentUser + val credentials = ApiUtils.getCredentials(_currentUser.username, _currentUser.token) ?: "" + + private val _notificationMessage = mutableStateOf("") + val notificationMessage = _notificationMessage + + private val _isLoading = mutableStateOf(false) + val isLoading = _isLoading + + private val _showDialog = mutableStateOf(false) + val showDialog = _showDialog + + fun fetchTestPushResult() { + viewModelScope.launch { + try { + _isLoading.value = true + val response = ncApiCoroutines.testPushNotifications( + credentials, + ApiUtils + .getUrlForTestPushNotifications(_currentUser.baseUrl ?: "") + ) + _notificationMessage.value = response.ocs?.data?.message ?: "Error while fetching test push message" + } catch (e: Exception) { + _notificationMessage.value = "Exception: ${e.localizedMessage}" + } finally { + _isLoading.value = false + _showDialog.value = true + } + } + } + + fun dismissDialog() { + _showDialog.value = false + } +} diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt new file mode 100644 index 000000000..6eea7d48f --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt @@ -0,0 +1,24 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.testNotification + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class TestNotificationData( + @JsonField(name = ["message"]) + var message: String +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : + this("") +} diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt new file mode 100644 index 000000000..86ce3245d --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt @@ -0,0 +1,26 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.testNotification + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import com.nextcloud.talk.models.json.generic.GenericMeta +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class TestNotificationOCS( + @JsonField(name = ["meta"]) + var meta: GenericMeta?, + @JsonField(name = ["data"]) + var data: TestNotificationData? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null, null) +} diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt new file mode 100644 index 000000000..858b084a6 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt @@ -0,0 +1,23 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.models.json.testNotification + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class TestNotificationOverall( + @JsonField(name = ["ocs"]) + var ocs: TestNotificationOCS? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null) +} diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index 8dc117490..875e7bb59 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -273,6 +273,10 @@ object ApiUtils { return getUrlForApi(version, baseUrl) + "/signaling" } + fun getUrlForTestPushNotifications(baseUrl: String): String { + return "$baseUrl$OCS_API_VERSION/apps/notifications/api/v3/test/self" + } + @JvmStatic fun getUrlForSignalingBackend(version: Int, baseUrl: String?): String { return getUrlForSignaling(version, baseUrl) + "/backend" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4742ce754..0495dee53 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -228,6 +228,7 @@ How to translate with transifex: Send email Create issue Build flavor + "Test push notifications Leave conversation From c438250f07dcf3deeb5ae8802cb1fb42045411b2 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 31 Mar 2025 11:15:43 +0200 Subject: [PATCH 2/9] add test push notification button Signed-off-by: sowjanyakch --- .../talk/diagnose/DiagnoseActivity.kt | 4 +- .../diagnose/DiagnoseContentComposable.kt | 69 ++++++++++--------- .../java/com/nextcloud/talk/utils/ApiUtils.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 4 files changed, 40 insertions(+), 36 deletions(-) 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 67bc22653..5fe38b5e8 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -141,8 +141,8 @@ class DiagnoseActivity : BaseActivity() { setupMetaValues() setupPhoneValues() setupAppValues() - testPushNotification() setupAccountValues() + testPushNotification() diagnoseDataState.value = diagnoseData.toList() } @@ -197,7 +197,7 @@ class DiagnoseActivity : BaseActivity() { ).show() } - private fun testPushNotification() { + private fun testPushNotification() { addHeadline(context.resources.getString(R.string.nc_test_push_button)) } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index 65d2deac4..c4a7366a5 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -11,7 +11,6 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.widget.Toast -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -25,6 +24,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface @@ -38,6 +38,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -64,19 +65,28 @@ fun DiagnoseContentComposable( when (element) { is DiagnoseActivity.DiagnoseElement.DiagnoseHeadline -> { if (element.headline == "Test push notifications") { - Text( - text = element.headline, + Button( modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp) - .clickable { diagnoseViewModel.fetchTestPushResult() }, - color = MaterialTheme.colorScheme.secondary, - fontSize = LocalDensity.current.run { - dimensionResource(R.dimen.headline_text_size).toPx().toSp() - }, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Start - ) + .wrapContentSize() + .padding(vertical = 8.dp), + onClick = { + diagnoseViewModel.fetchTestPushResult() + } + + ) { + Text( + text = element.headline, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp), + color = colorResource(R.color.high_emphasis_text), + fontSize = LocalDensity.current.run { + dimensionResource(R.dimen.headline_text_size).toPx().toSp() + }, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + } } else { Text( modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp), @@ -137,7 +147,11 @@ fun DiagnoseContentComposable( .padding(16.dp) ) { Column(modifier = Modifier.padding(16.dp)) { - Text("Push Test Result", style = MaterialTheme.typography.titleMedium) + Text( + text = stringResource(R.string.nc_test_results), + style = MaterialTheme.typography + .titleMedium + ) Spacer(modifier = Modifier.height(12.dp)) Box( modifier = Modifier @@ -145,7 +159,10 @@ fun DiagnoseContentComposable( .weight(1f, fill = false) .verticalScroll(rememberScrollState()) ) { - Text(message.value) + Text( + modifier = Modifier.padding(top = 8.dp), + text = message.value + ) } Spacer(modifier = Modifier.height(16.dp)) Row( @@ -153,19 +170,19 @@ fun DiagnoseContentComposable( modifier = Modifier.fillMaxWidth() ) { TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { - Text("Cancel") + Text(text = stringResource(R.string.nc_cancel)) } Spacer(modifier = Modifier.width(8.dp)) TextButton(onClick = { val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("PushMessage", message.value) + val clip = ClipData.newPlainText("Push Message", message.value) clipboard.setPrimaryClip(clip) - Toast.makeText(context, "Message copied to clipboard", Toast.LENGTH_SHORT) + Toast.makeText(context, "Message copied", Toast.LENGTH_SHORT) .show() diagnoseViewModel.dismissDialog() }) { - Text("Copy") + Text(text = stringResource(R.string.nc_common_copy)) } } } @@ -176,17 +193,3 @@ fun DiagnoseContentComposable( } } } - -// @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/java/com/nextcloud/talk/utils/ApiUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt index 875e7bb59..3e0bfd173 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.kt @@ -273,7 +273,7 @@ object ApiUtils { return getUrlForApi(version, baseUrl) + "/signaling" } - fun getUrlForTestPushNotifications(baseUrl: String): String { + fun getUrlForTestPushNotifications(baseUrl: String): String { return "$baseUrl$OCS_API_VERSION/apps/notifications/api/v3/test/self" } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0495dee53..fa3d3915d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -229,6 +229,7 @@ How to translate with transifex: Create issue Build flavor "Test push notifications + Test results Leave conversation From 7d381f4ca5cc5697180697091550c030d0319682 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 31 Mar 2025 11:34:32 +0200 Subject: [PATCH 3/9] adding copyright Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt | 3 --- .../main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt | 2 +- .../talk/models/json/testNotification/TestNotificationData.kt | 2 +- .../talk/models/json/testNotification/TestNotificationOCS.kt | 2 +- .../models/json/testNotification/TestNotificationOverall.kt | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index c4a7366a5..aea6c0cd9 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -10,7 +10,6 @@ package com.nextcloud.talk.diagnose import android.content.ClipData import android.content.ClipboardManager import android.content.Context -import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -178,8 +177,6 @@ fun DiagnoseContentComposable( context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText("Push Message", message.value) clipboard.setPrimaryClip(clip) - Toast.makeText(context, "Message copied", Toast.LENGTH_SHORT) - .show() diagnoseViewModel.dismissDialog() }) { Text(text = stringResource(R.string.nc_common_copy)) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt index d54e7667d..5d96af91a 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-FileCopyrightText: 2025 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt index 6eea7d48f..451b9a2af 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationData.kt @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-FileCopyrightText: 2025 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt index 86ce3245d..b43fe1f52 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOCS.kt @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-FileCopyrightText: 2025 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ diff --git a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt index 858b084a6..140d4b940 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/testNotification/TestNotificationOverall.kt @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-FileCopyrightText: 2025 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ From a7997abf5721bb3aa47d363e5ab649462edcbebb Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 31 Mar 2025 11:59:27 +0200 Subject: [PATCH 4/9] copy the message Signed-off-by: sowjanyakch --- .../diagnose/DiagnoseContentComposable.kt | 93 +++++++++---------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index aea6c0cd9..093d94fad 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -10,6 +10,8 @@ package com.nextcloud.talk.diagnose import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.os.Build +import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -71,7 +73,6 @@ fun DiagnoseContentComposable( onClick = { diagnoseViewModel.fetchTestPushResult() } - ) { Text( text = element.headline, @@ -121,7 +122,6 @@ fun DiagnoseContentComposable( CircularProgressIndicator() } } - if (showDialog.value) { Dialog( onDismissRequest = { diagnoseViewModel.dismissDialog() }, @@ -130,58 +130,51 @@ fun DiagnoseContentComposable( usePlatformDefaultWidth = false ) ) { - if (showDialog.value) { - Dialog( - onDismissRequest = { diagnoseViewModel.dismissDialog() }, - properties = DialogProperties( - dismissOnClickOutside = true, - usePlatformDefaultWidth = false + Surface( + shape = MaterialTheme.shapes.medium, + tonalElevation = 8.dp, + modifier = Modifier + .wrapContentSize() + .padding(16.dp) + ) { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = stringResource(R.string.nc_test_results), + style = MaterialTheme.typography + .titleMedium ) - ) { - Surface( - shape = MaterialTheme.shapes.medium, - tonalElevation = 8.dp, + Spacer(modifier = Modifier.height(12.dp)) + Box( modifier = Modifier - .wrapContentSize() - .padding(16.dp) + .fillMaxWidth() + .weight(1f, fill = false) + .verticalScroll(rememberScrollState()) ) { - Column(modifier = Modifier.padding(16.dp)) { - Text( - text = stringResource(R.string.nc_test_results), - style = MaterialTheme.typography - .titleMedium - ) - Spacer(modifier = Modifier.height(12.dp)) - Box( - modifier = Modifier - .fillMaxWidth() - .weight(1f, fill = false) - .verticalScroll(rememberScrollState()) - ) { - Text( - modifier = Modifier.padding(top = 8.dp), - text = message.value - ) - } - Spacer(modifier = Modifier.height(16.dp)) - Row( - horizontalArrangement = Arrangement.SpaceEvenly, - modifier = Modifier.fillMaxWidth() - ) { - TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { - Text(text = stringResource(R.string.nc_cancel)) - } - Spacer(modifier = Modifier.width(8.dp)) - TextButton(onClick = { - val clipboard = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Push Message", message.value) - clipboard.setPrimaryClip(clip) - diagnoseViewModel.dismissDialog() - }) { - Text(text = stringResource(R.string.nc_common_copy)) - } + Text( + modifier = Modifier.padding(top = 8.dp), + text = message.value + ) + } + Spacer(modifier = Modifier.height(16.dp)) + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxWidth() + ) { + TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { + Text(text = stringResource(R.string.nc_cancel)) + } + Spacer(modifier = Modifier.width(8.dp)) + TextButton(onClick = { + val clipboard = + context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("Push Message", message.value) + clipboard.setPrimaryClip(clip) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + Toast.makeText(context, R.string.message_copied, Toast.LENGTH_SHORT).show() } + diagnoseViewModel.dismissDialog() + }) { + Text(text = stringResource(R.string.nc_common_copy)) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fa3d3915d..b1f2c9b43 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -230,6 +230,7 @@ How to translate with transifex: Build flavor "Test push notifications Test results + Message copied Leave conversation From ce385556a3aeba824862e7e2b760e56a5dda0973 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 31 Mar 2025 13:46:50 +0200 Subject: [PATCH 5/9] fix detekt Signed-off-by: sowjanyakch --- .../talk/diagnose/DiagnoseActivity.kt | 1 - .../diagnose/DiagnoseContentComposable.kt | 125 ++++++++++-------- .../talk/diagnose/DiagnoseViewModel.kt | 1 + 3 files changed, 70 insertions(+), 57 deletions(-) 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 5fe38b5e8..f51bd942f 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -10,7 +10,6 @@ import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager import android.content.Intent -import android.net.Uri import android.os.Build import android.os.Build.MANUFACTURER import android.os.Build.MODEL diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index 093d94fad..509d76bc4 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.nextcloud.talk.R +@Suppress("LongMethod") @Composable fun DiagnoseContentComposable( data: State>, @@ -114,68 +115,80 @@ fun DiagnoseContentComposable( } } } - if (isLoading.value) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } + ShowNotificationData(isLoading.value, showDialog.value, context, message.value, diagnoseViewModel) + } +} + +@Composable +@Suppress("LongMethod") +fun ShowNotificationData( + isLoading: Boolean, + showDialog: Boolean, + context: Context, + message: String, + diagnoseViewModel: DiagnoseViewModel +) { + if (isLoading) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator() } - if (showDialog.value) { - Dialog( - onDismissRequest = { diagnoseViewModel.dismissDialog() }, - properties = DialogProperties( - dismissOnClickOutside = true, - usePlatformDefaultWidth = false - ) + } + if (showDialog) { + Dialog( + onDismissRequest = { diagnoseViewModel.dismissDialog() }, + properties = DialogProperties( + dismissOnClickOutside = true, + usePlatformDefaultWidth = false + ) + ) { + Surface( + shape = MaterialTheme.shapes.medium, + tonalElevation = 8.dp, + modifier = Modifier + .wrapContentSize() + .padding(16.dp) ) { - Surface( - shape = MaterialTheme.shapes.medium, - tonalElevation = 8.dp, - modifier = Modifier - .wrapContentSize() - .padding(16.dp) - ) { - Column(modifier = Modifier.padding(16.dp)) { + Column(modifier = Modifier.padding(16.dp)) { + Text( + text = stringResource(R.string.nc_test_results), + style = MaterialTheme.typography + .titleMedium + ) + Spacer(modifier = Modifier.height(12.dp)) + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f, fill = false) + .verticalScroll(rememberScrollState()) + ) { Text( - text = stringResource(R.string.nc_test_results), - style = MaterialTheme.typography - .titleMedium + modifier = Modifier.padding(top = 8.dp), + text = message ) - Spacer(modifier = Modifier.height(12.dp)) - Box( - modifier = Modifier - .fillMaxWidth() - .weight(1f, fill = false) - .verticalScroll(rememberScrollState()) - ) { - Text( - modifier = Modifier.padding(top = 8.dp), - text = message.value - ) + } + Spacer(modifier = Modifier.height(16.dp)) + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxWidth() + ) { + TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { + Text(text = stringResource(R.string.nc_cancel)) } - Spacer(modifier = Modifier.height(16.dp)) - Row( - horizontalArrangement = Arrangement.SpaceEvenly, - modifier = Modifier.fillMaxWidth() - ) { - TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { - Text(text = stringResource(R.string.nc_cancel)) - } - Spacer(modifier = Modifier.width(8.dp)) - TextButton(onClick = { - val clipboard = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Push Message", message.value) - clipboard.setPrimaryClip(clip) - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { - Toast.makeText(context, R.string.message_copied, Toast.LENGTH_SHORT).show() - } - diagnoseViewModel.dismissDialog() - }) { - Text(text = stringResource(R.string.nc_common_copy)) + Spacer(modifier = Modifier.width(8.dp)) + TextButton(onClick = { + val clipboard = + context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("Push Message", message) + clipboard.setPrimaryClip(clip) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + Toast.makeText(context, R.string.message_copied, Toast.LENGTH_SHORT).show() } + diagnoseViewModel.dismissDialog() + }) { + Text(text = stringResource(R.string.nc_common_copy)) } } } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt index 5d96af91a..e0b10d06a 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt @@ -17,6 +17,7 @@ import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import kotlinx.coroutines.launch import javax.inject.Inject +@Suppress("TooGenericExceptionCaught") class DiagnoseViewModel @Inject constructor( private val ncApiCoroutines: NcApiCoroutines, private val currentUserProvider: CurrentUserProviderNew From c57bd90ee50ecb46473b84fb13039b5998789b07 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Tue, 15 Apr 2025 14:24:16 +0200 Subject: [PATCH 6/9] minor fixes - show meaningful message + add previews Signed-off-by: sowjanyakch --- .../talk/diagnose/DiagnoseActivity.kt | 14 +- .../diagnose/DiagnoseContentComposable.kt | 187 +++++++++++------- app/src/main/res/values/strings.xml | 2 + 3 files changed, 123 insertions(+), 80 deletions(-) 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 f51bd942f..69e728c98 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -121,7 +121,14 @@ class DiagnoseActivity : BaseActivity() { .background(backgroundColor) .fillMaxSize() ) { - DiagnoseContentComposable(diagnoseDataState, diagnoseViewModel) + DiagnoseContentComposable( + diagnoseDataState, + isLoading = diagnoseViewModel.isLoading.value, + showDialog = diagnoseViewModel.showDialog.value, + message = diagnoseViewModel.notificationMessage.value, + onTestPushClick = { diagnoseViewModel.fetchTestPushResult() }, + onDismissDialog = { diagnoseViewModel.dismissDialog() } + ) } } ) @@ -141,7 +148,6 @@ class DiagnoseActivity : BaseActivity() { setupPhoneValues() setupAppValues() setupAccountValues() - testPushNotification() diagnoseDataState.value = diagnoseData.toList() } @@ -196,10 +202,6 @@ class DiagnoseActivity : BaseActivity() { ).show() } - private fun testPushNotification() { - addHeadline(context.resources.getString(R.string.nc_test_push_button)) - } - private fun setupMetaValues() { addHeadline(context.resources.getString(R.string.nc_diagnose_meta_category_title)) addDiagnosisEntry( diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index 509d76bc4..ba6047e89 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -33,6 +33,8 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -42,21 +44,22 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.nextcloud.talk.R -@Suppress("LongMethod") @Composable fun DiagnoseContentComposable( data: State>, - diagnoseViewModel: DiagnoseViewModel + isLoading: Boolean, + showDialog: Boolean, + message: String, + onTestPushClick: () -> Unit, + onDismissDialog: () -> Unit ) { val context = LocalContext.current - val message = diagnoseViewModel.notificationMessage - val isLoading = diagnoseViewModel.isLoading - val showDialog = diagnoseViewModel.showDialog Column( modifier = Modifier .fillMaxSize() @@ -66,39 +69,15 @@ fun DiagnoseContentComposable( data.value.forEach { element -> when (element) { is DiagnoseActivity.DiagnoseElement.DiagnoseHeadline -> { - if (element.headline == "Test push notifications") { - Button( - modifier = Modifier - .wrapContentSize() - .padding(vertical = 8.dp), - onClick = { - diagnoseViewModel.fetchTestPushResult() - } - ) { - Text( - text = element.headline, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - color = colorResource(R.color.high_emphasis_text), - fontSize = LocalDensity.current.run { - dimensionResource(R.dimen.headline_text_size).toPx().toSp() - }, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - } - } else { - Text( - modifier = Modifier.fillMaxWidth().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 - ) - } + Text( + modifier = Modifier.fillMaxWidth().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 -> { @@ -115,30 +94,84 @@ fun DiagnoseContentComposable( } } } - ShowNotificationData(isLoading.value, showDialog.value, context, message.value, diagnoseViewModel) + ShowTestPushButton(onTestPushClick) + ShowNotificationData(isLoading, showDialog, context, message, onDismissDialog) + } +} + +@Composable +fun ShowTestPushButton(onTestPushClick: () -> Unit) { + Button( + modifier = Modifier + .wrapContentSize() + .padding(vertical = 8.dp), + onClick = { + onTestPushClick() + } + ) { + Text( + text = stringResource(R.string.nc_test_push_button), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp), + fontSize = LocalDensity.current.run { + dimensionResource(R.dimen.headline_text_size).toPx().toSp() + }, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + } +} + +@Composable +fun ShowOptions(onDismissDialog: () -> Unit, message: String, context: Context) { + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier.fillMaxWidth() + ) { + TextButton(onClick = { onDismissDialog() }) { + Text(text = stringResource(R.string.nc_cancel)) + } + Spacer(modifier = Modifier.width(8.dp)) + TextButton(onClick = { + val clipboard = + context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("Push Message", message) + clipboard.setPrimaryClip(clip) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + Toast.makeText(context, R.string.message_copied, Toast.LENGTH_SHORT).show() + } + onDismissDialog() + }) { + Text(text = stringResource(R.string.nc_common_copy)) + } + } +} + +@Composable +fun LoadingIndicator() { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator() } } @Composable -@Suppress("LongMethod") fun ShowNotificationData( isLoading: Boolean, showDialog: Boolean, context: Context, message: String, - diagnoseViewModel: DiagnoseViewModel + onDismissDialog: () -> Unit ) { if (isLoading) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } + LoadingIndicator() } if (showDialog) { Dialog( - onDismissRequest = { diagnoseViewModel.dismissDialog() }, + onDismissRequest = { onDismissDialog() }, properties = DialogProperties( dismissOnClickOutside = true, usePlatformDefaultWidth = false @@ -157,42 +190,48 @@ fun ShowNotificationData( style = MaterialTheme.typography .titleMedium ) - Spacer(modifier = Modifier.height(12.dp)) Box( modifier = Modifier .fillMaxWidth() .weight(1f, fill = false) .verticalScroll(rememberScrollState()) ) { - Text( - modifier = Modifier.padding(top = 8.dp), - text = message - ) + Column(modifier = Modifier.padding(top = 12.dp)) { + Text( + text = stringResource(R.string.nc_push_notification_message), + color = colorResource(R.color.colorPrimary) + ) + Text( + modifier = Modifier.padding(top = 12.dp), + text = message + ) + } } Spacer(modifier = Modifier.height(16.dp)) - Row( - horizontalArrangement = Arrangement.SpaceEvenly, - modifier = Modifier.fillMaxWidth() - ) { - TextButton(onClick = { diagnoseViewModel.dismissDialog() }) { - Text(text = stringResource(R.string.nc_cancel)) - } - Spacer(modifier = Modifier.width(8.dp)) - TextButton(onClick = { - val clipboard = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = ClipData.newPlainText("Push Message", message) - clipboard.setPrimaryClip(clip) - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { - Toast.makeText(context, R.string.message_copied, Toast.LENGTH_SHORT).show() - } - diagnoseViewModel.dismissDialog() - }) { - Text(text = stringResource(R.string.nc_common_copy)) - } - } + ShowOptions(onDismissDialog, message, context) } } } } } + +@Preview(showBackground = true) +@Composable +fun DiagnoseContentPreview() { + val state = remember { + mutableStateOf( + listOf( + DiagnoseActivity.DiagnoseElement.DiagnoseHeadline("Headline"), + DiagnoseActivity.DiagnoseElement.DiagnoseEntry("Key", "Value") + ) + ) + } + DiagnoseContentComposable( + state, + false, + true, + "Testing Push Messages", + {}, + {} + ) +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b1f2c9b43..123a87c55 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -231,6 +231,8 @@ How to translate with transifex: "Test push notifications Test results Message copied + Push notification is sent successfully. You should now receive + a notification on this device with the title \'Testing push notifications\' Leave conversation From 61d0e323b3b0089c9263f7e6d7d12c8f7d85ad77 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Tue, 15 Apr 2025 16:12:58 +0200 Subject: [PATCH 7/9] fix detekt Signed-off-by: sowjanyakch --- .../com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index ba6047e89..e024eb4f2 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -50,6 +50,7 @@ import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.nextcloud.talk.R +@Suppress("LongParameterList") @Composable fun DiagnoseContentComposable( data: State>, From 0b6ed3bcc1ac96e2f9863b02bc9bcc63d886fbdc Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 17 Apr 2025 15:26:51 +0200 Subject: [PATCH 8/9] improvements Signed-off-by: sowjanyakch --- .../talk/diagnose/DiagnoseActivity.kt | 10 +++-- .../diagnose/DiagnoseContentComposable.kt | 39 +++++++++++++------ .../talk/diagnose/DiagnoseViewModel.kt | 17 ++++++-- app/src/main/res/values/strings.xml | 2 + 4 files changed, 49 insertions(+), 19 deletions(-) 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 69e728c98..c2dcf88fa 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseActivity.kt @@ -23,6 +23,7 @@ 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.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource @@ -88,6 +89,7 @@ class DiagnoseActivity : BaseActivity() { )[DiagnoseViewModel::class.java] val colorScheme = viewThemeUtils.getColorScheme(this) + isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable setContent { val backgroundColor = colorResource(id = R.color.bg_default) @@ -115,6 +117,7 @@ class DiagnoseActivity : BaseActivity() { ) }, content = { + val viewState = diagnoseViewModel.notificationViewState.collectAsState().value Column( Modifier .padding(it) @@ -125,9 +128,10 @@ class DiagnoseActivity : BaseActivity() { diagnoseDataState, isLoading = diagnoseViewModel.isLoading.value, showDialog = diagnoseViewModel.showDialog.value, - message = diagnoseViewModel.notificationMessage.value, + viewState = viewState, onTestPushClick = { diagnoseViewModel.fetchTestPushResult() }, - onDismissDialog = { diagnoseViewModel.dismissDialog() } + onDismissDialog = { diagnoseViewModel.dismissDialog() }, + isGooglePlayServicesAvailable = isGooglePlayServicesAvailable ) } } @@ -141,8 +145,6 @@ class DiagnoseActivity : BaseActivity() { super.onResume() supportActionBar?.show() - isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable - diagnoseData.clear() setupMetaValues() setupPhoneValues() diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index e024eb4f2..e46ce408b 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -56,9 +56,10 @@ fun DiagnoseContentComposable( data: State>, isLoading: Boolean, showDialog: Boolean, - message: String, + viewState: NotificationUiState, onTestPushClick: () -> Unit, - onDismissDialog: () -> Unit + onDismissDialog: () -> Unit, + isGooglePlayServicesAvailable: Boolean ) { val context = LocalContext.current Column( @@ -95,8 +96,10 @@ fun DiagnoseContentComposable( } } } - ShowTestPushButton(onTestPushClick) - ShowNotificationData(isLoading, showDialog, context, message, onDismissDialog) + if (isGooglePlayServicesAvailable) { + ShowTestPushButton(onTestPushClick) + } + ShowNotificationData(isLoading, showDialog, context, viewState, onDismissDialog) } } @@ -164,9 +167,20 @@ fun ShowNotificationData( isLoading: Boolean, showDialog: Boolean, context: Context, - message: String, + viewState: NotificationUiState, onDismissDialog: () -> Unit ) { + val message = when (viewState) { + is NotificationUiState.Success -> viewState.testNotification ?: context.getString( + R.string.nc_push_notification_fetch_error + ) + is NotificationUiState.Error -> String.format( + context.getString(R.string.nc_push_notification_error), + viewState.message + ) + else -> context.getString(R.string.nc_common_error_sorry) + } + if (isLoading) { LoadingIndicator() } @@ -198,10 +212,12 @@ fun ShowNotificationData( .verticalScroll(rememberScrollState()) ) { Column(modifier = Modifier.padding(top = 12.dp)) { - Text( - text = stringResource(R.string.nc_push_notification_message), - color = colorResource(R.color.colorPrimary) - ) + if (viewState is NotificationUiState.Success) { + Text( + text = stringResource(R.string.nc_push_notification_message), + color = colorResource(R.color.colorPrimary) + ) + } Text( modifier = Modifier.padding(top = 12.dp), text = message @@ -231,8 +247,9 @@ fun DiagnoseContentPreview() { state, false, true, - "Testing Push Messages", + NotificationUiState.Success("Test notification successful"), {}, - {} + {}, + true ) } diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt index e0b10d06a..6fca3b8da 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseViewModel.kt @@ -14,6 +14,8 @@ import com.nextcloud.talk.api.NcApiCoroutines import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject @@ -26,8 +28,8 @@ class DiagnoseViewModel @Inject constructor( val currentUser: User = _currentUser val credentials = ApiUtils.getCredentials(_currentUser.username, _currentUser.token) ?: "" - private val _notificationMessage = mutableStateOf("") - val notificationMessage = _notificationMessage + private val _notificationViewState = MutableStateFlow(NotificationUiState.None) + val notificationViewState: StateFlow = _notificationViewState private val _isLoading = mutableStateOf(false) val isLoading = _isLoading @@ -44,9 +46,10 @@ class DiagnoseViewModel @Inject constructor( ApiUtils .getUrlForTestPushNotifications(_currentUser.baseUrl ?: "") ) - _notificationMessage.value = response.ocs?.data?.message ?: "Error while fetching test push message" + val notificationMessage = response.ocs?.data?.message + _notificationViewState.value = NotificationUiState.Success(notificationMessage) } catch (e: Exception) { - _notificationMessage.value = "Exception: ${e.localizedMessage}" + _notificationViewState.value = NotificationUiState.Error(e.message ?: "") } finally { _isLoading.value = false _showDialog.value = true @@ -58,3 +61,9 @@ class DiagnoseViewModel @Inject constructor( _showDialog.value = false } } + +sealed class NotificationUiState { + data object None : NotificationUiState() + data class Success(val testNotification: String?) : NotificationUiState() + data class Error(val message: String) : NotificationUiState() +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 123a87c55..80c3a9e01 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,6 +67,8 @@ How to translate with transifex: Display name couldn\'t be fetched, aborting %1$s not available (not installed or restricted by admin) Could not store display name, aborting + Sorry something went wrong, error is %1$s + Sorry something went wrong, cannot fetch test push message Search From fd6bb5b17ed86187b64350e96c25860698b05f7a Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 17 Apr 2025 15:46:37 +0200 Subject: [PATCH 9/9] detekt Signed-off-by: sowjanyakch --- .../diagnose/DiagnoseContentComposable.kt | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt index e46ce408b..f6cfba19e 100644 --- a/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt +++ b/app/src/main/java/com/nextcloud/talk/diagnose/DiagnoseContentComposable.kt @@ -170,16 +170,7 @@ fun ShowNotificationData( viewState: NotificationUiState, onDismissDialog: () -> Unit ) { - val message = when (viewState) { - is NotificationUiState.Success -> viewState.testNotification ?: context.getString( - R.string.nc_push_notification_fetch_error - ) - is NotificationUiState.Error -> String.format( - context.getString(R.string.nc_push_notification_error), - viewState.message - ) - else -> context.getString(R.string.nc_common_error_sorry) - } + val message = getMessage(context, viewState) if (isLoading) { LoadingIndicator() @@ -232,6 +223,19 @@ fun ShowNotificationData( } } +fun getMessage(context: Context, viewState: NotificationUiState): String { + return when (viewState) { + is NotificationUiState.Success -> + viewState.testNotification ?: context.getString(R.string.nc_push_notification_fetch_error) + + is NotificationUiState.Error -> + context.getString(R.string.nc_push_notification_error, viewState.message) + + else -> + context.getString(R.string.nc_common_error_sorry) + } +} + @Preview(showBackground = true) @Composable fun DiagnoseContentPreview() {