Răsfoiți Sursa

Introduce SearchBar/Toolbar dark/light design

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Andy Scherzinger 4 ani în urmă
părinte
comite
a125185915
32 a modificat fișierele cu 739 adăugiri și 108 ștergeri
  1. 1 0
      CHANGELOG.md
  2. 17 1
      app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt
  3. 137 51
      app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java
  4. 16 1
      app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java
  5. 1 0
      app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java
  6. 95 4
      app/src/main/java/com/nextcloud/talk/controllers/base/BaseController.java
  7. 51 1
      app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java
  8. 11 0
      app/src/main/res/animator/appbar_elevation_off.xml
  9. 11 0
      app/src/main/res/animator/appbar_elevation_on.xml
  10. 23 0
      app/src/main/res/drawable-night/ic_close_search.xml
  11. 23 0
      app/src/main/res/drawable/ic_close_search.xml
  12. 9 0
      app/src/main/res/drawable/ic_menu.xml
  13. 23 0
      app/src/main/res/drawable/ic_search_grey.xml
  14. 46 13
      app/src/main/res/layout/activity_main.xml
  15. 2 1
      app/src/main/res/layout/controller_account_verification.xml
  16. 4 0
      app/src/main/res/layout/controller_browser.xml
  17. 1 0
      app/src/main/res/layout/controller_call.xml
  18. 1 1
      app/src/main/res/layout/controller_call_menu.xml
  19. 2 1
      app/src/main/res/layout/controller_chat.xml
  20. 1 1
      app/src/main/res/layout/controller_entry_menu.xml
  21. 9 6
      app/src/main/res/layout/controller_generic_rv.xml
  22. 1 1
      app/src/main/res/layout/controller_locked.xml
  23. 3 3
      app/src/main/res/layout/controller_operations_menu.xml
  24. 2 2
      app/src/main/res/layout/rv_item_app.xml
  25. 1 1
      app/src/main/res/layout/rv_item_browser_file.xml
  26. 120 0
      app/src/main/res/layout/search_layout.xml
  27. 1 8
      app/src/main/res/menu/menu_conversation_plus_filter.xml
  28. 18 0
      app/src/main/res/values-night/colors.xml
  29. 15 0
      app/src/main/res/values/colors.xml
  30. 2 0
      app/src/main/res/values/dimens.xml
  31. 4 1
      app/src/main/res/values/strings.xml
  32. 88 11
      app/src/main/res/values/styles.xml

+ 1 - 0
CHANGELOG.md

@@ -10,6 +10,7 @@ Types of changes can be: Added/Changed/Deprecated/Removed/Fixed/Security
 
 ### Changed
 - improve conversation list design and dark/light theming (@AndyScherzinger)
+- introduce new dark/light toolbar/searchbar design (@AndyScherzinger)
 
 ### Fixed
 - @ in username is allowed for phonebook sync

+ 17 - 1
app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt

@@ -38,12 +38,20 @@ import com.bluelinelabs.conductor.Router
 import com.bluelinelabs.conductor.RouterTransaction
 import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
 import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
+import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.appbar.MaterialToolbar
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.card.MaterialCardView
 import com.google.android.material.snackbar.Snackbar
+import com.google.android.material.textview.MaterialTextView
 import com.nextcloud.talk.R
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
-import com.nextcloud.talk.controllers.*
+import com.nextcloud.talk.controllers.CallNotificationController
+import com.nextcloud.talk.controllers.ConversationsListController
+import com.nextcloud.talk.controllers.LockedController
+import com.nextcloud.talk.controllers.ServerSelectionController
+import com.nextcloud.talk.controllers.WebViewLoginController
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
 import com.nextcloud.talk.models.json.conversations.RoomOverall
 import com.nextcloud.talk.utils.ApiUtils
@@ -69,8 +77,16 @@ import javax.inject.Inject
 @AutoInjector(NextcloudTalkApplication::class)
 class MainActivity : BaseActivity(), ActionBarProvider {
 
+    @BindView(R.id.appBar)
+    lateinit var appBar: AppBarLayout
     @BindView(R.id.toolbar)
     lateinit var toolbar: MaterialToolbar
+    @BindView(R.id.home_toolbar)
+    lateinit var searchCardView: MaterialCardView
+    @BindView(R.id.search_text)
+    lateinit var searchInputText: MaterialTextView
+    @BindView(R.id.switch_account_button)
+    lateinit var settingsButton: MaterialButton
     @BindView(R.id.controller_container)
     lateinit var container: ViewGroup
 

+ 137 - 51
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java

@@ -2,7 +2,9 @@
  * Nextcloud Talk application
  *
  * @author Mario Danic
- * Copyright (C) 2017 Mario Danic (mario@lovelyhq.com)
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de)
+ * Copyright (C) 2017-2020 Mario Danic (mario@lovelyhq.com)
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +22,7 @@
 
 package com.nextcloud.talk.controllers;
 
+import android.animation.AnimatorInflater;
 import android.app.SearchManager;
 import android.content.Context;
 import android.content.Intent;
@@ -27,8 +30,10 @@ import android.graphics.Bitmap;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.text.Editable;
 import android.text.InputType;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -39,6 +44,19 @@ import android.view.inputmethod.EditorInfo;
 import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.SearchView;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+import androidx.core.view.MenuItemCompat;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
+
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
 import com.bluelinelabs.conductor.changehandler.TransitionChangeHandlerCompat;
@@ -52,10 +70,12 @@ import com.facebook.imagepipeline.core.ImagePipeline;
 import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
 import com.facebook.imagepipeline.image.CloseableImage;
 import com.facebook.imagepipeline.request.ImageRequest;
+import com.google.android.material.button.MaterialButton;
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.kennyc.bottomsheet.BottomSheet;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.activities.MagicCallActivity;
+import com.nextcloud.talk.activities.MainActivity;
 import com.nextcloud.talk.adapters.items.CallItem;
 import com.nextcloud.talk.adapters.items.ConversationItem;
 import com.nextcloud.talk.api.NcApi;
@@ -95,17 +115,6 @@ import java.util.List;
 
 import javax.inject.Inject;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.SearchView;
-import androidx.core.graphics.drawable.RoundedBitmapDrawable;
-import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
-import androidx.core.view.MenuItemCompat;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import androidx.work.Data;
-import androidx.work.OneTimeWorkRequest;
-import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import butterknife.BindView;
 import eu.davidea.fastscroller.FastScroller;
