@@ -11,21 +11,26 @@ import android.content.ClipboardManager
1111import android.os.Bundle
1212import android.widget.Toast
1313import androidx.activity.compose.setContent
14+ import androidx.activity.result.contract.ActivityResultContracts
1415import androidx.compose.foundation.background
1516import androidx.compose.foundation.layout.Column
1617import androidx.compose.foundation.layout.displayCutoutPadding
1718import androidx.compose.foundation.layout.fillMaxSize
1819import androidx.compose.foundation.layout.padding
1920import androidx.compose.foundation.layout.statusBarsPadding
21+ import androidx.compose.material3.ColorScheme
2022import androidx.compose.material3.MaterialTheme
2123import androidx.compose.material3.Scaffold
24+ import androidx.compose.runtime.Composable
25+ import androidx.compose.runtime.MutableState
2226import androidx.compose.runtime.collectAsState
2327import androidx.compose.runtime.mutableStateOf
2428import androidx.compose.ui.Modifier
2529import androidx.compose.ui.res.colorResource
2630import androidx.compose.ui.res.stringResource
2731import androidx.compose.ui.unit.dp
2832import androidx.lifecycle.ViewModelProvider
33+ import androidx.lifecycle.lifecycleScope
2934import autodagger.AutoInjector
3035import com.nextcloud.talk.R
3136import com.nextcloud.talk.activities.BaseActivity
@@ -35,11 +40,14 @@ import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
3540import com.nextcloud.talk.components.ColoredStatusBar
3641import com.nextcloud.talk.components.StandardAppBar
3742import com.nextcloud.talk.data.network.NetworkMonitor
43+ import com.nextcloud.talk.errorhandling.saveLogsAsZip
3844import com.nextcloud.talk.logger.LogsRepository
3945import com.nextcloud.talk.users.UserManager
4046import com.nextcloud.talk.utils.ClosedInterfaceImpl
4147import com.nextcloud.talk.utils.UnifiedPushUtils
4248import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
49+ import kotlinx.coroutines.Dispatchers
50+ import kotlinx.coroutines.launch
4351import javax.inject.Inject
4452
4553@AutoInjector(NextcloudTalkApplication ::class )
@@ -69,6 +77,18 @@ class DiagnosisActivity : BaseActivity() {
6977 private val diagnosisData = mutableListOf<DiagnosisElement >()
7078 private val diagnosisDataState = mutableStateOf(emptyList<DiagnosisElement >())
7179
80+ private val saveZipLauncher =
81+ registerForActivityResult(ActivityResultContracts .CreateDocument (" application/zip" )) { uri ->
82+ if (uri != null ) {
83+ val diagnosisText = buildDiagnosisReportText(this , userManager, appPreferences, logsRepository)
84+ lifecycleScope.launch(Dispatchers .IO ) {
85+ contentResolver.openOutputStream(uri)?.use { os ->
86+ saveLogsAsZip(this @DiagnosisActivity, os, diagnosisText)
87+ }
88+ }
89+ }
90+ }
91+
7292 override fun onCreate (savedInstanceState : Bundle ? ) {
7393 super .onCreate(savedInstanceState)
7494 NextcloudTalkApplication .sharedApplication!! .componentApplication.inject(this )
@@ -81,59 +101,19 @@ class DiagnosisActivity : BaseActivity() {
81101 val isGooglePlayServicesAvailable = ClosedInterfaceImpl ().isGooglePlayServicesAvailable
82102 val useUnifiedPush = appPreferences.useUnifiedPush
83103 val useEmbeddedDistrib = UnifiedPushUtils .hasEmbeddedDistributor(context) && ! useUnifiedPush
104+ val showTestPushButton = isGooglePlayServicesAvailable || useUnifiedPush || useEmbeddedDistrib
84105
85106 setContent {
86- val backgroundColor = colorResource(id = R .color.bg_default)
87-
88- val menuItems = listOf (
89- stringResource(R .string.nc_common_copy) to { copyToClipboard(diagnosisData.toMarkdown()) }
107+ DiagnosisScreen (
108+ colorScheme = colorScheme,
109+ networkMonitor = networkMonitor,
110+ diagnosisData = diagnosisData,
111+ diagnosisDataState = diagnosisDataState,
112+ diagnosisViewModel = diagnosisViewModel,
113+ showTestPushButton = showTestPushButton,
114+ onCopyClick = ::copyToClipboard,
115+ onShareReportClick = ::openShareReportDialog
90116 )
91-
92- MaterialTheme (
93- colorScheme = colorScheme
94- ) {
95- val isOnline = networkMonitor.isOnline.collectAsState().value
96- ColoredStatusBar ()
97- Scaffold (
98- modifier = Modifier
99- .statusBarsPadding()
100- .displayCutoutPadding(),
101- topBar = {
102- StandardAppBar (
103- title = stringResource(R .string.nc_settings_diagnosis_title),
104- menuItems
105- )
106- },
107- content = { paddingValues ->
108- val viewState = diagnosisViewModel.notificationViewState.collectAsState().value
109-
110- Column (
111- Modifier
112- .background(backgroundColor)
113- .padding(
114- 0 .dp,
115- paddingValues.calculateTopPadding(),
116- 0 .dp,
117- paddingValues.calculateBottomPadding()
118- )
119- .fillMaxSize()
120- ) {
121- DiagnosisContentComposable (
122- diagnosisDataState,
123- isLoading = diagnosisViewModel.isLoading.value,
124- showDialog = diagnosisViewModel.showDialog.value,
125- viewState = viewState,
126- onTestPushClick = { diagnosisViewModel.fetchTestPushResult() },
127- onDismissDialog = { diagnosisViewModel.dismissDialog() },
128- showTestPushButton = isGooglePlayServicesAvailable ||
129- useUnifiedPush ||
130- useEmbeddedDistrib,
131- isOnline = isOnline
132- )
133- }
134- }
135- )
136- }
137117 }
138118 }
139119
@@ -154,6 +134,10 @@ class DiagnosisActivity : BaseActivity() {
154134 diagnosisDataState.value = diagnosisData.toList()
155135 }
156136
137+ private fun openShareReportDialog () {
138+ showShareReportDialog(this , userManager, appPreferences, logsRepository, saveZipLauncher)
139+ }
140+
157141 private fun copyToClipboard (text : String ) {
158142 val clipboardManager =
159143 getSystemService(CLIPBOARD_SERVICE ) as ClipboardManager
@@ -174,3 +158,67 @@ class DiagnosisActivity : BaseActivity() {
174158 val TAG = DiagnosisActivity ::class .java.simpleName
175159 }
176160}
161+
162+ @Suppress(" LongParameterList" )
163+ @Composable
164+ private fun DiagnosisScreen (
165+ colorScheme : ColorScheme ,
166+ networkMonitor : NetworkMonitor ,
167+ diagnosisData : List <DiagnosisElement >,
168+ diagnosisDataState : MutableState <List <DiagnosisElement >>,
169+ diagnosisViewModel : DiagnosisViewModel ,
170+ showTestPushButton : Boolean ,
171+ onCopyClick : (String ) -> Unit ,
172+ onShareReportClick : () -> Unit
173+ ) {
174+ val backgroundColor = colorResource(id = R .color.bg_default)
175+
176+ val menuItems = listOf (
177+ stringResource(R .string.nc_common_copy) to { onCopyClick(diagnosisData.toMarkdown()) },
178+ stringResource(R .string.nc_settings_share_report_title) to onShareReportClick
179+ )
180+
181+ MaterialTheme (
182+ colorScheme = colorScheme
183+ ) {
184+ val isOnline = networkMonitor.isOnline.collectAsState().value
185+ ColoredStatusBar ()
186+ Scaffold (
187+ modifier = Modifier
188+ .statusBarsPadding()
189+ .displayCutoutPadding(),
190+ topBar = {
191+ StandardAppBar (
192+ title = stringResource(R .string.nc_settings_diagnosis_title),
193+ menuItems
194+ )
195+ },
196+ content = { paddingValues ->
197+ val viewState = diagnosisViewModel.notificationViewState.collectAsState().value
198+
199+ Column (
200+ Modifier
201+ .background(backgroundColor)
202+ .padding(
203+ 0 .dp,
204+ paddingValues.calculateTopPadding(),
205+ 0 .dp,
206+ paddingValues.calculateBottomPadding()
207+ )
208+ .fillMaxSize()
209+ ) {
210+ DiagnosisContentComposable (
211+ diagnosisDataState,
212+ isLoading = diagnosisViewModel.isLoading.value,
213+ showDialog = diagnosisViewModel.showDialog.value,
214+ viewState = viewState,
215+ onTestPushClick = { diagnosisViewModel.fetchTestPushResult() },
216+ onDismissDialog = { diagnosisViewModel.dismissDialog() },
217+ showTestPushButton = showTestPushButton,
218+ isOnline = isOnline
219+ )
220+ }
221+ }
222+ )
223+ }
224+ }
0 commit comments