Merge pull request #1097 from nextcloud/newSearchToolBar

Introduce SearchBar/Toolbar in dark/light design
This commit is contained in:
Marcel Hibbe 2021-04-07 19:58:03 +02:00 committed by GitHub
commit 7375e0d439
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 731 additions and 146 deletions

View file

@ -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

View file

@ -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

View file

@ -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,93 @@ 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.appbar, null)
);
}
});
}
searchView.setOnCloseListener(() -> {
if (TextUtils.isEmpty(searchView.getQuery().toString())) {
searchView.onActionViewCollapsed();
if (activity != null && getResources() != null) {
DisplayUtils.applyColorToStatusBar(
activity,
ResourcesCompat.getColor(getResources(), R.color.bg_default, 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);
if (getResources() != null) {
DisplayUtils.applyColorToStatusBar(
activity,
ResourcesCompat.getColor(getResources(), R.color.bg_default, null)
);
}
}
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 +469,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 +512,6 @@ public class ConversationsListController extends BaseController implements Searc
isRefreshing = false;
});
}
private void prepareViews() {
@ -472,6 +547,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 +579,6 @@ public class ConversationsListController extends BaseController implements Searc
roomsQueryDisposable != null && !roomsQueryDisposable.isDisposed()) {
roomsQueryDisposable.dispose();
roomsQueryDisposable = null;
}
}
@ -508,7 +596,9 @@ public class ConversationsListController extends BaseController implements Searc
@Override
public void onRestoreViewState(@NonNull View view, @NonNull Bundle savedViewState) {
super.onRestoreViewState(view, savedViewState);
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 +615,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 +691,6 @@ public class ConversationsListController extends BaseController implements Searc
bottomSheet.show();
}
@Override
protected String getTitle() {
return getResources().getString(R.string.nc_app_name);
@ -624,7 +712,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 +840,9 @@ public class ConversationsListController extends BaseController implements Searc
}
}
@Override
public AppBarLayoutType getAppBarLayoutType() {
return AppBarLayoutType.SEARCH_BAR;
}
}

View file

@ -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;
}
}

View file

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

View file

@ -37,6 +37,7 @@ import android.webkit.*;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.res.ResourcesCompat;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import autodagger.AutoInjector;
@ -50,6 +51,7 @@ import com.nextcloud.talk.events.CertificateEvent;
import com.nextcloud.talk.jobs.PushRegistrationWorker;
import com.nextcloud.talk.models.LoginData;
import com.nextcloud.talk.models.database.UserEntity;
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;
@ -452,6 +454,16 @@ public class WebViewLoginController extends BaseController {
}
}
@Override
protected void onAttach(@NonNull View view) {
super.onAttach(view);
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));
}
}
@Override
public void onDestroy() {
super.onDestroy();
@ -465,4 +477,9 @@ public class WebViewLoginController extends BaseController {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}
}
@Override
public AppBarLayoutType getAppBarLayoutType() {
return AppBarLayoutType.EMPTY;
}
}

View file

@ -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));
}
}

View file

