@@ -81,7 +81,9 @@ import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
8181import com.owncloud.android.utils.PermissionUtil.checkSelfPermission
8282import com.owncloud.android.utils.theme.ViewThemeUtils
8383import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
84+ import kotlinx.coroutines.Dispatchers
8485import kotlinx.coroutines.launch
86+ import kotlinx.coroutines.withContext
8587import javax.inject.Inject
8688
8789class FileDetailSharingFragment : Fragment (), ShareeListAdapterListener, AvatarGenerationListener, Injectable,
@@ -279,85 +281,29 @@ class FileDetailSharingFragment : Fragment(), ShareeListAdapterListener, AvatarG
279281 setShareWithYou()
280282
281283 binding?.run {
282- val parentFile = file?.parentId?.let { fileDataStorageManager?.getFileById(it) }
283-
284284 FileDetailSharingFragmentHelper .setupSearchView(
285285 fileActivity?.getSystemService(Context .SEARCH_SERVICE ) as SearchManager ? ,
286286 searchView,
287287 fileActivity?.componentName
288288 )
289289
290- viewThemeUtils.material.themeSearchCardView(searchCardWrapper)
291- viewThemeUtils.files.themeContentSearchView(searchView)
292- viewThemeUtils.platform.colorImageView(searchViewIcon, ColorRole .ON_SURFACE_VARIANT )
293- viewThemeUtils.platform.colorImageView(pickContactEmailBtn, ColorRole .ON_SURFACE_VARIANT )
294-
295- viewThemeUtils.material.colorMaterialButtonPrimaryOutlined(sendCopyBtn)
296-
297- viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(sharesListInternalShowAll)
298- viewThemeUtils.material.colorMaterialTextButton(sharesListInternalShowAll)
299- sharesListInternalShowAll.setOnClickListener {
300- internalShareeListAdapter?.toggleShowAll()
301- val textRes = if (internalShareeListAdapter?.isShowAll == true ) R .string.show_less else R .string.show_all
302- sharesListInternalShowAll.setText(textRes)
303- }
304-
305- viewThemeUtils.material.colorMaterialButtonPrimaryOutlined(createLink)
290+ themeView(this )
291+ setupShareList(this )
306292
307- viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(sharesListExternalShowAll)
308- sharesListExternalShowAll.let { viewThemeUtils.material.colorMaterialTextButton(it) }
309- sharesListExternalShowAll.setOnClickListener {
310- externalShareeListAdapter!! .toggleShowAll()
311- val textRes = if (externalShareeListAdapter?.isShowAll == true ) R .string.show_less else R .string.show_all
312- sharesListExternalShowAll.setText(textRes)
313- }
314293
315294 if (file?.canReshare() == true && ! FileDetailSharingFragmentHelper .isPublicShareDisabled(capabilities)) {
316- if (file?.isEncrypted == true || (parentFile != null && parentFile.isEncrypted)) {
317- internalShareHeadline.text = resources.getString(R .string.internal_share_headline_end_to_end_encrypted)
318- internalShareDescription.visibility = View .VISIBLE
319- externalSharesHeadline.text = resources.getString(R .string.create_end_to_end_encrypted_share_title)
320-
321- fetchE2EECounter {
322- if (binding == null ) {
323- return @fetchE2EECounter
324- }
325- if (file?.e2eCounter == - 1L ) {
326- // V1 cannot share
327- searchContainer.visibility = View .GONE
328- createLink.visibility = View .GONE
329- } else {
330- createLink.setText(R .string.add_new_secure_file_drop)
331- searchView.setQueryHint(resources.getString(R .string.secure_share_search))
332-
333- if (file?.isSharedViaLink == true ) {
334- searchView.setQueryHint(resources.getString(R .string.share_not_allowed_when_file_drop))
335- searchView.inputType = InputType .TYPE_NULL
336- toggleSearchViewEnable(searchView, false )
337- }
338- }
339- }
340- } else {
341- createLink.setText(R .string.create_link)
342- searchView.setQueryHint(getResources().getString(R .string.share_search_internal))
343- }
344-
345- createLink.setOnClickListener(View .OnClickListener { v: View ? -> createPublicShareLink() })
295+ val parentFile = file?.parentId?.let { fileDataStorageManager?.getFileById(it) }
296+ setupShareView(this , parentFile)
346297 } else {
347- searchView.setQueryHint(getResources().getString(R .string.resharing_is_not_allowed))
348- createLink.visibility = View .GONE
349- externalSharesHeadline.visibility = View .GONE
350- searchView.inputType = InputType .TYPE_NULL
351- pickContactEmailBtn.setVisibility(View .GONE )
352- toggleSearchViewEnable(searchView, false )
353- createLink.setOnClickListener(null )
298+ setupDisabledShareView(this )
354299 }
355300
356301 checkShareViaUser()
357302
358303 if (file?.isFolder == true ) {
359304 sendCopyBtn.visibility = View .GONE
360305 }
306+
361307 sendCopyBtn.setOnClickListener {
362308 startActivity(
363309 Intent .createChooser(
@@ -367,27 +313,117 @@ class FileDetailSharingFragment : Fragment(), ShareeListAdapterListener, AvatarG
367313 )
368314 }
369315 }
316+ }
317+
318+ private fun themeView (binding : FileDetailsSharingFragmentBinding ) {
319+ binding.run {
320+ viewThemeUtils.material.run {
321+ themeSearchCardView(searchCardWrapper)
322+ colorMaterialButtonPrimaryOutlined(sendCopyBtn)
323+ colorMaterialButtonPrimaryBorderless(sharesListInternalShowAll)
324+ colorMaterialTextButton(sharesListInternalShowAll)
325+ colorMaterialButtonPrimaryOutlined(createLink)
326+ colorMaterialButtonPrimaryBorderless(sharesListExternalShowAll)
327+ }
370328
329+ viewThemeUtils.platform.run {
330+ colorImageView(searchViewIcon, ColorRole .ON_SURFACE_VARIANT )
331+ colorImageView(pickContactEmailBtn, ColorRole .ON_SURFACE_VARIANT )
332+ }
371333
334+ viewThemeUtils.files.run {
335+ themeContentSearchView(searchView)
336+ }
337+ }
338+ }
339+
340+ private fun setupShareList (binding : FileDetailsSharingFragmentBinding ) {
341+ binding.run {
342+ sharesListInternalShowAll.setOnClickListener {
343+ internalShareeListAdapter?.toggleShowAll()
344+ val textRes = if (internalShareeListAdapter?.isShowAll == true ) R .string.show_less else R .string.show_all
345+ sharesListInternalShowAll.setText(textRes)
346+ }
347+ sharesListExternalShowAll.let { viewThemeUtils.material.colorMaterialTextButton(it) }
348+ sharesListExternalShowAll.setOnClickListener {
349+ externalShareeListAdapter?.toggleShowAll()
350+ val textRes = if (externalShareeListAdapter?.isShowAll == true ) R .string.show_less else R .string.show_all
351+ sharesListExternalShowAll.setText(textRes)
352+ }
353+ }
372354 }
373355
374- private fun fetchE2EECounter (onComplete : Runnable ? ) {
375- val context = requireContext()
356+ private fun setupViewForEncryptedShare (binding : FileDetailsSharingFragmentBinding ) {
357+ binding.run {
358+ internalShareHeadline.text = resources.getString(R .string.internal_share_headline_end_to_end_encrypted)
359+ internalShareDescription.visibility = View .VISIBLE
360+ externalSharesHeadline.text = resources.getString(R .string.create_end_to_end_encrypted_share_title)
361+
362+ lifecycleScope.launch {
363+ val result = fetchE2EECounter()
364+ if (! result) {
365+ return @launch
366+ }
376367
377- Thread {
378- try {
379- val client = clientFactory.create(user)
380- val metadata = RefreshFolderOperation .getDecryptedFolderMetadata(true , file, client, user, context)
381- if (metadata is DecryptedFolderMetadataFile ) {
382- file?.setE2eCounter(metadata.metadata.counter)
383- fileDataStorageManager?.saveFile(file)
368+ withContext(Dispatchers .Main ) {
369+ if (file?.e2eCounter == - 1L ) {
370+ // V1 cannot share
371+ searchContainer.visibility = View .GONE
372+ createLink.visibility = View .GONE
373+ } else {
374+ createLink.setText(R .string.add_new_secure_file_drop)
375+ searchView.setQueryHint(resources.getString(R .string.secure_share_search))
376+
377+ if (file?.isSharedViaLink == true ) {
378+ searchView.setQueryHint(resources.getString(R .string.share_not_allowed_when_file_drop))
379+ searchView.inputType = InputType .TYPE_NULL
380+ toggleSearchViewEnable(searchView, false )
381+ }
382+ }
384383 }
385- } catch (e: Exception ) {
386- Log_OC .e(TAG , " Error refreshing E2E counter: " + e.message)
387384 }
388- val activity = getActivity()
389- activity?.runOnUiThread(onComplete)
390- }.start()
385+ }
386+ }
387+
388+ private fun setupShareView (binding : FileDetailsSharingFragmentBinding , parentFile : OCFile ? ) {
389+ binding.run {
390+ if (file?.isEncrypted == true || (parentFile != null && parentFile.isEncrypted)) {
391+ setupViewForEncryptedShare(this )
392+ } else {
393+ createLink.setText(R .string.create_link)
394+ searchView.setQueryHint(getResources().getString(R .string.share_search_internal))
395+ }
396+
397+ createLink.setOnClickListener { createPublicShareLink() }
398+ }
399+ }
400+
401+ private fun setupDisabledShareView (binding : FileDetailsSharingFragmentBinding ) {
402+ binding.run {
403+ searchView.setQueryHint(getResources().getString(R .string.resharing_is_not_allowed))
404+ createLink.visibility = View .GONE
405+ externalSharesHeadline.visibility = View .GONE
406+ searchView.inputType = InputType .TYPE_NULL
407+ pickContactEmailBtn.setVisibility(View .GONE )
408+ toggleSearchViewEnable(searchView, false )
409+ createLink.setOnClickListener(null )
410+ }
411+ }
412+
413+ private suspend fun fetchE2EECounter (): Boolean = withContext(Dispatchers .IO ) {
414+ return @withContext try {
415+ val context = requireContext()
416+ val client = clientFactory.create(user)
417+ val metadata = RefreshFolderOperation .getDecryptedFolderMetadata(true , file, client, user, context)
418+ if (metadata is DecryptedFolderMetadataFile ) {
419+ file?.setE2eCounter(metadata.metadata.counter)
420+ fileDataStorageManager?.saveFile(file)
421+ }
422+ true
423+ } catch (e: Exception ) {
424+ Log_OC .e(TAG , " Error refreshing E2E counter: " + e.message)
425+ false
426+ }
391427 }
392428
393429 private fun checkShareViaUser () {
@@ -485,13 +521,17 @@ class FileDetailSharingFragment : Fragment(), ShareeListAdapterListener, AvatarG
485521 }
486522
487523 override fun copyLink (share : OCShare ) {
488- if (file?.isSharedViaLink == true ) {
489- if (TextUtils .isEmpty(share.shareLink)) {
490- fileOperationsHelper?.getFileWithLink(file!! , viewThemeUtils)
491- } else {
492- copyToClipboard(requireActivity(), share.shareLink)
493- }
524+ val file = file ? : return
525+ if (! file.isSharedViaLink) {
526+ return
494527 }
528+
529+ if (TextUtils .isEmpty(share.shareLink)) {
530+ fileOperationsHelper?.getFileWithLink(file, viewThemeUtils)
531+ return
532+ }
533+
534+ copyToClipboard(requireActivity(), share.shareLink)
495535 }
496536
497537 @VisibleForTesting
0 commit comments