diff --git a/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png b/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png index 1d3297faceb4..6b0f9ad6ce81 100644 Binary files a/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png and b/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png differ diff --git a/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png b/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png index 1d3297faceb4..6b0f9ad6ce81 100644 Binary files a/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png and b/app/screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png differ diff --git a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java index 5039fb427441..24200fd83ed5 100644 --- a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java +++ b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java @@ -95,6 +95,7 @@ import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; import com.owncloud.android.ui.dialog.RenamePublicShareDialogFragment; +import com.owncloud.android.ui.dialog.SendFilesDialog; import com.owncloud.android.ui.dialog.SendShareDialog; import com.owncloud.android.ui.dialog.SetupEncryptionDialogFragment; import com.owncloud.android.ui.dialog.SharePasswordDialogFragment; @@ -460,6 +461,9 @@ abstract class ComponentsModule { @ContributesAndroidInjector abstract FileActionsBottomSheet fileActionsBottomSheet(); + @ContributesAndroidInjector + abstract SendFilesDialog sendFilesDialog(); + @ContributesAndroidInjector abstract DocumentScanActivity documentScanActivity(); diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.java b/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.java deleted file mode 100644 index b38bde87d644..000000000000 --- a/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.owncloud.android.ui.dialog; - -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Toast; - -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; -import com.nextcloud.client.utils.IntentUtil; -import com.owncloud.android.R; -import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.ui.adapter.SendButtonAdapter; -import com.owncloud.android.ui.components.SendButtonData; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -/* - * Nextcloud Android client application - * - * @author Tobias Kaminsky - * Copyright (C) 2020 Tobias Kaminsky - * Copyright (C) 2020 Nextcloud GmbH. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -public class SendFilesDialog extends BottomSheetDialogFragment { - - private static final String KEY_OCFILES = "KEY_OCFILES"; - - private OCFile[] files; - - public static SendFilesDialog newInstance(Set files) { - - SendFilesDialog dialogFragment = new SendFilesDialog(); - - Bundle args = new Bundle(); - args.putParcelableArray(KEY_OCFILES, files.toArray(new OCFile[0])); - dialogFragment.setArguments(args); - - return dialogFragment; - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // keep the state of the fragment on configuration changes - setRetainInstance(true); - - files = (OCFile[]) requireArguments().getParcelableArray(KEY_OCFILES); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.send_files_fragment, container, false); - - // populate send apps - Intent sendIntent = IntentUtil.createSendIntent(requireContext(), files); - List matches = requireActivity().getPackageManager().queryIntentActivities(sendIntent, 0); - if (matches.isEmpty()) { - Toast.makeText(getContext(), R.string.no_send_app, Toast.LENGTH_SHORT).show(); - dismiss(); - return null; - } - - List sendButtonDataList = setupSendButtonData(matches); - - SendButtonAdapter.ClickListener clickListener = setupSendButtonClickListener(sendIntent); - - RecyclerView sendButtonsView = view.findViewById(R.id.send_button_recycler_view); - sendButtonsView.setLayoutManager(new GridLayoutManager(getActivity(), 4)); - sendButtonsView.setAdapter(new SendButtonAdapter(sendButtonDataList, clickListener)); - - return view; - } - - @NonNull - private SendButtonAdapter.ClickListener setupSendButtonClickListener(Intent sendIntent) { - return sendButtonDataData -> { - String packageName = sendButtonDataData.getPackageName(); - String activityName = sendButtonDataData.getActivityName(); - - sendIntent.setComponent(new ComponentName(packageName, activityName)); - requireActivity().startActivity(Intent.createChooser(sendIntent, getString(R.string.send))); - - dismiss(); - }; - } - - @NonNull - private List setupSendButtonData(List matches) { - Drawable icon; - SendButtonData sendButtonData; - CharSequence label; - - List sendButtonDataList = new ArrayList<>(matches.size()); - for (ResolveInfo match : matches) { - icon = match.loadIcon(requireActivity().getPackageManager()); - label = match.loadLabel(requireActivity().getPackageManager()); - sendButtonData = new SendButtonData(icon, label, - match.activityInfo.packageName, - match.activityInfo.name); - - sendButtonDataList.add(sendButtonData); - } - return sendButtonDataList; - } -} diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.kt b/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.kt new file mode 100644 index 000000000000..b11dc503f8c8 --- /dev/null +++ b/app/src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.kt @@ -0,0 +1,138 @@ +package com.owncloud.android.ui.dialog + +import android.content.ComponentName +import android.content.Intent +import android.content.pm.ResolveInfo +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.nextcloud.android.common.ui.theme.utils.ColorRole +import com.nextcloud.client.di.Injectable +import com.nextcloud.client.utils.IntentUtil.createSendIntent +import com.owncloud.android.R +import com.owncloud.android.databinding.SendFilesFragmentBinding +import com.owncloud.android.datamodel.OCFile +import com.owncloud.android.ui.adapter.SendButtonAdapter +import com.owncloud.android.ui.components.SendButtonData +import com.owncloud.android.utils.theme.ViewThemeUtils +import javax.inject.Inject + +/* + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2020 Tobias Kaminsky + * Copyright (C) 2020 Nextcloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +class SendFilesDialog : BottomSheetDialogFragment(R.layout.send_files_fragment), Injectable { + + private var files: Array? = null + private lateinit var binding: SendFilesFragmentBinding + + @JvmField + @Inject + var viewThemeUtils: ViewThemeUtils? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + // keep the state of the fragment on configuration changes + retainInstance = true + + files = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + requireArguments().getParcelableArray(KEY_OCFILES, OCFile::class.java) + } else { + @Suppress("DEPRECATION") + requireArguments().getParcelableArray(KEY_OCFILES) as Array? + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = SendFilesFragmentBinding.inflate(inflater, container, false) + + setupSendButtonRecyclerView() + viewThemeUtils?.platform?.colorViewBackground(binding.bottomSheet, ColorRole.SURFACE) + + return binding.root + } + + private fun setupSendButtonRecyclerView() { + val sendIntent = createSendIntent(requireContext(), files!!) + val matches = requireActivity().packageManager.queryIntentActivities(sendIntent, 0) + + if (matches.isEmpty()) { + Toast.makeText(context, R.string.no_send_app, Toast.LENGTH_SHORT).show() + dismiss() + return + } + + val sendButtonDataList = setupSendButtonData(matches) + val clickListener = setupSendButtonClickListener(sendIntent) + + @Suppress("MagicNumber") + binding.sendButtonRecyclerView.layoutManager = GridLayoutManager(requireActivity(), 4) + binding.sendButtonRecyclerView.adapter = SendButtonAdapter(sendButtonDataList, clickListener) + } + + private fun setupSendButtonClickListener(sendIntent: Intent): SendButtonAdapter.ClickListener { + return SendButtonAdapter.ClickListener { sendButtonDataData: SendButtonData -> + val packageName = sendButtonDataData.packageName + val activityName = sendButtonDataData.activityName + sendIntent.component = ComponentName(packageName, activityName) + requireActivity().startActivity(Intent.createChooser(sendIntent, getString(R.string.send))) + dismiss() + } + } + + private fun setupSendButtonData(matches: List): List { + var icon: Drawable + var sendButtonData: SendButtonData + var label: CharSequence + val sendButtonDataList: MutableList = ArrayList(matches.size) + for (match in matches) { + icon = match.loadIcon(requireActivity().packageManager) + label = match.loadLabel(requireActivity().packageManager) + sendButtonData = SendButtonData( + icon, label, + match.activityInfo.packageName, + match.activityInfo.name + ) + sendButtonDataList.add(sendButtonData) + } + return sendButtonDataList + } + + companion object { + private const val KEY_OCFILES = "KEY_OCFILES" + + fun newInstance(files: Set): SendFilesDialog { + val dialogFragment = SendFilesDialog() + val args = Bundle() + args.putParcelableArray(KEY_OCFILES, files.toTypedArray()) + dialogFragment.arguments = args + return dialogFragment + } + } +} diff --git a/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java index 68f3720a28c6..4fa13c39fdc5 100755 --- a/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java +++ b/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java @@ -810,7 +810,7 @@ public void sendFiles(Set files) { FragmentTransaction ft = fm.beginTransaction(); ft.addToBackStack(null); - SendFilesDialog sendFilesDialog = SendFilesDialog.newInstance(files); + SendFilesDialog sendFilesDialog = SendFilesDialog.Companion.newInstance(files); sendFilesDialog.show(ft, "TAG_SEND_SHARE_DIALOG"); } diff --git a/app/src/main/res/layout/send_files_fragment.xml b/app/src/main/res/layout/send_files_fragment.xml index 07b1d96accab..121a73ac046d 100644 --- a/app/src/main/res/layout/send_files_fragment.xml +++ b/app/src/main/res/layout/send_files_fragment.xml @@ -18,19 +18,38 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - + android:layout_height="wrap_content" + android:layout_gravity="bottom" + app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"> - + android:layout_height="wrap_content" + android:orientation="vertical"> + + - - + tools:listitem="@layout/send_button"/> + + + + + +