Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 547b732d authored by alperozturk's avatar alperozturk
Browse files

add ShareLinkToDialog

parent 0dec9900
Loading
Loading
Loading
Loading
+48 −8
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ package it.niedermann.owncloud.notes.share;
import android.Manifest;
import android.app.Activity;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -15,6 +16,7 @@ import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
@@ -43,10 +45,11 @@ import it.niedermann.owncloud.notes.databinding.FragmentNoteShareBinding;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.persistence.entity.Note;
import it.niedermann.owncloud.notes.share.adapter.ShareeListAdapter;
import it.niedermann.owncloud.notes.share.dialog.ShareLinkToDialog;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;
import it.niedermann.owncloud.notes.share.model.UsersAndGroupsSearchConfig;
import it.niedermann.owncloud.notes.shared.user.User;
import it.niedermann.owncloud.notes.shared.util.ClipboardUtil;
import it.niedermann.owncloud.notes.shared.util.clipboard.ClipboardUtil;
import it.niedermann.owncloud.notes.shared.util.extensions.BundleExtensionsKt;

public class NoteShareFragment extends Fragment implements ShareeListAdapterListener {
@@ -55,6 +58,7 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
    private static final String ARG_NOTE = "NOTE";
    private static final String ARG_ACCOUNT = "ACCOUNT";
    private static final String ARG_USER = "USER";
    public static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";

    private FragmentNoteShareBinding binding;
    private Note note;
@@ -157,14 +161,17 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
    private void setupView() {
        setShareWithYou();

        OCFile parentFile = fileDataStorageManager.getFileById(file.getParentId());
        // OCFile parentFile = fileDataStorageManager.getFileById(file.getParentId());

        FileDetailSharingFragmentHelper.setupSearchView(
                (SearchManager) fileActivity.getSystemService(Context.SEARCH_SERVICE),
                binding.searchView,
                fileActivity.getComponentName());
        viewThemeUtils.androidx.themeToolbarSearchView(binding.searchView);
        setupSearchView((SearchManager) requireContext().getSystemService(Context.SEARCH_SERVICE), binding.searchView, requireActivity().getComponentName());
        // viewThemeUtils.androidx.themeToolbarSearchView(binding.searchView);

        binding.searchView.setQueryHint(getResources().getString(R.string.note_share_fragment_resharing_not_allowed));
        binding.searchView.setInputType(InputType.TYPE_NULL);
        binding.pickContactEmailBtn.setVisibility(View.GONE);
        disableSearchView(binding.searchView);

        /*
        if (file.canReshare()) {
            binding.searchView.setQueryHint(getResources().getString(R.string.note_share_fragment_search_text));
        } else {
@@ -173,6 +180,39 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList
            binding.pickContactEmailBtn.setVisibility(View.GONE);
            disableSearchView(binding.searchView);
        }
         */

    }

    private void setupSearchView(@Nullable SearchManager searchManager, SearchView searchView,
                                       ComponentName componentName) {
        if (searchManager == null) {
            searchView.setVisibility(View.GONE);
            return;
        }

        // assumes parent activity is the searchable activity
        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));

        // do not iconify the widget; expand it by default
        searchView.setIconifiedByDefault(false);

        // avoid fullscreen with softkeyboard
        searchView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // return true to prevent the query from being processed;
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // leave it for the parent listener in the hierarchy / default behaviour
                return false;
            }
        });
    }

    private void disableSearchView(View view) {
@@ -249,7 +289,7 @@ public class NoteShareFragment extends Fragment implements ShareeListAdapterList

        String[] packagesToExclude = new String[] { requireContext().getPackageName() };
        DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intentToShareLink, packagesToExclude);
        chooserDialog.show(getParentFragmentManager(), FileDisplayActivity.FTAG_CHOOSER_DIALOG);
        chooserDialog.show(getParentFragmentManager(), FTAG_CHOOSER_DIALOG);
    }

    // TODO: Check account.getUrl returning base url?
+141 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.share.dialog


import android.app.Dialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.owncloud.android.lib.common.utils.Log_OC
import it.niedermann.owncloud.notes.R
import it.niedermann.owncloud.notes.shared.util.clipboard.CopyToClipboardActivity
import it.niedermann.owncloud.notes.shared.util.extensions.getParcelableArgument
import java.util.Collections

/**
 * Dialog showing a list activities able to resolve a given Intent,
 * filtering out the activities matching give package names.
 */
class ShareLinkToDialog : DialogFragment() {
    private var mAdapter: ActivityAdapter? = null
    private var mIntent: Intent? = null

    init {
        Log_OC.d(TAG, "constructor")
    }

    @Suppress("SpreadOperator")
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        mIntent = arguments.getParcelableArgument(ARG_INTENT, Intent::class.java) ?: throw NullPointerException()
        val packagesToExclude = arguments?.getStringArray(ARG_PACKAGES_TO_EXCLUDE)
        val packagesToExcludeList = listOf(*packagesToExclude ?: arrayOfNulls(0))
        val pm = activity?.packageManager ?: throw NullPointerException()