@@ -214,9 +223,16 @@ public class ConversationsListController extends BaseController implements Searc
         prepareViews();
     }
 
-    private void loadUserAvatar(MenuItem menuItem) {
+    private void loadUserAvatar(MaterialButton button) {
         if (getActivity() != null) {
-            int avatarSize = (int) DisplayUtils.convertDpToPixel(menuItem.getIcon().getIntrinsicHeight(), getActivity());
+            int avatarSize;
+
+            if (getResources() != null) {
+                avatarSize = getResources().getDimensionPixelSize(R.dimen.avatar_size_app_bar);
+            } else {
+                avatarSize = (int) DisplayUtils.convertDpToPixel(30.0f, context);
+            }
+
             ImageRequest imageRequest = DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithNameAndPixels(currentUser.getBaseUrl(),
                     currentUser.getUserId(), avatarSize), currentUser);
 
@@ -229,13 +245,15 @@ public class ConversationsListController extends BaseController implements Searc
                         RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
                         roundedBitmapDrawable.setCircular(true);
                         roundedBitmapDrawable.setAntiAlias(true);
-                        menuItem.setIcon(roundedBitmapDrawable);
+                        button.setIcon(roundedBitmapDrawable);
                     }
                 }
 
                 @Override
                 protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
-                    menuItem.setIcon(R.drawable.ic_settings_white_24dp);
+                    if (getResources() != null) {
+                        button.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_settings_white_24dp, null));
+                    }
                 }
             }, UiThreadImmediateExecutorService.getInstance());
         }
@@ -251,6 +269,9 @@ public class ConversationsListController extends BaseController implements Searc
         if (currentUser != null) {
             credentials = ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken());
             shouldUseLastMessageLayout = currentUser.hasSpreedFeatureCapability("last-room-activity");
+            if (getActivity() != null && getActivity() instanceof MainActivity) {
+                loadUserAvatar(((MainActivity) getActivity()).settingsButton);
+            }
             fetchData(false);
         }
     }
@@ -266,6 +287,7 @@ public class ConversationsListController extends BaseController implements Searc
             SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
             if (searchItem != null) {
                 searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
+                DisplayUtils.themeSearchView(searchView, context);
                 searchView.setMaxWidth(Integer.MAX_VALUE);
                 searchView.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER);
                 int imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_FULLSCREEN;
@@ -273,7 +295,7 @@ public class ConversationsListController extends BaseController implements Searc
                     imeOptions |= EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING;
                 }
                 searchView.setImeOptions(imeOptions);
-                searchView.setQueryHint(getResources().getString(R.string.nc_search));
+                searchView.setQueryHint(getSearchHint());
                 if (searchManager != null) {
                     searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
                 }
@@ -283,22 +305,7 @@ public class ConversationsListController extends BaseController implements Searc
     }
 
     @Override
-    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.action_settings:
-                ArrayList<String> names = new ArrayList<>();
-                names.add("userAvatar.transitionTag");
-                getRouter().pushController((RouterTransaction.with(new SettingsController())
-                        .pushChangeHandler(new TransitionChangeHandlerCompat(new SharedElementTransition(names), new VerticalChangeHandler()))
-                        .popChangeHandler(new TransitionChangeHandlerCompat(new SharedElementTransition(names), new VerticalChangeHandler()))));
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
         inflater.inflate(R.menu.menu_conversation_plus_filter, menu);
         searchItem = menu.findItem(R.id.action_search);
@@ -306,16 +313,87 @@ public class ConversationsListController extends BaseController implements Searc
     }
 
     @Override
-    public void onPrepareOptionsMenu(Menu menu) {
+    public void onPrepareOptionsMenu(@NonNull Menu menu) {
         super.onPrepareOptionsMenu(menu);
+
+        searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
+
+        MainActivity activity = (MainActivity) getActivity();
+
         searchItem.setVisible(callItems.size() > 0);
         if (adapter.hasFilter()) {
-            searchItem.expandActionView();
+            showSearchView(activity, searchView, searchItem);
             searchView.setQuery(adapter.getFilter(String.class), false);
         }
 
-        MenuItem menuItem = menu.findItem(R.id.action_settings);
-        loadUserAvatar(menuItem);
+        if (activity != null) {
+            activity.getSearchInputText().setOnClickListener(v -> {
+                showSearchView(activity, searchView, searchItem);
+                if (getResources() != null) {
+                    DisplayUtils.applyColorToStatusBar(
+                            activity,
+                            ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
+                    );
+                }
+            });
+        }
+
+        searchView.setOnCloseListener(() -> {
+            if (TextUtils.isEmpty(searchView.getQuery().toString())) {
+                searchView.onActionViewCollapsed();
+                if (activity != null && getResources() != null) {
+                    DisplayUtils.applyColorToStatusBar(
+                            activity,
+                            ResourcesCompat.getColor(getResources(), R.color.appbar, null)
+                    );
+                }
+            } else {
+                searchView.post(() -> searchView.setQuery("", true));
+            }
+            return true;
+        });
+
+        searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
+            @Override
+            public boolean onMenuItemActionExpand(MenuItem item) {
+                return true;
+            }
+
+            @Override
+            public boolean onMenuItemActionCollapse(MenuItem item) {
+                searchView.onActionViewCollapsed();
+                MainActivity activity = (MainActivity) getActivity();
+                if (activity != null) {
+                    activity.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
+                            activity.appBar.getContext(),
+                            R.animator.appbar_elevation_off)
+                    );
+                    activity.toolbar.setVisibility(View.GONE);
+                    activity.searchCardView.setVisibility(View.VISIBLE);
+                }
+                SmoothScrollLinearLayoutManager layoutManager =
+                        (SmoothScrollLinearLayoutManager) recyclerView.getLayoutManager();
+                if (layoutManager!=null) {
+                    layoutManager.scrollToPositionWithOffset(0, 0);
+                }
+                return true;
+            }
+        });
+    }
+
+    protected void showSearchOrToolbar() {
+        if (TextUtils.isEmpty(searchQuery)) {
+            super.showSearchOrToolbar();
+        }
+    }
+
+    public void showSearchView(MainActivity activity, SearchView searchView, MenuItem searchItem) {
+        activity.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
+                activity.appBar.getContext(),
+                R.animator.appbar_elevation_on));
+        activity.toolbar.setVisibility(View.VISIBLE);
+        activity.searchCardView.setVisibility(View.GONE);
+        searchItem.expandActionView();
     }
 
     private void fetchData(boolean fromBottomSheet) {
@@ -385,19 +463,11 @@ public class ConversationsListController extends BaseController implements Searc
 
                     adapter.updateDataSet(callItems, false);
 
-                    if (searchItem != null) {
-                        searchItem.setVisible(callItems.size() > 0);
-                    }
-
                     if (swipeRefreshLayout != null) {
                         swipeRefreshLayout.setRefreshing(false);
                     }
 
                 }, throwable -> {
-                    if (searchItem != null) {
-                        searchItem.setVisible(false);
-                    }
-
                     if (throwable instanceof HttpException) {
                         HttpException exception = (HttpException) throwable;
                         switch (exception.code()) {
@@ -436,7 +506,6 @@ public class ConversationsListController extends BaseController implements Searc
 
                     isRefreshing = false;
                 });
-
     }
 
     private void prepareViews() {
@@ -472,6 +541,20 @@ public class ConversationsListController extends BaseController implements Searc
             }
             return displayName;
         });
