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

Commit bab1101b authored by Hyunyoung Song's avatar Hyunyoung Song Committed by Android (Google) Code Review
Browse files

Merge "Show suggestion when user taps on folder's edit text" into ub-launcher3-master

parents d4ec31a5 54d1f88a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ public class ExtendedEditText extends EditText {
     * Implemented by listeners of the back key.
     */
    public interface OnBackKeyListener {
        public boolean onBackKey();
        boolean onBackKey();
    }

    private OnBackKeyListener mBackKeyListener;
+33 −11
Original line number Diff line number Diff line
@@ -297,16 +297,22 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
    }

    public void startEditingFolderName() {
        post(new Runnable() {
            @Override
            public void run() {
        post(() -> {
            if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
                if (TextUtils.isEmpty(mFolderName.getText())) {
                    final String[] suggestedNames = new String[FolderNameProvider.SUGGEST_MAX];
                    mLauncher.getFolderNameProvider().getSuggestedFolderName(getContext(),
                            mInfo.contents, suggestedNames);
                    mFolderName.setText(suggestedNames[0]);
                    mFolderName.displayCompletions(Arrays.asList(suggestedNames).subList(1,
                            suggestedNames.length));
                }
            }
            mFolderName.setHint("");
            mIsEditingName = true;
            }
        });
    }


    @Override
    public boolean onBackKey() {
        // Convert to a string here to ensure that no other state associated with the text field
@@ -316,11 +322,19 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        mFolderIcon.onTitleChanged(newTitle);
        mLauncher.getModelWriter().updateItemInDatabase(mInfo);

        if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
            mFolderName.setText(mInfo.title);
            // TODO: depending on whether the title was manually edited or automatically
            // suggested, apply different hint.
            mFolderName.setHint("");
        } else {
            if (TextUtils.isEmpty(mInfo.title)) {
                mFolderName.setHint(R.string.folder_hint_text);
                mFolderName.setText("");
            } else {
                mFolderName.setHint(null);
            }
        }

        sendCustomAccessibilityEvent(
                this, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
@@ -403,8 +417,12 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
            mFolderName.setHint(null);
        } else {
            mFolderName.setText("");
            if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
                mFolderName.setHint("");
            } else {
                mFolderName.setHint(R.string.folder_hint_text);
            }
        }
        // In case any children didn't come across during loading, clean up the folder accordingly
        mFolderIcon.post(() -> {
            if (getItemCount() <= 1) {
@@ -420,7 +438,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        if (FeatureFlags.FOLDER_NAME_SUGGEST.get()
                && TextUtils.isEmpty(mFolderName.getText().toString())) {
            if (suggestName.length > 0 && !TextUtils.isEmpty(suggestName[0])) {
                mFolderName.setHint(suggestName[0]);
                mFolderName.setHint("");
                mFolderName.setText(suggestName[0]);
                mInfo.title = suggestName[0];
                animateOpen(mInfo.contents, 0, true);
@@ -534,6 +552,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
            openFolder.close(true);
        }

        if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
            mLauncher.getFolderNameProvider().load(getContext());
        }
        mContent.bindItems(items);
        centerAboutIcon();
        mItemsInvalidated = true;
@@ -1350,6 +1371,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
        return itemsOnCurrentPage;
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == mFolderName) {
            if (hasFocus) {
+32 −4
Original line number Diff line number Diff line
@@ -18,13 +18,16 @@ package com.android.launcher3.folder;
import android.content.Context;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;

import com.android.launcher3.AppInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.config.FeatureFlags;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -38,16 +41,26 @@ import java.util.stream.Collectors;
 */
public class FolderNameProvider {

    private static final String TAG = FeatureFlags.FOLDER_NAME_SUGGEST.getKey();
    private static final boolean DEBUG = FeatureFlags.FOLDER_NAME_SUGGEST.get();

    /**
     * IME usually has up to 3 suggest slots. In total, there are 4 suggest slots as the folder
     * name edit box can also be used to provide suggestion.
     */
    public static final int SUGGEST_MAX = 4;

    /**
     * When inheriting class requires precaching, override this method.
     */
    public void load(Context context) {}

    public CharSequence getSuggestedFolderName(Context context,
            ArrayList<WorkspaceItemInfo> workspaceItemInfos, CharSequence[] candidates) {

        CharSequence suggest;
        if (DEBUG) {
            Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(candidates));
        }
        // If all the icons are from work profile,
        // Then, suggest "Work" as the folder name
        List<WorkspaceItemInfo> distinctItemInfos = workspaceItemInfos.stream()
@@ -75,19 +88,28 @@ public class FolderNameProvider {
            // Place it as first viable suggestion and shift everything else
            info.ifPresent(i -> setAsFirstSuggestion(candidates, i.title.toString()));
        }
        if (DEBUG) {
            Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(candidates));
        }
        return candidates[0];
    }

    private void setAsFirstSuggestion(CharSequence[] candidatesOut, CharSequence candidate) {
        if (contains(candidatesOut, candidate)) {
            return;
        }
        for (int i = candidatesOut.length - 1; i > 0; i--) {
            if (TextUtils.isEmpty(candidatesOut[i])) {
                candidatesOut[i - 1] = candidatesOut[i];
            if (!TextUtils.isEmpty(candidatesOut[i - 1])) {
                candidatesOut[i] = candidatesOut[i - 1];
            }
            candidatesOut[0] = candidate;
        }
        candidatesOut[0] = candidate;
    }

    private void setAsLastSuggestion(CharSequence[] candidatesOut, CharSequence candidate) {
        if (contains(candidatesOut, candidate)) {
            return;
        }
        for (int i = 0; i < candidate.length(); i++) {
            if (TextUtils.isEmpty(candidatesOut[i])) {
                candidatesOut[i] = candidate;
@@ -95,6 +117,12 @@ public class FolderNameProvider {
        }
    }

    private boolean contains(CharSequence[] list, CharSequence key) {
        return Arrays.asList(list).stream()
                .filter(s -> s != null)
                .anyMatch(s -> s.toString().equalsIgnoreCase(key.toString()));
    }

    // This method can be moved to some Utility class location.
    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();