Skip to content

Commit

Permalink
Merge pull request #1680 from nextcloud/theme-alignment
Browse files Browse the repository at this point in the history
feat(theming): Use nextcloud-common library for theming UI elements (#1648)
  • Loading branch information
AlvaroBrey authored Feb 16, 2023
2 parents 466d053 + 2558acd commit 1f1cdc0
Show file tree
Hide file tree
Showing 48 changed files with 486 additions and 532 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'

// Nextcloud SSO
implementation 'com.github.nextcloud.android-common:ui:0.6.0'
implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1'
implementation 'com.github.stefan-niedermann:android-commons:0.2.9'
implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.branding.BrandedActivity;
import it.niedermann.owncloud.notes.branding.BrandingUtil;
import it.niedermann.owncloud.notes.databinding.ActivityFormattingHelpBinding;

import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences;
Expand Down Expand Up @@ -222,7 +223,8 @@ private String buildFormattingHelp() {
}

@Override
public void applyBrand(int mainColor, int textColor) {
applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar);
public void applyBrand(int color) {
final var util = BrandingUtil.of(color, this);
util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package it.niedermann.owncloud.notes;

import static androidx.preference.PreferenceManager.getDefaultSharedPreferences;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.util.Log;

import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;

import it.niedermann.owncloud.notes.preferences.DarkModeSetting;

import static androidx.preference.PreferenceManager.getDefaultSharedPreferences;

public class NotesApplication extends Application {
private static final String TAG = NotesApplication.class.getSimpleName();

Expand Down Expand Up @@ -57,19 +55,6 @@ public static DarkModeSetting getAppTheme(Context context) {
return DarkModeSetting.valueOf(mode);
}

public static boolean isDarkThemeActive(Context context, DarkModeSetting setting) {
if (setting == DarkModeSetting.SYSTEM_DEFAULT) {
return isDarkThemeActive(context);
} else {
return setting == DarkModeSetting.DARK;
}
}

public static boolean isDarkThemeActive(Context context) {
final int uiMode = context.getResources().getConfiguration().uiMode;
return (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}

public static void setLockedPreference(boolean lockedPreference) {
Log.i(TAG, "New locked preference: " + lockedPreference);
NotesApplication.lockedPreference = lockedPreference;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ protected void onCreate(Bundle savedInstanceState) {
}

@Override
public void applyBrand(int mainColor, int textColor) {
applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar);
@ColorInt int finalMainColor = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(this, mainColor);
binding.tabs.setSelectedTabIndicatorColor(finalMainColor);
public void applyBrand(int color) {
final var util = BrandingUtil.of(color, this);
util.material.themeTabLayout(binding.tabs);
util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent);
}

private static class TabsStateAdapter extends FragmentStateAdapter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
}

@Override
public void applyBrand(int mainColor, int textColor) {
@ColorInt final int finalMainColor = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(requireContext(), mainColor);
DrawableCompat.setTintList(binding.aboutAppLicenseButton.getBackground(), ColorStateList.valueOf(finalMainColor));
binding.aboutAppLicenseButton.setTextColor(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(finalMainColor));
public void applyBrand(int color) {
final var util = BrandingUtil.of(color, requireContext());
util.material.colorMaterialButtonPrimaryFilled(binding.aboutAppLicenseButton);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public static DialogFragment newInstance(@NonNull ArrayList<Account> targetAccou
}

@Override
public void applyBrand(int mainColor, int textColor) {
public void applyBrand(int color) {
// Nothing to do...
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package it.niedermann.owncloud.notes.accountswitcher;

import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToLayerDrawable;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
Expand All @@ -18,6 +16,7 @@

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.branding.BrandedDialogFragment;
import it.niedermann.owncloud.notes.branding.BrandingUtil;
import it.niedermann.owncloud.notes.databinding.DialogAccountSwitcherBinding;
import it.niedermann.owncloud.notes.manageaccounts.ManageAccountsActivity;
import it.niedermann.owncloud.notes.persistence.NotesRepository;
Expand Down Expand Up @@ -117,7 +116,8 @@ public static DialogFragment newInstance(long currentAccountId) {
}

@Override
public void applyBrand(int mainColor, int textColor) {
applyBrandToLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, mainColor);
public void applyBrand(int color) {
final var util = BrandingUtil.of(color, requireContext());
util.notes.colorLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, color);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@

public interface Branded {
@UiThread
void applyBrand(@ColorInt int mainColor, @ColorInt int textColor);
void applyBrand(@ColorInt int color);
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
package it.niedermann.owncloud.notes.branding;

import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColorLiveData;

import android.util.TypedValue;
import android.view.Menu;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

import it.niedermann.owncloud.notes.R;

import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandColors;
import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon;

public abstract class BrandedActivity extends AppCompatActivity implements Branded {

@ColorInt
protected int colorAccent;

public static void applyBrandToFAB(@ColorInt int mainColor, @ColorInt int textColor, @NonNull FloatingActionButton fab) {
fab.setSupportBackgroundTintList(ColorStateList.valueOf(mainColor));
fab.setColorFilter(textColor);
}

@Override
protected void onStart() {
super.onStart();
Expand All @@ -38,31 +23,17 @@ protected void onStart() {
getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
colorAccent = typedValue.data;

readBrandColors(this).observe(this, (pair) -> applyBrand(pair.first, pair.second));
readBrandMainColorLiveData(this).observe(this, this::applyBrand);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
for (int i = 0; i < menu.size(); i++) {
tintMenuIcon(menu.getItem(i), colorAccent);
}
return super.onCreateOptionsMenu(menu);
}

public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar) {
// FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889
appBarLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.primary));
final var utils = BrandingUtil.of(colorAccent, this);

final var overflowDrawable = toolbar.getOverflowIcon();
if (overflowDrawable != null) {
overflowDrawable.setColorFilter(colorAccent, PorterDuff.Mode.SRC_ATOP);
toolbar.setOverflowIcon(overflowDrawable);
for (int i = 0; i < menu.size(); i++) {
utils.platform.colorToolbarMenuIcon(this, menu.getItem(i));
}

final var navigationDrawable = toolbar.getNavigationIcon();
if (navigationDrawable != null) {
navigationDrawable.setColorFilter(colorAccent, PorterDuff.Mode.SRC_ATOP);
toolbar.setNavigationIcon(navigationDrawable);
}
return super.onCreateOptionsMenu(menu);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public void onStart() {
super.onStart();

@Nullable final var context = requireContext();
@ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context);
@ColorInt final int textColor = BrandingUtil.readBrandTextColor(context);
applyBrand(mainColor, textColor);
@ColorInt final int color = BrandingUtil.readBrandMainColor(context);
applyBrand(color);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package it.niedermann.owncloud.notes.branding;

import android.content.Context;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import it.niedermann.owncloud.notes.R;

import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon;

public abstract class BrandedFragment extends Fragment implements Branded {

@ColorInt
Expand All @@ -32,16 +28,19 @@ public void onStart() {
context.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
colorPrimary = typedValue.data;

@ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context);
@ColorInt final int textColor = BrandingUtil.readBrandTextColor(context);
applyBrand(mainColor, textColor);
@ColorInt final int color = BrandingUtil.readBrandMainColor(context);
applyBrand(color);
}

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
final var utils = BrandingUtil.of(colorAccent, requireContext());

for (int i = 0; i < menu.size(); i++) {
tintMenuIcon(menu.getItem(i), colorAccent);
if (menu.getItem(i).getIcon() != null) {
utils.platform.colorToolbarMenuIcon(requireContext(), menu.getItem(i));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceViewHolder;

import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme;
import com.nextcloud.android.common.ui.theme.utils.ColorRole;

public class BrandedPreferenceCategory extends PreferenceCategory {

Expand All @@ -36,9 +34,10 @@ public void onBindViewHolder(PreferenceViewHolder holder) {

final var view = holder.itemView.findViewById(android.R.id.title);
@Nullable final var context = getContext();
if (context != null && view instanceof TextView) {
@ColorInt final int mainColor = getSecondaryForegroundColorDependingOnTheme(context, BrandingUtil.readBrandMainColor(context));
((TextView) view).setTextColor(mainColor);
if (view instanceof TextView) {
final var util = BrandingUtil.of(BrandingUtil.readBrandMainColor(context), context);

util.platform.colorTextView((TextView) view, ColorRole.ON_PRIMARY_CONTAINER);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package it.niedermann.owncloud.notes.branding;

import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive;
import static it.niedermann.owncloud.notes.branding.BrandingUtil.getAttribute;
import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColor;
import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient;

import android.graphics.Color;
import android.view.View;

import androidx.annotation.ColorInt;
Expand All @@ -15,26 +11,15 @@
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;

import it.niedermann.owncloud.notes.R;

public class BrandedSnackbar {

@NonNull
public static Snackbar make(@NonNull View view, @NonNull CharSequence text, @BaseTransientBottomBar.Duration int duration) {
final var snackbar = Snackbar.make(view, text, duration);

@ColorInt final int backgroundColor = getAttribute(view.getContext(), R.attr.colorSurfaceInverse);
@ColorInt final int color = readBrandMainColor(view.getContext());
final var snackbar = Snackbar.make(view, text, duration);
final var utils = BrandingUtil.of(color, view.getContext());

if (contrastRatioIsSufficient(backgroundColor, color)) {
snackbar.setActionTextColor(color);
} else {
if (isDarkThemeActive(view.getContext())) {
snackbar.setActionTextColor(Color.BLACK);
} else {
snackbar.setActionTextColor(Color.WHITE);
}
}
utils.material.themeSnackbar(snackbar);

return snackbar;
}
Expand Down
Loading

0 comments on commit 1f1cdc0

Please sign in to comment.