+
+        if (getActivity() != null && getActivity() instanceof MainActivity) {
+            MainActivity activity = (MainActivity) getActivity();
+
+            if (activity.settingsButton != null) {
+                activity.settingsButton.setOnClickListener(v -> {
+                    ArrayList<String> names = new ArrayList<>();
+                    names.add("userAvatar.transitionTag");
+                    getRouter().pushController((RouterTransaction.with(new SettingsController())
+                            .pushChangeHandler(new TransitionChangeHandlerCompat(new SharedElementTransition(names), new VerticalChangeHandler()))
+                            .popChangeHandler(new TransitionChangeHandlerCompat(new SharedElementTransition(names), new VerticalChangeHandler()))));
+                });
+            }
+        }
     }
 
     private void showNewConversationsScreen() {
@@ -490,7 +573,6 @@ public class ConversationsListController extends BaseController implements Searc
                 roomsQueryDisposable != null && !roomsQueryDisposable.isDisposed()) {
             roomsQueryDisposable.dispose();
             roomsQueryDisposable = null;
-
         }
     }
 
@@ -508,7 +590,9 @@ public class ConversationsListController extends BaseController implements Searc
     @Override
     public void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) {
         super.onRestoreViewState(view, savedViewState);
-        searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, "");
+        if (savedViewState.containsKey(KEY_SEARCH_QUERY)) {
+            searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, "");
+        }
         if (LovelySaveStateHandler.wasDialogOnScreen(savedViewState)) {
             //Dialog won't be restarted automatically, so we need to call this method.
             //Each dialog knows how to restore its state
@@ -525,7 +609,6 @@ public class ConversationsListController extends BaseController implements Searc
     @Override
     public boolean onQueryTextChange(String newText) {
         if (adapter.hasNewFilter(newText) || !TextUtils.isEmpty(searchQuery)) {
-
             if (!TextUtils.isEmpty(searchQuery)) {
                 adapter.setFilter(searchQuery);
                 searchQuery = "";
@@ -602,7 +685,6 @@ public class ConversationsListController extends BaseController implements Searc
         bottomSheet.show();
     }
 
-
     @Override
     protected String getTitle() {
         return getResources().getString(R.string.nc_app_name);
@@ -624,7 +706,6 @@ public class ConversationsListController extends BaseController implements Searc
                 conversation = ((CallItem) clickedItem).getModel();
             }
 
-
             Bundle bundle = new Bundle();
             bundle.putParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY(), currentUser);
             bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), conversation.getToken());
@@ -753,4 +834,9 @@ public class ConversationsListController extends BaseController implements Searc
         }
 
     }
+
+    @Override
+    public AppBarLayoutType getAppBarLayoutType() {
+        return AppBarLayoutType.SEARCH_BAR;
+    }
 }

+ 16 - 1
app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java

@@ -1,6 +1,7 @@
 /*
  * Nextcloud Talk application
  *
+ * @author Andy Scherzinger
  * @author Mario Danic
  * Copyright (C) 2017 Mario Danic (mario@lovelyhq.com)
  *
@@ -44,6 +45,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.controllers.base.BaseController;
 import com.nextcloud.talk.utils.AccountUtils;
 import com.nextcloud.talk.utils.ApiUtils;
+import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.user.UserUtils;
 import com.nextcloud.talk.utils.preferences.AppPreferences;
@@ -54,6 +56,10 @@ import java.security.cert.CertificateException;
 import javax.inject.Inject;
 
 import androidx.annotation.NonNull;
+import androidx.core.content.res.ResourcesCompat;
+
+import org.jetbrains.annotations.NotNull;
+
 import autodagger.AutoInjector;
 import butterknife.BindView;
 import butterknife.OnClick;
@@ -90,6 +96,7 @@ public class ServerSelectionController extends BaseController {
 
     private Disposable statusQueryDisposable;
 
+    @NotNull
     @Override
     protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
         return inflater.inflate(R.layout.controller_server_selection, container, false);
@@ -354,6 +361,11 @@ public class ServerSelectionController extends BaseController {
             ApplicationWideMessageHolder.getInstance().setMessageType(null);
         }
 
+        if (getActivity() != null && getResources() != null) {
+            DisplayUtils.applyColorToStatusBar(getActivity(), ResourcesCompat.getColor(getResources(), R.color.colorPrimary, null));
+            DisplayUtils.applyColorToNavigationBar(getActivity().getWindow(), ResourcesCompat.getColor(getResources(), R.color.colorPrimary, null));
+        }
+
         setCertTextView();
     }
 
@@ -394,5 +406,8 @@ public class ServerSelectionController extends BaseController {
         statusQueryDisposable = null;
     }
 
-
+    @Override
+    public AppBarLayoutType getAppBarLayoutType() {
+        return AppBarLayoutType.EMPTY;
+    }
 }

+ 1 - 0
app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java

@@ -1,6 +1,7 @@
 /*
  * Nextcloud Talk application
  *
+ * @author Andy Scherzinger
  * @author Mario Danic
  * Copyright (C) 2017 Mario Danic (mario@lovelyhq.com)
  *

+ 95 - 4
app/src/main/java/com/nextcloud/talk/controllers/base/BaseController.java

@@ -1,7 +1,11 @@
-/**
+/*
  * Nextcloud Talk application
  *
+ * @author Andy Scherzinger
  * @author BlueLine Labs, Inc.
+ * @author Mario Danic
+ * Copyright (C) 2021 Andy Scherzinger (info@andy-scherzinger.de)
+ * Copyright (C) 2020 Mario Danic (mario@lovelyhq.com)
  * Copyright (C) 2016 BlueLine Labs, Inc.
  * <p>
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +22,7 @@
  */
 package com.nextcloud.talk.controllers.base;
 
