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

Commit 54d1f88a authored by Hyunyoung Song's avatar Hyunyoung Song
Browse files

Show suggestion when user taps on folder's edit text

Also, enabled preloading of the folder name db
Bug: 147523650
Bug: 147359653

Change-Id: Ia77e12d2b2bc428263c2b2821a96894a6004d82e
parent 2000228d
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<>();