        val activities = pm.queryIntentActivities(mIntent!!, PackageManager.MATCH_DEFAULT_ONLY)
        val it = activities.iterator()
        var resolveInfo: ResolveInfo
        while (it.hasNext()) {
            resolveInfo = it.next()
            if (packagesToExcludeList.contains(resolveInfo.activityInfo.packageName.lowercase())) {
                it.remove()
            }
        }

        val sendAction = mIntent?.getBooleanExtra(Intent.ACTION_SEND, false)

        if (sendAction == false) {
            // add activity for copy to clipboard
            val copyToClipboardIntent = Intent(requireActivity(), CopyToClipboardActivity::class.java)
            val copyToClipboard = pm.queryIntentActivities(copyToClipboardIntent, 0)
            if (copyToClipboard.isNotEmpty()) {
                activities.add(copyToClipboard[0])
            }
        }

        Collections.sort(activities, ResolveInfo.DisplayNameComparator(pm))
        mAdapter = ActivityAdapter(requireActivity(), pm, activities)

        return createSelector(sendAction ?: false)
    }

    private fun createSelector(sendAction: Boolean): AlertDialog {
        val titleId = if (sendAction) {
            R.string.activity_chooser_send_file_title
        } else {
            R.string.activity_chooser_title
        }

        return MaterialAlertDialogBuilder(requireActivity())
            .setTitle(titleId)
            .setAdapter(mAdapter) { _, which ->
                // Add the information of the chosen activity to the intent to send
                val chosen = mAdapter?.getItem(which)
                val actInfo = chosen?.activityInfo ?: return@setAdapter
                val name = ComponentName(
                    actInfo.applicationInfo.packageName,
                    actInfo.name
                )
                mIntent?.setComponent(name)
                activity?.startActivity(mIntent)
            }
            .create()
    }

    internal inner class ActivityAdapter(
        context: Context,
        private val mPackageManager: PackageManager,
        apps: List<ResolveInfo>
    ) : ArrayAdapter<ResolveInfo?>(context, R.layout.activity_row, apps) {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            val view = convertView ?: newView(parent)
            bindView(position, view)
            return view
        }

        private fun newView(parent: ViewGroup): View {
            return (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
                .inflate(R.layout.activity_row, parent, false)
        }

        private fun bindView(position: Int, row: View) {
            row.findViewById<TextView>(R.id.title).run {
                text = getItem(position)?.loadLabel(mPackageManager)
            }

            row.findViewById<ImageView>(R.id.icon).run {
                setImageDrawable(getItem(position)?.loadIcon(mPackageManager))
            }
        }
    }

    companion object {
        private val TAG: String = ShareLinkToDialog::class.java.simpleName
        private val ARG_INTENT = ShareLinkToDialog::class.java.simpleName +
                ".ARG_INTENT"
        private val ARG_PACKAGES_TO_EXCLUDE = ShareLinkToDialog::class.java.simpleName +
                ".ARG_PACKAGES_TO_EXCLUDE"

        @JvmStatic
        fun newInstance(intent: Intent?, vararg packagesToExclude: String?): ShareLinkToDialog {
            val bundle = Bundle().apply {
                putParcelable(ARG_INTENT, intent)
                putStringArray(ARG_PACKAGES_TO_EXCLUDE, packagesToExclude)
            }

            return ShareLinkToDialog().apply {
                arguments = bundle
            }
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
 */

package it.niedermann.owncloud.notes.shared.util
package it.niedermann.owncloud.notes.shared.util.clipboard

import android.app.Activity
import android.content.ClipData
+16 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.shared.util.clipboard

import android.app.Activity
import android.content.Intent
import android.os.Bundle

/**
 * Activity copying the text of the received Intent into the system clipboard.
 */
class CopyToClipboardActivity : Activity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ClipboardUtil.copyToClipboard(this, intent.getCharSequenceExtra(Intent.EXTRA_TEXT).toString())
        finish()
    }
}
+37 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Nextcloud - Android Client
  ~
  ~ SPDX-FileCopyrightText: 2017 Andy Scherzinger <info@andy-scherzinger.de>
  ~ SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_item"
    android:layout_width="match_parent"
    android:layout_height="@dimen/activity_row_layout_height"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minWidth="@dimen/activity_row_layout_min_width_independent"
    android:orientation="horizontal"
    android:paddingEnd="@dimen/spacer_2x"
    android:paddingLeft="@dimen/spacer_2x"
    android:paddingRight="@dimen/spacer_2x"
    android:paddingStart="@dimen/spacer_2x">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="@dimen/default_icon_size"
        android:layout_height="@dimen/default_icon_size"
        android:layout_gravity="center_vertical"
        android:layout_marginEnd="@dimen/spacer_2x"
        android:contentDescription="@string/activity_icon" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:textAppearance="?android:attr/textAppearanceLargePopupMenu" />

</LinearLayout>
Loading