+import android.animation.AnimatorInflater;
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
@@ -28,25 +33,39 @@ import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.appcompat.app.ActionBar;
-import autodagger.AutoInjector;
+import androidx.core.content.res.ResourcesCompat;
+
 import com.bluelinelabs.conductor.Controller;
+import com.google.android.material.appbar.AppBarLayout;
+import com.nextcloud.talk.R;
+import com.nextcloud.talk.activities.MainActivity;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.controllers.AccountVerificationController;
 import com.nextcloud.talk.controllers.ServerSelectionController;
 import com.nextcloud.talk.controllers.SwitchAccountController;
 import com.nextcloud.talk.controllers.WebViewLoginController;
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider;
+import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.preferences.AppPreferences;
 
-import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
+import autodagger.AutoInjector;
+
 @AutoInjector(NextcloudTalkApplication.class)
 public abstract class BaseController extends ButterKnifeController {
+    public enum AppBarLayoutType {
+        TOOLBAR,
+        SEARCH_BAR,
+        EMPTY
+    }
 
     private static final String TAG = "BaseController";
     @Inject
@@ -95,6 +114,11 @@ public abstract class BaseController extends ButterKnifeController {
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.getIsKeyboardIncognito()) {
             disableKeyboardPersonalisedLearning((ViewGroup) view);
+
+            if (getActivity() != null && getActivity() instanceof MainActivity) {
+                MainActivity activity = (MainActivity) getActivity();
+                disableKeyboardPersonalisedLearning(activity.appBar);
+            }
         }
     }
 
@@ -112,12 +136,71 @@ public abstract class BaseController extends ButterKnifeController {
 
     @Override
     protected void onAttach(@NonNull View view) {
-        super.onAttach(view);
+        showSearchOrToolbar();
 
         setTitle();
         if (getActionBar() != null) {
             getActionBar().setDisplayHomeAsUpEnabled(getParentController() != null || getRouter().getBackstackSize() > 1);
         }
+
+        super.onAttach(view);
+    }
+
+    protected void showSearchOrToolbar() {
+        if (getActivity() != null && getActivity() instanceof MainActivity) {
+            boolean showSearchBar = getAppBarLayoutType() == AppBarLayoutType.SEARCH_BAR;
+            MainActivity activity = (MainActivity) getActivity();
+
+            if (getAppBarLayoutType() == AppBarLayoutType.EMPTY) {
+                activity.toolbar.setVisibility(View.GONE);
+                activity.getSearchCardView().setVisibility(View.GONE);
+            } else {
+                AppBarLayout.LayoutParams layoutParams = (AppBarLayout.LayoutParams) activity.searchCardView.getLayoutParams();
+
+                if (showSearchBar) {
+                    activity.getSearchCardView().setVisibility(View.VISIBLE);
+                    activity.getSearchInputText().setHint(getSearchHint());
+                    activity.toolbar.setVisibility(View.GONE);
+                    //layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
+                    layoutParams.setScrollFlags(0);
+                    activity.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
+                            activity.appBar.getContext(),
+                            R.animator.appbar_elevation_off)
+                    );
+                } else {
+                    activity.getSearchCardView().setVisibility(View.GONE);
+                    activity.toolbar.setVisibility(View.VISIBLE);
+                    layoutParams.setScrollFlags(0);
+                    activity.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
+                            activity.appBar.getContext(),
+                            R.animator.appbar_elevation_on)
+                    );
+                }
+
+                activity.searchCardView.setLayoutParams(layoutParams);
+
+                if ((getResources() != null)) {
+                    if (showSearchBar) {
+                        DisplayUtils.applyColorToStatusBar(
+                                activity, ResourcesCompat.getColor(getResources(),
+                                        R.color.bg_default, null)
+                        );
+                    } else {
+                        DisplayUtils.applyColorToStatusBar(
+                                activity, ResourcesCompat.getColor(getResources(),
+                                        R.color.appbar, null)
+                        );
+                    }
+                }
+            }
+
+            if ((getResources() != null)) {
+                DisplayUtils.applyColorToNavigationBar(
+                        activity.getWindow(),
+                        ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
+                );
+            }
+        }
     }
 
     @Override
@@ -164,4 +247,12 @@ public abstract class BaseController extends ButterKnifeController {
             }
         }
     }
+
+    public AppBarLayoutType getAppBarLayoutType() {
+        return AppBarLayoutType.TOOLBAR;
+    }
+
+    public String getSearchHint() {
+        return context.getString(R.string.appbar_search_in, context.getString(R.string.nc_app_name));
+    }
 }

+ 51 - 1
app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.java

@@ -2,7 +2,7 @@
  * Nextcloud Talk application
  *
  * @author Mario Danic
- * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
+ * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 package com.nextcloud.talk.utils;
 
 import android.annotation.SuppressLint;
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.ColorStateList;
@@ -49,7 +50,10 @@ import android.util.Log;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.EditText;
+import android.widget.ImageView;
 import android.widget.TextView;
 
 import androidx.annotation.ColorInt;
@@ -58,10 +62,14 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.XmlRes;
+import androidx.appcompat.app.AppCompatDelegate;
 import androidx.appcompat.widget.AppCompatDrawableManager;
+import androidx.appcompat.widget.SearchView;
 import androidx.core.content.ContextCompat;
+import androidx.core.content.res.ResourcesCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.emoji.text.EmojiCompat;
+import androidx.viewpager.widget.ViewPager;
 
 import com.facebook.common.executors.UiThreadImmediateExecutorService;
 import com.facebook.common.references.CloseableReference;
@@ -395,6 +403,48 @@ public class DisplayUtils {
         return drawable;
     }
 
