diff --git a/app/src/common/shared/com/igalia/wolvic/ui/adapters/Bookmark.java b/app/src/common/shared/com/igalia/wolvic/ui/adapters/Bookmark.java index ee52ac6ed7..829b0fa84e 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/adapters/Bookmark.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/adapters/Bookmark.java @@ -1,5 +1,7 @@ package com.igalia.wolvic.ui.adapters; +import android.util.Log; + import androidx.annotation.NonNull; import java.util.ArrayList; @@ -25,6 +27,11 @@ public enum Type { private Type mType; private boolean mHasChildren; + public Bookmark(String title, String url) { + mTitle = title; + mURL = url; + } + public Bookmark(@NonNull BookmarkNode node, int level, boolean isExpanded) { mIsExpanded = isExpanded; mLevel = level; @@ -131,6 +138,28 @@ private static List getDisplayListTree(@NonNull List boo return children; } + /*public static List getBookmarkItems(@NonNull List bookmarkNodes) { + Log.e("New Tab", "Bookmark nodes size: " + bookmarkNodes.size()); + + ArrayList bookmarkItems = new ArrayList<>(); + + for (BookmarkNode node : bookmarkNodes) { + if (node.getType() == BookmarkNodeType.ITEM) { + //if (node.getTitle() != null) { + //if (node.getType() != BookmarkNodeType.FOLDER && node.getTitle() != null) { + Log.e("New Tab", "Bookmark node's item type recognized"); + Bookmark bookmark = new Bookmark(node, 0, false); + bookmarkItems.add(bookmark); + } else { + Log.e("New Tab", "Not item type. Real type: " + node.getType()); + } + } + + Log.e("New Tab", "Bookmark items size: " + bookmarkItems.size()); + + return bookmarkItems; + }*/ + /** * Traverses the current display list looking for opened folders * @param displayList diff --git a/app/src/common/shared/com/igalia/wolvic/ui/adapters/BookmarkAdapter.java b/app/src/common/shared/com/igalia/wolvic/ui/adapters/BookmarkAdapter.java index ac271eff20..7666512d47 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/adapters/BookmarkAdapter.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/adapters/BookmarkAdapter.java @@ -339,7 +339,6 @@ static class BookmarkViewHolder extends RecyclerView.ViewHolder { } static class BookmarkFolderViewHolder extends RecyclerView.ViewHolder { - final BookmarkItemFolderBinding binding; BookmarkFolderViewHolder(@NonNull BookmarkItemFolderBinding binding) { diff --git a/app/src/common/shared/com/igalia/wolvic/ui/adapters/NewTabAdapter.java b/app/src/common/shared/com/igalia/wolvic/ui/adapters/NewTabAdapter.java new file mode 100644 index 0000000000..85fd98a807 --- /dev/null +++ b/app/src/common/shared/com/igalia/wolvic/ui/adapters/NewTabAdapter.java @@ -0,0 +1,183 @@ +package com.igalia.wolvic.ui.adapters; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.recyclerview.widget.RecyclerView; + +import com.igalia.wolvic.R; +import com.igalia.wolvic.browser.engine.SessionStore; +import com.igalia.wolvic.databinding.BookmarkItemInNewTabBinding; +import com.igalia.wolvic.ui.callbacks.BookmarkItemCallback; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import mozilla.appservices.places.BookmarkRoot; +import mozilla.components.browser.icons.IconRequest; +import mozilla.components.concept.storage.BookmarkNode; + +// Initial implementation: Show, add, delete bookmarks in New Tab page. +// TODO: Implement data structure and logics to handle pages in New Tab that are separate from bookmarks. +public class NewTabAdapter extends RecyclerView.Adapter { + + private List bookmarkItems; + + @Nullable + private final BookmarkItemCallback mBookmarkItemCallback; + + public NewTabAdapter(@Nullable BookmarkItemCallback clickCallback) { + mBookmarkItemCallback = clickCallback; + } + + public void setBookmarkListInNewTab(final List bookmarkNodes) { + //bookmarkItems = Bookmark.getBookmarkItems(bookmarkNodes); + + List newDisplayList; + bookmarkItems = new ArrayList<>(); + newDisplayList = Bookmark.getDisplayListTree(bookmarkNodes, Collections.singletonList(BookmarkRoot.Mobile.getId())); + for (Bookmark node : newDisplayList) { + if (node.getType() == Bookmark.Type.ITEM) { + bookmarkItems.add(node); + } + } + + notifyItemRangeInserted(0, bookmarkItems.size()); + } + + public void removeItem(Bookmark aBookmark) { + bookmarkItems.remove(aBookmark); + notifyDataSetChanged(); + } + + public void addItem(String title, String url) { + SessionStore.get().getBookmarkStore().addBookmark(url, title); + Bookmark item = new Bookmark(title, url); + bookmarkItems.add(item); + notifyDataSetChanged(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + BookmarkItemInNewTabBinding binding = DataBindingUtil + .inflate(LayoutInflater.from(parent.getContext()), R.layout.bookmark_item_in_new_tab, + parent, false); + + binding.setCallback(mBookmarkItemCallback); + binding.setIsHovered(false); + + return new BookmarkViewHolder(binding); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + Bookmark item = bookmarkItems.get(position); + + BookmarkViewHolder bookmarkHolder = (BookmarkViewHolder) holder; + BookmarkItemInNewTabBinding binding = bookmarkHolder.binding; + binding.setItem(item); + + SessionStore.get().getBrowserIcons().loadIntoView(binding.favicon, item.getUrl(), IconRequest.Size.DEFAULT); + + binding.layout.setOnHoverListener((view, motionEvent) -> { + int ev = motionEvent.getActionMasked(); + switch (ev) { + case MotionEvent.ACTION_HOVER_ENTER: + binding.setIsHovered(true); + view.getBackground().setState(new int[]{android.R.attr.state_hovered}); + view.postInvalidate(); + return false; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_HOVER_EXIT: + view.getBackground().setState(new int[]{android.R.attr.state_active}); + binding.setIsHovered(false); + view.postInvalidate(); + return false; + } + + return false; + }); + binding.layout.setOnTouchListener((view, motionEvent) -> { + int ev = motionEvent.getActionMasked(); + switch (ev) { + case MotionEvent.ACTION_UP: + return false; + + case MotionEvent.ACTION_DOWN: + binding.trash.setImageState(new int[]{android.R.attr.state_active},false); + binding.setIsHovered(true); + return false; + + case MotionEvent.ACTION_CANCEL: + binding.setIsHovered(false); + return false; + } + return false; + }); + binding.trash.setOnHoverListener(mIconHoverListener); + binding.trash.setOnTouchListener((view, motionEvent) -> { + binding.setIsHovered(true); + int ev = motionEvent.getActionMasked(); + switch (ev) { + case MotionEvent.ACTION_UP: + if (mBookmarkItemCallback != null) { + mBookmarkItemCallback.onDelete(view, binding.getItem()); + } + binding.trash.setImageState(new int[]{android.R.attr.state_active},true); + return true; + + case MotionEvent.ACTION_DOWN: + binding.trash.setImageState(new int[]{android.R.attr.state_pressed},true); + return true; + + case MotionEvent.ACTION_CANCEL: + binding.setIsHovered(false); + binding.trash.setImageState(new int[]{android.R.attr.state_active},true); + return false; + } + return false; + }); + } + + @Override + public int getItemCount() { + return bookmarkItems == null ? 0 : bookmarkItems.size(); + } + + static class BookmarkViewHolder extends RecyclerView.ViewHolder { + + final BookmarkItemInNewTabBinding binding; + + BookmarkViewHolder(@NonNull BookmarkItemInNewTabBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + private View.OnHoverListener mIconHoverListener = (view, motionEvent) -> { + ImageView icon = (ImageView) view; + int ev = motionEvent.getActionMasked(); + switch (ev) { + case MotionEvent.ACTION_HOVER_ENTER: + icon.setImageState(new int[]{android.R.attr.state_hovered}, true); + return false; + + case MotionEvent.ACTION_HOVER_EXIT: + icon.setImageState(new int[]{android.R.attr.state_active}, true); + return false; + } + + return false; + }; +} \ No newline at end of file diff --git a/app/src/common/shared/com/igalia/wolvic/ui/views/NewTabView.java b/app/src/common/shared/com/igalia/wolvic/ui/views/NewTabView.java new file mode 100644 index 0000000000..e85d2dfa4f --- /dev/null +++ b/app/src/common/shared/com/igalia/wolvic/ui/views/NewTabView.java @@ -0,0 +1,162 @@ +package com.igalia.wolvic.ui.views; + +import java.util.List; +import java.util.concurrent.Executor; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.databinding.DataBindingUtil; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.igalia.wolvic.R; +import com.igalia.wolvic.VRBrowserActivity; +import com.igalia.wolvic.VRBrowserApplication; +import com.igalia.wolvic.browser.engine.Session; +import com.igalia.wolvic.browser.engine.SessionStore; +import com.igalia.wolvic.databinding.NewTabBinding; +import com.igalia.wolvic.ui.adapters.Bookmark; +import com.igalia.wolvic.ui.adapters.NewTabAdapter; +import com.igalia.wolvic.ui.callbacks.BookmarkItemCallback; +import com.igalia.wolvic.ui.widgets.WidgetManagerDelegate; +import com.igalia.wolvic.ui.widgets.WindowWidget; + +import mozilla.appservices.places.BookmarkRoot; +import mozilla.components.concept.storage.BookmarkNode; + +public class NewTabView extends FrameLayout { + + private WidgetManagerDelegate mWidgetManager; + + private NewTabBinding mBinding; + + private NewTabAdapter mNewTabAdapter; + + public NewTabView(Context context) { + super(context); + initialize(); + } + + protected void initialize() { + mWidgetManager = ((VRBrowserActivity) getContext()); + updateUI(); + } + + @SuppressLint("ClickableViewAccessibility") + public void updateUI() { + removeAllViews(); + + LayoutInflater inflater = LayoutInflater.from(getContext()); + + mBinding = DataBindingUtil.inflate(inflater, R.layout.new_tab, this, true); + mBinding.setLifecycleOwner((VRBrowserActivity)getContext()); + + mBinding.bookmarkAddView.setVisibility(GONE); + + mNewTabAdapter = new NewTabAdapter(mBookmarkItemCallback); + mBinding.bookmarksList.setAdapter(mNewTabAdapter); + LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false); + mBinding.bookmarksList.setLayoutManager(layoutManager); + mBinding.bookmarksList.setOnTouchListener((v, event) -> { + v.requestFocusFromTouch(); + return false; + }); + mBinding.bookmarksList.setHasFixedSize(true); + mBinding.bookmarksList.setItemViewCacheSize(20); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + mBinding.bookmarksList.setDrawingCacheEnabled(true); + mBinding.bookmarksList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); + } + + mBinding.bookmarkAdd.setOnClickListener(view -> { + mBinding.bookmarkAddButton.requestFocusFromTouch(); + showAddBookmarkView(); + }); + + mBinding.executePendingBindings(); + + updateBookmarks(); + + setOnTouchListener((v, event) -> { + v.requestFocusFromTouch(); + return false; + }); + + } + + private void showAddBookmarkView() { + mBinding.bookmarkAddView.setVisibility(VISIBLE); + mBinding.main.setAlpha(0.5F); + + mBinding.bookmarkAddCancelButton.setOnClickListener(view -> { + mBinding.bookmarkAddView.setVisibility(GONE); + mBinding.main.setAlpha(1F); + }); + + mBinding.bookmarkAddButton.setOnClickListener(view -> { + String title = mBinding.bookmarkTitle.getText().toString(); + String url = mBinding.bookmarkUrl.getText().toString(); + + if (!title.isEmpty() && !url.isEmpty()) { + mNewTabAdapter.addItem(title, url); + } + + mBinding.bookmarkAddView.setVisibility(GONE); + mBinding.main.setAlpha(1F); + }); + } + + private void updateBookmarks() { + Executor executor = ((VRBrowserApplication)getContext().getApplicationContext()).getExecutors().mainThread(); + + SessionStore.get().getBookmarkStore().getTree(BookmarkRoot.Root.getId(), true). + thenAcceptAsync(this::showBookmarks, executor). + exceptionally(throwable -> { + Log.d("NewTab", "Error getting bookmarks: " + throwable.getLocalizedMessage()); + throwable.printStackTrace(); + return null; + }); + } + + private void showBookmarks(List aBookmarks) { + mNewTabAdapter.setBookmarkListInNewTab(aBookmarks); + mBinding.executePendingBindings(); + } + + private final BookmarkItemCallback mBookmarkItemCallback = new BookmarkItemCallback() { + @Override + public void onClick(@NonNull View view, @NonNull Bookmark item) { + mBinding.bookmarksList.requestFocusFromTouch(); + + Session session = SessionStore.get().getActiveSession(); + session.loadUri(item.getUrl()); + + WindowWidget window = mWidgetManager.getFocusedWindow(); + window.hideNewTab(true); + } + + @Override + public void onDelete(@NonNull View view, @NonNull Bookmark item) { + mBinding.bookmarksList.requestFocusFromTouch(); + SessionStore.get().getBookmarkStore().deleteBookmarkById(item.getGuid()); + mNewTabAdapter.removeItem(item); + } + + @Override + public void onMore(@NonNull View view, @NonNull Bookmark item) { + + } + + @Override + public void onFolderOpened(@NonNull Bookmark item) { + + } + }; +} \ No newline at end of file diff --git a/app/src/common/shared/com/igalia/wolvic/ui/views/library/BookmarksView.java b/app/src/common/shared/com/igalia/wolvic/ui/views/library/BookmarksView.java index 55b4f50188..40c5710207 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/views/library/BookmarksView.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/views/library/BookmarksView.java @@ -111,6 +111,7 @@ public void updateUI() { mBinding.setBookmarksViewModel(mViewModel); mBinding.setCallback(mBookmarksCallback); mBookmarkAdapter = new BookmarkAdapter(mBookmarkItemCallback, getContext()); + mBookmarkAdapter = new BookmarkAdapter(mBookmarkItemCallback, getContext()); mBinding.bookmarksList.setAdapter(mBookmarkAdapter); mBinding.bookmarksList.setOnTouchListener((v, event) -> { v.requestFocusFromTouch(); diff --git a/app/src/common/shared/com/igalia/wolvic/ui/widgets/WindowWidget.java b/app/src/common/shared/com/igalia/wolvic/ui/widgets/WindowWidget.java index ba3db0c8cc..626e365ce9 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/widgets/WindowWidget.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/widgets/WindowWidget.java @@ -62,6 +62,7 @@ import com.igalia.wolvic.telemetry.TelemetryService; import com.igalia.wolvic.ui.adapters.WebApp; import com.igalia.wolvic.ui.viewmodel.WindowViewModel; +import com.igalia.wolvic.ui.views.NewTabView; import com.igalia.wolvic.ui.views.library.LibraryPanel; import com.igalia.wolvic.ui.widgets.dialogs.PromptDialogWidget; import com.igalia.wolvic.ui.widgets.dialogs.SelectionActionWidget; @@ -134,6 +135,7 @@ public class WindowWidget extends UIWidget implements SessionChangeListener, private Session mSession; private int mWindowId; private LibraryPanel mLibrary; + private NewTabView mNewTab; private Windows.WindowPlacement mWindowPlacement = Windows.WindowPlacement.FRONT; private Windows.WindowPlacement mWindowPlacementBeforeFullscreen = Windows.WindowPlacement.FRONT; private float mMaxWindowScale = 3; @@ -217,6 +219,7 @@ private void initialize(Context aContext) { setupListeners(mSession); mLibrary = new LibraryPanel(aContext); + mNewTab = new NewTabView(aContext); SessionStore.get().getBookmarkStore().addListener(mBookmarksListener); @@ -523,6 +526,22 @@ public void showPanel(@Windows.PanelType int panelType) { showPanel(panelType, true); } + public void showNewTab() { + if (mNewTab != null) { + setView(mNewTab, true); + mViewModel.setIsFindInPage(false); + final Runnable firstDrawCallback = mFirstDrawCallback; + onFirstContentfulPaint(mSession.getWSession()); + mRestoreFirstPaint = () -> { + setFirstPaintReady(false); + setFirstDrawCallback(firstDrawCallback); + if (mWidgetManager != null) { + mWidgetManager.updateWidget(WindowWidget.this); + } + }; + } + } + private void showPanel(@Windows.PanelType int panelType, boolean switchSurface) { if (mLibrary != null) { if (mView == null) { @@ -542,7 +561,6 @@ private void showPanel(@Windows.PanelType int panelType, boolean switchSurface) } }; } - } else if (mView == mLibrary) { mLibrary.selectPanel(panelType); } @@ -565,6 +583,16 @@ private void hidePanel(boolean switchSurface) { } } + public void hideNewTab(boolean switchSurface) { + if (mView != null && mNewTab != null) { + unsetView(mNewTab, switchSurface); + } + if (switchSurface && mRestoreFirstPaint != null) { + mRestoreFirstPaint.run(); + mRestoreFirstPaint = null; + } + } + public void pauseCompositor() { if (mSession == null) { return; @@ -2002,23 +2030,33 @@ WResult onLoadRequest(WSession aSession, @NonNull LoadRequest aReq Uri uri = Uri.parse(aRequest.uri); if (UrlUtils.isAboutPage(uri.toString())) { - if(UrlUtils.isBookmarksUrl(uri.toString())) { - showPanel(Windows.BOOKMARKS); + if(UrlUtils.isBookmarksUrl(uri.toString())) { + hideNewTab(true); + showPanel(Windows.BOOKMARKS); } else if (UrlUtils.isHistoryUrl(uri.toString())) { - showPanel(Windows.HISTORY); + hideNewTab(true); + showPanel(Windows.HISTORY); } else if (UrlUtils.isDownloadsUrl(uri.toString())) { - showPanel(Windows.DOWNLOADS); + hideNewTab(true); + showPanel(Windows.DOWNLOADS); } else if (UrlUtils.isAddonsUrl(uri.toString())) { - showPanel(Windows.ADDONS); + hideNewTab(true); + showPanel(Windows.ADDONS); + + } else if (UrlUtils.isNewTabUrl(uri.toString())) { + showNewTab(); } else { - hideLibraryPanel(); - } + hideNewTab(true); + hideLibraryPanel(); + + } } else { + hideNewTab(true); hideLibraryPanel(); } diff --git a/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/DisplayOptionsView.java b/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/DisplayOptionsView.java index ddcf3c920b..66f1a1e410 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/DisplayOptionsView.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/DisplayOptionsView.java @@ -72,6 +72,10 @@ protected void updateUI() { mBinding.msaaRadio.setOnCheckedChangeListener(mMSSAChangeListener); setMSAAMode(mBinding.msaaRadio.getIdForValue(msaaLevel), false); + int homepageId = getHomepageId(SettingsStore.getInstance(getContext()).getHomepage()); + mBinding.homepage.setOnCheckedChangeListener(mHomepageChangeListener); + setHomepage(homepageId, false); + mBinding.autoplaySwitch.setOnCheckedChangeListener(mAutoplayListener); setAutoplay(SettingsStore.getInstance(getContext()).isAutoplayEnabled(), false); @@ -165,6 +169,10 @@ public boolean isEditing() { setMSAAMode(checkedId, true); }; + private RadioGroupSetting.OnCheckedChangeListener mHomepageChangeListener = (radioGroup, checkedId, doApply) -> { + setHomepage(checkedId, true); + }; + private SwitchSetting.OnCheckedChangeListener mAutoplayListener = (compoundButton, enabled, apply) -> { setAutoplay(enabled, true); }; @@ -249,6 +257,11 @@ public boolean isEditing() { restart = true; } + int defaultHomepageId = getHomepageId(mDefaultHomepageUrl); + if (mBinding.homepage.getCheckedRadioButtonId() != defaultHomepageId) { + setHomepage(defaultHomepageId, true); + } + float prevDensity = SettingsStore.getInstance(getContext()).getDisplayDensity(); restart = restart | setDisplayDensity(SettingsStore.DISPLAY_DENSITY_DEFAULT); int prevDpi = SettingsStore.getInstance(getContext()).getDisplayDpi(); @@ -374,11 +387,39 @@ private void setWindowMovement(boolean value, boolean doApply) { } } + private void setHomepage(int checkedId, boolean doApply) { + mBinding.homepage.setOnCheckedChangeListener(null); + mBinding.homepage.setChecked(checkedId, doApply); + mBinding.homepage.setOnCheckedChangeListener(mHomepageChangeListener); + + if (checkedId == 0) { + mBinding.homepageEdit.setVisibility(View.GONE); + SettingsStore.getInstance(getContext()).setHomepage(mDefaultHomepageUrl); + } else if (checkedId == 1) { + mBinding.homepageEdit.setVisibility(View.GONE); + SettingsStore.getInstance(getContext()).setHomepage("about://newtab"); + } else if (checkedId == 2) { + mBinding.homepageEdit.setVisibility(View.VISIBLE); + } + } + + private int getHomepageId(String homepage) { + if (homepage == getContext().getString(R.string.HOMEPAGE_URL)) { + return 0; + } else if (homepage == "about://newtab") { + return 1; + } else { + return 2; + } + } + private void setHomepage(String newHomepage) { - mBinding.homepageEdit.setOnClickListener(null); - mBinding.homepageEdit.setFirstText(newHomepage); - SettingsStore.getInstance(getContext()).setHomepage(newHomepage); - mBinding.homepageEdit.setOnClickListener(mHomepageListener); + if (mBinding.homepageEdit.getVisibility() == VISIBLE) { + mBinding.homepageEdit.setOnClickListener(null); + mBinding.homepageEdit.setFirstText(newHomepage); + SettingsStore.getInstance(getContext()).setHomepage(newHomepage); + mBinding.homepageEdit.setOnClickListener(mHomepageListener); + } } private void setWindowDistance(float value, boolean doApply) { diff --git a/app/src/common/shared/com/igalia/wolvic/utils/UrlUtils.java b/app/src/common/shared/com/igalia/wolvic/utils/UrlUtils.java index 00567d996c..072051315d 100644 --- a/app/src/common/shared/com/igalia/wolvic/utils/UrlUtils.java +++ b/app/src/common/shared/com/igalia/wolvic/utils/UrlUtils.java @@ -188,6 +188,12 @@ public static boolean isBookmarksUrl(@Nullable String url) { return url != null && url.equalsIgnoreCase(ABOUT_BOOKMARKS); } + public static final String ABOUT_NEWTAB = "about://newtab"; + + public static boolean isNewTabUrl(@Nullable String url) { + return url != null && url.equalsIgnoreCase(ABOUT_NEWTAB); + } + public static final String ABOUT_DOWNLOADS = "about://downloads"; public static boolean isDownloadsUrl(@Nullable String url) { @@ -225,7 +231,7 @@ public static boolean isPrivateUrl(@Nullable String url) { } public static boolean isAboutPage(@Nullable String url) { - return isHistoryUrl(url) || isBookmarksUrl(url) || isDownloadsUrl(url) || isAddonsUrl(url) || isPrivateUrl(url); + return isHistoryUrl(url) || isBookmarksUrl(url) || isDownloadsUrl(url) || isAddonsUrl(url) || isPrivateUrl(url) || isNewTabUrl(url); } public static boolean isContentFeed(Context aContext, @Nullable String url) { diff --git a/app/src/main/res/layout/bookmark_item_in_new_tab.xml b/app/src/main/res/layout/bookmark_item_in_new_tab.xml new file mode 100644 index 0000000000..4b424bff61 --- /dev/null +++ b/app/src/main/res/layout/bookmark_item_in_new_tab.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/new_tab.xml b/app/src/main/res/layout/new_tab.xml new file mode 100644 index 0000000000..cddca6cc34 --- /dev/null +++ b/app/src/main/res/layout/new_tab.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/options_display.xml b/app/src/main/res/layout/options_display.xml index d6e8de6dbd..974712b0c9 100644 --- a/app/src/main/res/layout/options_display.xml +++ b/app/src/main/res/layout/options_display.xml @@ -90,15 +90,22 @@ app:options="@array/developer_options_msaa" app:values="@array/developer_options_msaa_mode_values" /> + + + app:highlightedTextColor="@color/fog" + android:visibility="gone" /> 2 + + + @string/developer_options_homepage_wolvic + @string/developer_options_homepage_new_tab + @string/developer_options_homepage_other + + @string/privacy_options_tracking_etp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f7d2fbdfe1..7790fa1027 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -607,6 +607,15 @@ 4x + + Wolvic + + + New Tab + + + Other + User-Agent Mode