@ -107,6 +107,8 @@ import retrofit2.Retrofit;
@AutoInjector(NextcloudTalkApplication.class)
public class NotificationWorker extends Worker {
public static final String TAG = "NotificationWorker";
private static final String CHAT = "chat";
private static final String ROOM = "room";
@Inject
AppPreferences appPreferences;
@ -274,7 +276,7 @@ public class NotificationWorker extends Worker {
smallIcon = R.drawable.ic_logo;
if (decryptedPushMessage.getType().equals("chat") || decryptedPushMessage.getType().equals("room")) {
if (CHAT.equals(decryptedPushMessage.getType()) || ROOM.equals(decryptedPushMessage.getType())) {
category = Notification.CATEGORY_MESSAGE;
} else {
category = Notification.CATEGORY_CALL;
@ -289,7 +291,7 @@ public class NotificationWorker extends Worker {
break;
default:
// assuming one2one
if (decryptedPushMessage.getType().equals("chat") || decryptedPushMessage.getType().equals("room")) {
if (CHAT.equals(decryptedPushMessage.getType()) || ROOM.equals(decryptedPushMessage.getType())) {
largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_comment);
} else {
largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_call_black_24dp);
@ -339,7 +341,7 @@ public class NotificationWorker extends Worker {
Long.toString(crc32.getValue()),
groupName);*/
if (decryptedPushMessage.getType().equals("chat") || decryptedPushMessage.getType().equals("room")) {
if (CHAT.equals(decryptedPushMessage.getType()) || ROOM.equals(decryptedPushMessage.getType())) {
AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder().setContentType
(AudioAttributes.CONTENT_TYPE_SONIFICATION);
audioAttributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
@ -517,7 +519,7 @@ public class NotificationWorker extends Worker {
AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder().setContentType
(AudioAttributes.CONTENT_TYPE_SONIFICATION);
if (decryptedPushMessage.getType().equals("chat") || decryptedPushMessage.getType().equals("room")) {
if (CHAT.equals(decryptedPushMessage.getType()) || ROOM.equals(decryptedPushMessage.getType())) {
audioAttributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
} else {
audioAttributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);

View file

@ -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;
@ -28,6 +29,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
@ -49,7 +51,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 +63,15 @@ 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.ColorUtils;
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;
@ -101,6 +111,9 @@ public class DisplayUtils {
private static final String TAG = "DisplayUtils";
private static final int INDEX_LUMINATION = 2;
private static final double MAX_LIGHTNESS = 0.92;
public static void setClickableString(String string, String url, TextView textView) {
SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(new ClickableSpan() {
@ -305,7 +318,6 @@ public class DisplayUtils {
return chip;
}
public static Spannable searchAndReplaceWithMentionSpan(Context context, Spannable text,
String id, String label, String type,
UserEntity conversationUser,
@ -342,7 +354,6 @@ public class DisplayUtils {
}
return spannableString;
}
public static Spannable searchAndColor(Spannable text, String searchText, @ColorInt int color) {
@ -395,20 +406,69 @@ public class DisplayUtils {
return drawable;
}
public static boolean isDarkModeActive(Context context, AppPreferences prefs) {
if (prefs.getTheme().equals("night_yes")) {
return true;
/**
* Sets the color of the status bar to {@code color}.
*
* @param activity activity
* @param color the color
*/
public static void applyColorToStatusBar(Activity activity, @ColorInt int color) {
Window window = activity.getWindow();
boolean isLightTheme = lightTheme(color);
if (window != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decor = window.getDecorView();
if (isLightTheme) {
int systemUiFlagLightStatusBar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
} else {
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
decor.setSystemUiVisibility(systemUiFlagLightStatusBar);
} else {
decor.setSystemUiVisibility(0);
}
window.setStatusBarColor(color);
} else if (isLightTheme) {
window.setStatusBarColor(Color.BLACK);
}
}
}
int currentNightMode =
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
return false;
case Configuration.UI_MODE_NIGHT_YES:
return true;
default:
return false;
/**
* Tests if light color is set
*
* @param color the color
* @return true if primaryColor is lighter than MAX_LIGHTNESS
*/
public static boolean lightTheme(int color) {
float[] hsl = colorToHSL(color);
return hsl[INDEX_LUMINATION] >= MAX_LIGHTNESS;
}
private static float[] colorToHSL(int color) {
float[] hsl = new float[3];
ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl);
return hsl;
}
public static void applyColorToNavigationBar(Window window, @ColorInt int color) {
window.setNavigationBarColor(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
SearchView.SearchAutoComplete editText = searchView.findViewById(R.id.search_src_text);
editText.setTextSize(16);
editText.setHintTextColor(context.getResources().getColor(R.color.fontSecondaryAppbar));
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
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="?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" />
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -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>

View file

@ -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

View file

@ -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
@ -71,7 +72,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/nc_voice_call"/>
tools:text="Voice Call"/>
<TextView
android:id="@+id/callConversationNameTextView"
@ -101,7 +102,7 @@
android:visibility="invisible"
tools:visibility="visible"/>
<com.facebook.drawee.view.SimpleDraweeView xmlns:app="http://schemas.android.com/apk/res-auto"
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/call_control_switch_camera"
android:layout_width="40dp"
android:layout_height="40dp"

View file

@ -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"

View file

@ -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"

View file

@ -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" />

View file

@ -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>

View file

@ -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>

View file

@ -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" />

View file

@ -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" />

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -24,10 +24,22 @@
-->
<resources>
<color name="colorPrimary">#0082C9</color>
<color name="colorPrimaryDark">#006AA3</color>
<color name="colorAccent">@color/colorPrimary</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="nc_darkGreen">#00AA00</color>
<color name="conversation_unread_bubble">#373737</color>

View file

@ -23,8 +23,15 @@
<resources>
<color name="colorPrimary">#0082C9</color>
<color name="colorPrimaryDark">#006AA3</color>
<color name="colorAccent">@color/colorPrimary</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>
<!-- Text color of sent messages -->
<color name="nc_outcoming_text_default">#FFFFFF</color>
<!-- Text color of received messages -->
@ -37,7 +44,6 @@
<color name="nc_darkRed">#D32F2F</color>
<color name="nc_darkGreen">#006400</color>
<color name="nc_white_color">@color/per70white</color>
<color name="controller_chat_separator">#E8E8E8</color>
<color name="grey_600">#757575</color>
<color name="nc_grey">#D5D5D5</color>
@ -48,10 +54,11 @@
<!-- 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="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>

View file

@ -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>

View file

@ -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>

View file

@ -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="colorAccent">@color/colorPrimary</item>
<item name="android:windowBackground">@color/bg_default</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</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="android:navigationBarColor">@color/bg_default</item>
</style>
<style name="ErrorAppearance" parent="@android:style/TextAppearance">
@ -54,29 +55,38 @@
<item name="android:textColor">@color/textColorOnPrimaryBackground</item>
</style>
<style name="ChipMentionTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:textColor">@color/colorPrimary</item>
</style>
<style name="ChipUnreadMessagesTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:textSize">14sp</item>
<item name="android:textStyle">bold</item>
</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>
</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>
</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="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>
</resources>

View file

@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE
<span class="mdl-layout-title">Lint Report: 3 errors and 131 warnings</span>
<span class="mdl-layout-title">Lint Report: 3 errors and 130 warnings</span>