+    public static void applyColorToNavigationBar(Window window, @ColorInt int color) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                View decor = window.getDecorView();
+                if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_NO) {
+                    int systemUiFlags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        systemUiFlags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
+                        WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+                    }
+                    decor.setSystemUiVisibility(systemUiFlags);
+                } else {
+                    decor.setSystemUiVisibility(0);
+                }
+                window.setNavigationBarColor(color);
+            }
+        }
+    }
+
+    public static void applyColorToStatusBar(Activity activity, @ColorInt int color) {
+        Window window = activity.getWindow();
+        if (window != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            window.setStatusBarColor(color);
+        }
+    }
+
+    /**
+     * Theme search view
+     *
+     * @param searchView searchView to be changed
+     * @param context    the app's context
+     */
+    public static void themeSearchView(SearchView searchView, Context context) {
+        // hacky as no default way is provided
+        int fontColor = context.getResources().getColor(R.color.fontAppbar);
+        SearchView.SearchAutoComplete editText = searchView.findViewById(R.id.search_src_text);
+        editText.setTextSize(16);
+        editText.setHintTextColor(context.getResources().getColor(R.color.fontSecondaryAppbar));
+    }
+
     public static boolean isDarkModeActive(Context context, AppPreferences prefs) {
         if (prefs.getTheme().equals("night_yes")) {
             return true;

+ 11 - 0
app/src/main/res/animator/appbar_elevation_off.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="PrivateResource">
+    <item>
+        <objectAnimator
+            android:propertyName="elevation"
+            android:valueTo="0dp"
+            android:valueType="floatType" />
+    </item>
+</selector>

+ 11 - 0
app/src/main/res/animator/appbar_elevation_on.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="PrivateResource">
+    <item>
+        <objectAnimator
+            android:propertyName="elevation"
+            android:valueTo="@dimen/design_appbar_elevation"
+            android:valueType="floatType" />
+    </item>
+</selector>

+ 23 - 0
app/src/main/res/drawable-night/ic_close_search.xml

@@ -0,0 +1,23 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2018 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#FFFFFF" android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
+</vector>

+ 23 - 0
app/src/main/res/drawable/ic_close_search.xml

@@ -0,0 +1,23 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2018 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#666666" android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
+</vector>

+ 9 - 0
app/src/main/res/drawable/ic_menu.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
+</vector>

+ 23 - 0
app/src/main/res/drawable/ic_search_grey.xml

@@ -0,0 +1,23 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2018 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#757575" android:pathData="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
+</vector>

+ 46 - 13
app/src/main/res/layout/activity_main.xml

@@ -2,7 +2,9 @@
   ~ Nextcloud Talk application
   ~
   ~ @author Mario Danic
-  ~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
+  ~ Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
   ~
   ~ This program is free software: you can redistribute it and/or modify
   ~ it under the terms of the GNU General Public License as published by
@@ -21,28 +23,59 @@
 <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/mainActivityCoordinatorLayout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:animateLayoutChanges="true"
     tools:context=".activities.MainActivity">
 
-    <com.bluelinelabs.conductor.ChangeHandlerFrameLayout
-        android:id="@+id/controller_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
-
     <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/appBar"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        android:background="@color/bg_default"
+        android:elevation="0dp"
+        android:clipChildren="true"
+        android:clipToPadding="false"
+        android:windowContentOverlay="@null"
+        app:elevation="0dp">
+
+        <include
+            layout="@layout/search_layout"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
         <com.google.android.material.appbar.MaterialToolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
-            android:layout_height="?android:attr/actionBarSize"
-            android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
-            app:contentInsetStart="24dp"
-            app:contentInsetStartWithNavigation="0dp"
-            app:popupTheme="@style/appActionBarPopupMenu" />
+            android:layout_height="?attr/actionBarSize"
+            android:background="@color/appbar"
+            android:theme="?attr/actionBarPopupTheme"
+            app:contentInsetStartWithNavigation="16dp"
+            app:layout_scrollFlags="enterAlwaysCollapsed|noScroll"
+            app:navigationIconTint="@color/fontAppbar"
+            app:popupTheme="@style/appActionBarPopupMenu"
+            app:titleTextColor="@color/fontAppbar"
+            tools:title="@string/nc_app_name">
+
+            <ProgressBar
+                android:id="@+id/toolbarProgressBar"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:layout_gravity="center_vertical|end"
+                android:layout_marginEnd="8dp"
+                android:visibility="gone"
+                android:indeterminateTint="@color/white"
+                android:scaleType="fitCenter" />
+
+        </com.google.android.material.appbar.MaterialToolbar>
+
     </com.google.android.material.appbar.AppBarLayout>
 
+    <com.bluelinelabs.conductor.ChangeHandlerFrameLayout
+        android:id="@+id/controller_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/bg_default"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 2 - 1
app/src/main/res/layout/controller_account_verification.xml

@@ -22,7 +22,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/nc_white_color"
+    android:background="@color/bg_default"
     android:keepScreenOn="true">
 
     <ProgressBar
@@ -53,6 +53,7 @@
         android:layout_marginRight="@dimen/activity_horizontal_margin"
         android:textAlignment="center"
         android:textSize="18sp"
+        android:textColor="@color/fg_default"
         tools:text="Verifying..." />
 
 </RelativeLayout>

+ 4 - 0
app/src/main/res/layout/controller_browser.xml

@@ -39,6 +39,8 @@
         android:layout_width="match_parent"
         android:layout_height="64dp"
         android:background="@color/bg_default"
+        app:itemTextColor="@color/fg_default"
+        app:itemIconTint="@color/fg_default"
         app:menu="@menu/file_browser_path" />
 
     <com.google.android.material.bottomnavigation.BottomNavigationView
@@ -47,6 +49,8 @@
         android:layout_height="64dp"
         android:layout_alignParentBottom="true"
         android:background="@color/bg_default"
+        app:itemTextColor="@color/fg_default"
+        app:itemIconTint="@color/fg_default"
         app:menu="@menu/file_browser_bottom" />
 
     <include

+ 1 - 0
app/src/main/res/layout/controller_call.xml

@@ -27,6 +27,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
+        android:fitsSystemWindows="true"
         tools:context=".activities.MagicCallActivity">
 
     <LinearLayout

+ 1 - 1
app/src/main/res/layout/controller_call_menu.xml

@@ -22,7 +22,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@color/nc_white_color">
+    android:background="@color/bg_default">
 
     <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/recycler_view"

+ 2 - 1
app/src/main/res/layout/controller_chat.xml

@@ -25,7 +25,8 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:keepScreenOn="true"
-    android:animateLayoutChanges="true">
+    android:animateLayoutChanges="true"
+    android:background="@color/bg_default">
 
     <include layout="@layout/lobby_view"
         android:visibility="gone"

+ 1 - 1
app/src/main/res/layout/controller_entry_menu.xml

@@ -35,7 +35,7 @@
         android:layout_marginEnd="8dp"
         android:layout_marginBottom="12dp"
         android:alpha="0.7"
-        android:background="#0000"
+        android:background="@color/bg_default"
         android:enabled="false"
         android:text="@string/nc_proceed"
         android:textColor="@color/colorPrimary" />

+ 9 - 6
app/src/main/res/layout/controller_generic_rv.xml

@@ -19,6 +19,7 @@
   -->
 
 <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/generic_rv_layout"
     android:layout_width="match_parent"
@@ -33,15 +34,17 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent">
 
-            <androidx.recyclerview.widget.RecyclerView
-                android:id="@+id/recycler_view"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                tools:listitem="@layout/rv_item_conversation" />
-
         </FrameLayout>
 
     </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
 
     <include layout="@layout/fast_scroller" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recycler_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_anchor="@+id/swipe_refresh_layout"
+        app:layout_anchorGravity="center"
+        tools:listitem="@layout/rv_item_conversation" />
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 1 - 1
app/src/main/res/layout/controller_locked.xml

@@ -49,5 +49,5 @@
         android:padding="16dp"
         android:text="@string/nc_locked"
         android:textAlignment="center"
-        android:textColor="@color/white" />
+        android:textColor="@color/fg_inverse" />
 </RelativeLayout>

+ 3 - 3
app/src/main/res/layout/controller_operations_menu.xml

@@ -21,7 +21,7 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@color/nc_white_color">
+    android:background="@color/bg_default">
 
     <ImageView
         android:id="@+id/result_image_view"
@@ -70,7 +70,7 @@
         android:layout_alignParentEnd="true"
         android:layout_marginEnd="8dp"
         android:layout_marginBottom="12dp"
-        android:background="#0000"
+        android:background="@color/bg_inverse"
         android:text="@string/nc_ok"
         android:textColor="@color/colorPrimary"
         android:visibility="gone" />
@@ -84,7 +84,7 @@
         android:layout_marginEnd="8dp"
         android:layout_marginBottom="12dp"
         android:layout_toStartOf="@id/ok_button"
-        android:background="#0000"
+        android:background="@color/bg_inverse"
         android:text="@string/nc_join_via_web"
         android:textColor="@color/nc_darkGreen"
         android:visibility="gone" />

+ 2 - 2
app/src/main/res/layout/rv_item_app.xml

@@ -22,7 +22,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@color/white"
+    android:background="@color/bg_default"
     android:paddingTop="16dp"
     android:paddingBottom="16dp">
 
@@ -46,7 +46,7 @@
         android:layout_toEndOf="@id/icon_image_view"
         android:focusable="false"
         android:focusableInTouchMode="false"
-        android:textColor="@color/black"
+        android:textColor="@color/fg_default"
         android:textSize="16sp"
         tools:text="Start a new conversation" />
 

+ 1 - 1
app/src/main/res/layout/rv_item_browser_file.xml

@@ -43,7 +43,7 @@
         android:layout_below="@id/file_icon"
         android:layout_alignEnd="@id/file_icon"
         android:src="@drawable/ic_star_black_24dp"
-        android:tint="@color/grey_600" />
+        app:tint="@color/grey_600" />
 
     <ImageView
         android:id="@+id/fileEncryptedImageView"

+ 120 - 0
app/src/main/res/layout/search_layout.xml

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ /*
+  ~  * Nextcloud Talk application
+  ~  *
+  ~  * @author Mario Danic
+  ~  * @author Andy Scherzinger
+  ~  * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
+  ~  * Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
+  ~  *
+  ~  * This program is free software: you can redistribute it and/or modify
+  ~  * it under the terms of the GNU 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 General Public License for more details.
+  ~  *
+  ~  * You should have received a copy of the GNU General Public License
+  ~  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  ~  */
+  -->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <com.google.android.material.card.MaterialCardView
+        android:id="@+id/home_toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="5dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginBottom="1dp"
+        android:visibility="gone"
+        app:cardCornerRadius="8dp"
+        app:cardElevation="2dp"
+        app:strokeWidth="0dp"
+        tools:visibility="visible">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/menu_button"
+                style="@style/Widget.AppTheme.Button.IconButton"
+                android:layout_width="3dp"
+                android:layout_height="1dp"
+                android:layout_marginStart="5dp"
+                android:contentDescription="@string/nc_action_open_main_menu"
+                android:visibility="gone"
+                app:cornerRadius="@dimen/button_corner_radius"
+                app:icon="@drawable/ic_menu"
+                app:iconTint="@color/fontAppbar"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <com.google.android.material.textview.MaterialTextView
+                android:id="@+id/search_text"
+                android:layout_width="0dp"
+                android:layout_height="48dp"
+                android:layout_marginStart="13dp"
+                android:layout_marginEnd="18dp"
+                android:ellipsize="end"
+                android:gravity="start|center_vertical"
+                android:lines="1"
+                android:textColor="@color/fontSecondaryAppbar"
+                android:textSize="16sp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintLeft_toRightOf="@id/menu_button"
+                app:layout_constraintRight_toLeftOf="@id/rightContainer"
+                app:layout_constraintTop_toTopOf="parent"
+                tools:text="Search in Nextcloud" />
+
+            <FrameLayout
+                android:id="@+id/rightContainer"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_alignParentEnd="true"
+                android:minWidth="48dp"
+                android:layout_centerVertical="true"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent">
+
+                <com.google.android.material.button.MaterialButton
+                    android:id="@+id/switch_account_button"
+                    style="@style/Widget.AppTheme.Button.IconButton"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"
+                    android:layout_gravity="center"
+                    android:scaleType="fitCenter"
+                    android:transitionName="userAvatar.transitionTag"
+                    app:cornerRadius="@dimen/button_corner_radius"
+                    app:iconSize="@dimen/avatar_size_app_bar"
+                    tools:visibility="gone" />
+
+                <ProgressBar
+                    android:id="@+id/searchProgressBar"
+                    android:layout_width="32dp"
+                    android:layout_height="32dp"
+                    android:padding="4dp"
+                    android:layout_gravity="center"
+                    android:indeterminate="true"
+                    android:indeterminateTint="@color/colorPrimary"
+                    android:scaleType="fitCenter"
+                    android:visibility="gone" />
+
+            </FrameLayout>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </com.google.android.material.card.MaterialCardView>
+</merge>

+ 1 - 8
app/src/main/res/menu/menu_conversation_plus_filter.xml

@@ -28,13 +28,6 @@
 	      android:icon="@drawable/ic_search_white_24dp"
 	      app:showAsAction="collapseActionView|always"
 	      android:animateLayoutChanges="true"
-	      app:actionViewClass="androidx.appcompat.widget.SearchView"
-        />
-
-	<item android:id="@+id/action_settings"
-		android:title="@string/nc_settings"
-		android:icon="@drawable/ic_settings_white_24dp"
-		app:showAsAction="ifRoom"/>
-
+	      app:actionViewClass="androidx.appcompat.widget.SearchView" />
 
 </menu>

+ 18 - 0
app/src/main/res/values-night/colors.xml

@@ -24,10 +24,28 @@
   -->
 
 <resources>
+    <bool name="is_night">true</bool>
+    <bool name="status_bar_light">false</bool>
+
+    <color name="colorPrimary">#0082C9</color>
+    <color name="colorPrimaryDark">#006AA3</color>
+    <color name="colorAccent">#007CC2</color>
+
+    <!-- App bar -->
+    <color name="appbar">#1E1E1E</color>
+    <color name="fontAppbar">#FFFFFF</color>
+
     <color name="conversation_item_header">#deffffff</color>
 
     <color name="bg_default">#121212</color>
     <color name="bg_alt">#121212</color>
+    <color name="bg_inverse">@color/grey950</color>
+
+    <color name="fg_default">#FFFFFF</color>
+    <color name="fg_inverse">#121212</color>
+    <color name="fg_contrast">#717171</color>
+    <color name="fg_chat_message_sent">@color/fg_default</color>
+
     <color name="nc_darkGreen">#00AA00</color>
 
     <color name="conversation_unread_bubble">#373737</color>

+ 15 - 0
app/src/main/res/values/colors.xml

@@ -22,9 +22,20 @@
   -->
 
 <resources>
+    <bool name="is_night">false</bool>
+    <bool name="status_bar_light">true</bool>
+
     <color name="colorPrimary">#0082C9</color>
+    <color name="colorPrimaryDark">#006AA3</color>
+    <color name="colorAccent">#007CC2</color>
     <color name="textColorOnPrimaryBackground">#ffffff</color> <!-- white/black depending on primary color -->
 
+    <!-- App bar -->
+    <color name="appbar">@android:color/white</color>
+    <color name="fontAppbar">#666666</color>
+    <color name="fontSecondaryAppbar">#A5A5A5</color>
+    <color name="actionbar_shadow">#222222</color>
+
     <!-- Text color of sent messages -->
     <color name="nc_outcoming_text_default">#FFFFFF</color>
     <!-- Text color of received messages -->
@@ -48,10 +59,14 @@
     <!-- Emoji list in chat window -->
     <color name="emoji_icons">#61000000</color>
 
+    <color name="fg_default">#666666</color>
     <color name="fg_inverse">#FFFFFF</color>
+    <color name="fg_contrast">#656565</color>
+    <color name="fg_chat_message_sent">@color/fg_default</color>
 
     <color name="bg_default">#FFFFFF</color>
     <color name="bg_alt">@color/white60</color>
+    <color name="bg_inverse">@color/grey950</color>
     <color name="bg_dark_mention_chips">#333333</color>
 
     <color name="bg_message_list_incoming_bubble">#EFEFEF</color>

+ 2 - 0
app/src/main/res/values/dimens.xml

@@ -30,6 +30,7 @@
     <dimen name="margin_between_elements">8dp</dimen>
     <dimen name="double_margin_between_elements">16dp</dimen>
     <dimen name="avatar_size">40dp</dimen>
+    <dimen name="avatar_size_app_bar">30dp</dimen>
     <dimen name="avatar_size_big">96dp</dimen>
     <dimen name="avatar_size_very_big">@dimen/avatar_fetching_size_very_big</dimen>
     <dimen name="avatar_fetching_size_very_big">180dp</dimen>
@@ -42,4 +43,5 @@
 
     <dimen name="large_preview_dimension">80dp</dimen>
     <dimen name="corner_radius">16dp</dimen>
+    <dimen name="button_corner_radius">24dp</dimen>
 </resources>

+ 4 - 1
app/src/main/res/values/strings.xml

@@ -307,7 +307,6 @@
     <string name="nc_file_browser_reshare_forbidden">You are not allowed to re-share this file</string>
 
     <!-- Lobby -->
-
     <string name="nc_webinar">Webinar</string>
     <string name="nc_lobby">Lobby</string>
     <string name="nc_start_time">Start time</string>
@@ -358,8 +357,12 @@
     <string name="nc_phone_book_integration_chat_via">Chat via %s</string>
     <string name="nc_phone_book_integration_account_not_found">Account not found</string>
 
+    <!-- App Bar -->
+    <string name="appbar_search_in">Search in %s</string>
+
     <!-- Non-translatable strings -->
     <string name="path_password_strike_through" translatable="false"
         tools:override="true">M3.27,4.27L19.74,20.74</string>
     <string name="tooManyUnreadMessages" translatable="false">999+</string>
+    <string name="nc_action_open_main_menu">Open main menu</string>
 </resources>

+ 88 - 11
app/src/main/res/values/styles.xml

@@ -4,7 +4,7 @@
   ~ @author Mario Danic
   ~ @author Andy Scherzinger
   ~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
-  ~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+  ~ Copyright (C) 2017-2020 Mario Danic <mario@lovelyhq.com>
   ~
   ~ This program is free software: you can redistribute it and/or modify
   ~ it under the terms of the GNU General Public License as published by
@@ -26,15 +26,16 @@
     <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
         <!-- Customize your theme here. -->
         <item name="colorPrimary">@color/colorPrimary</item>
-        <item name="colorPrimaryDark">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
         <item name="colorAccent">@color/colorPrimary</item>
-        <item name="android:windowBackground">@color/bg_default</item>
         <item name="android:panelFullBackground">@color/colorPrimary</item>
         <item name="android:itemBackground">@color/nc_outcoming_text_default</item>
         <item name="android:textColor">@color/nc_incoming_text_default</item>
         <item name="android:popupMenuStyle">@style/appActionBarPopupMenu</item>
         <item name="actionOverflowMenuStyle">@style/appActionBarPopupMenu</item>
-        <item name="actionBarStyle">@style/appActionBarStyle</item>
+        <item name="actionBarPopupTheme">@style/appActionBarPopupMenu</item>
+        <item name="searchViewStyle">@style/SearchView</item>
+        <item name="textInputStyle">@style/TextInputLayout</item>
     </style>
 
     <style name="ErrorAppearance" parent="@android:style/TextAppearance">
@@ -55,7 +56,7 @@
     </style>
 
     <style name="ChipMentionTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
-        <item name="android:textColor">@color/colorPrimary</item>
+        <item name="android:textColor">@color/colorAccent</item>
     </style>
 
     <style name="ChipUnreadMessagesTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
@@ -64,19 +65,95 @@
     </style>
 
     <style name="appActionBarStyle" parent="@style/Widget.MaterialComponents.ActionBar.Solid">
-        <item name="android:colorPrimary">@color/fg_inverse</item>
-        <item name="android:textColor">@color/fg_inverse</item>
+        <item name="colorControlNormal">@color/fontAppbar</item>
+        <item name="android:colorPrimary">@color/appbar</item>
+        <item name="android:colorAccent">@color/appbar</item>
+        <item name="android:textColor">@color/fontAppbar</item>
+        <item name="android:textColorSecondary">@color/fontAppbar</item>
+        <item name="searchViewStyle">@style/SearchView</item>
     </style>
 
     <style name="Toolbar_TextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
-        <item name="android:colorPrimary">@color/fg_inverse</item>
-        <item name="android:textColor">@color/fg_inverse</item>
+        <item name="android:colorPrimary">@color/fontAppbar</item>
+        <item name="android:textColor">@color/fontAppbar</item>
+        <item name="android:textColorPrimary">@color/fontAppbar</item>
     </style>
 
     <style name="appActionBarPopupMenu" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
         <item name="android:colorPrimary">@color/fg_inverse</item>
-        <item name="android:background">@color/bg_alt</item>
-        <item name="android:textColor">@color/nc_incoming_text_default</item>
+        <item name="android:textColorSecondary">@color/fontAppbar</item>
+        <item name="android:background">@color/appbar</item>
+        <item name="android:textColor">@color/conversation_item_header</item>
+        <item name="iconTint">@color/fontAppbar</item>
+    </style>
+
+    <style name="SearchView" parent="Widget.AppCompat.SearchView">
+        <!-- Close button icon -->
+        <item name="closeIcon">@drawable/ic_close_search</item>
+        <!-- Search button icon -->
+        <item name="searchIcon">@drawable/ic_search_grey</item>
+        <!-- Layout for query suggestion rows // unused for now, staying with the standard layout -->
+        <!--<item name="suggestionRowLayout">...</item>-->
+        <item name="submitBackground">@color/appbar</item>
+        <item name="queryBackground">@color/appbar</item>
+        <item name="searchHintIcon">@null</item>
+    </style>
+
+    <style name="circleImageView" parent="">
+        <item name="cornerFamily">rounded</item>
+        <item name="cornerSize">50%</item>
+    </style>
+
+    <style name="Widget.AppTheme.Button.IconButton" parent="Widget.MaterialComponents.Button.TextButton">
+        <item name="android:minWidth">0dp</item>
+        <item name="android:insetLeft">0dp</item>
+        <item name="android:insetTop">0dp</item>
+        <item name="android:insetRight">0dp</item>
+        <item name="android:insetBottom">0dp</item>
+        <item name="iconGravity">textStart</item>
+        <item name="iconPadding">0dp</item>
     </style>
 
+    <style name="TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
+        <item name="colorControlActivated">@color/fg_default</item>
+        <item name="colorControlHighlight">@color/fg_default</item>
+        <item name="boxBackgroundColor">@color/bg_default</item>
+        <item name="hintTextColor">@color/fg_default</item>
+        <item name="helperTextTextColor">@color/fg_default</item>
+        <item name="boxStrokeColor">@color/fg_default</item>
+    </style>
+
+    <style name="Widget.App.Login.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
+        <item name="colorControlActivated">@color/white</item>
+        <item name="colorControlHighlight">@color/white</item>
+        <item name="materialThemeOverlay">@style/ThemeOverlay.App.Login.TextInputLayout</item>
+        <item name="shapeAppearance">@style/ShapeAppearance.MaterialComponents.SmallComponent</item>
+        <item name="hintTextColor">@color/white</item>
+        <item name="helperTextTextColor">@color/white</item>
+    </style>
+
+    <style name="ThemeOverlay.App.Login.TextInputLayout" parent="">
+        <item name="colorPrimary">@color/white</item>
+        <item name="colorOnSurface">@color/white</item>
+        <item name="colorError">@color/nc_darkRed</item>
+        <item name="textAppearanceSubtitle1">@style/TextAppearance.MaterialComponents.Subtitle1</item>
+        <item name="textAppearanceCaption">@style/TextAppearance.MaterialComponents.Caption</item>
+        <item name="editTextStyle">@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox</item>
+    </style>
+
+    <style name="TextInputLayoutLogin" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
+        <item name="boxStrokeColor">@color/white</item>
+        <item name="boxStrokeErrorColor">@color/white</item>
+        <item name="hintTextAppearance">@style/HintTextLogin</item>
+        <item name="errorTextAppearance">@style/HintTextLogin</item>
+        <item name="android:colorPrimary">@color/white</item>
+        <!-- Theme attributes -->
+        <item name="android:textColorHint">#80FFFFFF</item>
+        <item name="colorControlNormal">@color/white</item>
+        <item name="colorControlActivated">@color/white</item>
+    </style>
+
+    <style name="HintTextLogin" parent="TextAppearance.AppCompat">
+        <item name="android:textColor">@color/white</item>
+    </style>
 </resources>