From db819fc5ab78a9b6b0a7ab12016349d403ce7835 Mon Sep 17 00:00:00 2001 From: A117870935 Date: Sun, 14 May 2023 02:57:18 +0530 Subject: [PATCH] Customized navigation view theme with drawer options. --- .../android/ui/activity/DrawerActivity.java | 236 ++++-------------- .../owncloud/android/utils/StringUtils.java | 30 +++ .../drawable/ic_magentacloud_product_logo.xml | 31 +++ .../drawable/menu_background_color_state.xml | 4 + app/src/main/res/layout/drawer.xml | 40 ++- .../main/res/menu/partial_drawer_entries.xml | 29 ++- app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values-night/colors.xml | 66 +++++ app/src/main/res/values/colors.xml | 91 +++++++ app/src/main/res/values/dimens.xml | 31 +++ app/src/main/res/values/setup.xml | 4 +- app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 6 +- 13 files changed, 369 insertions(+), 205 deletions(-) create mode 100644 app/src/main/res/drawable/ic_magentacloud_product_logo.xml create mode 100644 app/src/main/res/drawable/menu_background_color_state.xml create mode 100644 app/src/main/res/values/dimens.xml diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 9e37e03e0e00..cff9c296fc69 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -36,31 +36,18 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.LayerDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; -import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.webkit.URLUtil; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.bumptech.glide.GenericRequestBuilder; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; -import com.bumptech.glide.load.model.StreamEncoder; -import com.bumptech.glide.load.resource.file.FileToStreamDecoder; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SimpleTarget; import com.google.android.material.button.MaterialButton; @@ -106,14 +93,11 @@ import com.owncloud.android.ui.fragment.SharedListFragment; import com.owncloud.android.ui.preview.PreviewTextStringFragment; import com.owncloud.android.ui.trashbin.TrashbinActivity; -import com.owncloud.android.utils.BitmapUtils; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.DrawerMenuUtil; import com.owncloud.android.utils.FilesSyncHelper; +import com.owncloud.android.utils.StringUtils; import com.owncloud.android.utils.svg.MenuSimpleTarget; -import com.owncloud.android.utils.svg.SVGorImage; -import com.owncloud.android.utils.svg.SvgOrImageBitmapTranscoder; -import com.owncloud.android.utils.svg.SvgOrImageDecoder; import com.owncloud.android.utils.theme.CapabilityUtils; import org.greenrobot.eventbus.EventBus; @@ -121,7 +105,6 @@ import org.greenrobot.eventbus.ThreadMode; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -129,6 +112,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.widget.AppCompatTextView; import androidx.core.content.ContextCompat; import androidx.core.content.res.ResourcesCompat; import androidx.core.view.GravityCompat; @@ -167,11 +151,6 @@ public abstract class DrawerActivity extends ToolbarActivity */ private NavigationView mNavigationView; - /** - * Reference to the navigation view header. - */ - private View mNavigationViewHeader; - /** * Flag to signal if the account chooser is active. */ @@ -197,6 +176,7 @@ public abstract class DrawerActivity extends ToolbarActivity */ private TextView mQuotaTextPercentage; private TextView mQuotaTextLink; + private AppCompatTextView mQuotaTextUsage; /** * runnable that will be executed after the drawer has been closed. @@ -232,10 +212,6 @@ protected void setupDrawer() { mNavigationView = findViewById(R.id.nav_view); if (mNavigationView != null) { - // Setting up drawer header - mNavigationViewHeader = mNavigationView.getHeaderView(0); - updateHeader(); - setupDrawerMenu(mNavigationView); getAndDisplayUserQuota(); setupQuotaElement(); @@ -294,147 +270,9 @@ private void setupQuotaElement() { mQuotaView = (LinearLayout) findQuotaViewById(R.id.drawer_quota); mQuotaProgressBar = (LinearProgressIndicator) findQuotaViewById(R.id.drawer_quota_ProgressBar); mQuotaTextPercentage = (TextView) findQuotaViewById(R.id.drawer_quota_percentage); + mQuotaTextUsage = (AppCompatTextView) mNavigationView.findViewById(R.id.drawer_quota_usage); mQuotaTextLink = (TextView) findQuotaViewById(R.id.drawer_quota_link); - viewThemeUtils.material.colorProgressBar(mQuotaProgressBar); - } - - public void updateHeader() { - if (getAccount() != null && - getCapabilities().getServerBackground() != null) { - - OCCapability capability = getCapabilities(); - String logo = capability.getServerLogo(); - int primaryColor = themeColorUtils.unchangedPrimaryColor(getAccount(), this); - - // set background to primary color - LinearLayout drawerHeader = mNavigationViewHeader.findViewById(R.id.drawer_header_view); - drawerHeader.setBackgroundColor(primaryColor); - - if (!TextUtils.isEmpty(logo) && URLUtil.isValidUrl(logo)) { - // background image - GenericRequestBuilder requestBuilder = Glide.with(this) - .using(Glide.buildStreamModelLoader(Uri.class, this), InputStream.class) - .from(Uri.class) - .as(SVGorImage.class) - .transcode(new SvgOrImageBitmapTranscoder(128, 128), Bitmap.class) - .sourceEncoder(new StreamEncoder()) - .cacheDecoder(new FileToStreamDecoder<>(new SvgOrImageDecoder())) - .decoder(new SvgOrImageDecoder()); - - // background image - SimpleTarget target = new SimpleTarget<>() { - @Override - public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) { - - Bitmap logo = resource; - int width = resource.getWidth(); - int height = resource.getHeight(); - int max = Math.max(width, height); - if (max > MAX_LOGO_SIZE_PX) { - logo = BitmapUtils.scaleBitmap(resource, MAX_LOGO_SIZE_PX, width, height, max); - } - - Drawable[] drawables = {new ColorDrawable(primaryColor), - new BitmapDrawable(getResources(), logo)}; - LayerDrawable layerDrawable = new LayerDrawable(drawables); - - String name = capability.getServerName(); - setDrawerHeaderLogo(layerDrawable, name); - } - }; - - requestBuilder - .diskCacheStrategy(DiskCacheStrategy.SOURCE) - .load(Uri.parse(logo)) - .into(target); - } - - // hide ecosystem apps according to user preference or in branded client - LinearLayout ecosystemApps = mNavigationViewHeader.findViewById(R.id.drawer_ecosystem_apps); - if (getResources().getBoolean(R.bool.is_branded_client) || !preferences.isShowEcosystemApps()) { - ecosystemApps.setVisibility(View.GONE); - } else { - LinearLayout[] views = { - ecosystemApps.findViewById(R.id.drawer_ecosystem_notes), - ecosystemApps.findViewById(R.id.drawer_ecosystem_talk), - ecosystemApps.findViewById(R.id.drawer_ecosystem_more) - }; - - views[0].setOnClickListener(v -> openAppOrStore("it.niedermann.owncloud.notes")); - views[1].setOnClickListener(v -> openAppOrStore("com.nextcloud.talk2")); - views[2].setOnClickListener(v -> openAppStore("Nextcloud", true)); - - int iconColor; - if (Hct.fromInt(primaryColor).getTone() < 80.0) { - iconColor = Color.WHITE; - } else { - iconColor = getColor(R.color.grey_800_transparent); - } - for (LinearLayout view : views) { - ImageView imageView = (ImageView) view.getChildAt(0); - imageView.setImageTintList(ColorStateList.valueOf(iconColor)); - GradientDrawable background = (GradientDrawable) imageView.getBackground(); - background.setStroke(DisplayUtils.convertDpToPixel(1, this), iconColor); - TextView textView = (TextView) view.getChildAt(1); - textView.setTextColor(iconColor); - } - - ecosystemApps.setVisibility(View.VISIBLE); - } - } - } - - /** - * Open specified app and, if not installed redirect to corresponding download. - * - * @param packageName of app to be opened - */ - private void openAppOrStore(String packageName) { - Intent intent = getPackageManager().getLaunchIntentForPackage(packageName); - if (intent != null) { - // app installed - open directly - intent.putExtra(FileDisplayActivity.KEY_ACCOUNT, getUser().get().hashCode()); - startActivity(intent); - } else { - // app not found - open market (Google Play Store, F-Droid, etc.) - openAppStore(packageName, false); - } - } - - /** - * Open app store page of specified app or search for specified string. - * Will attempt to open browser when no app store is available. - * - * @param string packageName or url-encoded search string - * @param search false -> show app corresponding to packageName; true -> open search for string - */ - private void openAppStore(String string, boolean search) { - String suffix = (search ? "search?q=" : "details?id=") + string; - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://" + suffix)); - try { - startActivity(intent); - } catch (android.content.ActivityNotFoundException activityNotFoundException1) { - // all is lost: open google play store web page for app - if (!search) { - suffix = "apps/" + suffix; - } - intent.setData(Uri.parse("https://play.google.com/store/" + suffix)); - startActivity(intent); - } - } - - private void setDrawerHeaderLogo(Drawable drawable, String serverName) { - ImageView imageHeader = mNavigationViewHeader.findViewById(R.id.drawer_header_logo); - imageHeader.setImageDrawable(drawable); - imageHeader.setAdjustViewBounds(true); - - if (!TextUtils.isEmpty(serverName)) { - TextView serverNameView = mNavigationViewHeader.findViewById(R.id.drawer_header_server_name); - serverNameView.setVisibility(View.VISIBLE); - serverNameView.setText(serverName); - serverNameView.setTextColor(themeColorUtils.unchangedFontColor(this)); - } - + viewThemeUtils.material.colorProgressBar(mQuotaProgressBar, getResources().getColor(R.color.primary)); } /** @@ -462,7 +300,9 @@ private void filterDrawerMenu(final Menu menu, @NonNull final User user) { OCCapability capability = getCapabilities(); DrawerMenuUtil.filterSearchMenuItems(menu, user, getResources()); - DrawerMenuUtil.filterTrashbinMenuItem(menu, capability); + //trashbin icon is depending on capability due to this it doesn't appear in some of the devices + //so removing the check as we need this option always + //DrawerMenuUtil.filterTrashbinMenuItem(menu, capability); DrawerMenuUtil.filterActivityMenuItem(menu, capability); DrawerMenuUtil.filterGroupfoldersMenuItem(menu, capability); @@ -744,21 +584,20 @@ private void showQuota(boolean showQuota) { * @param quotaValue {@link GetUserInfoRemoteOperation#SPACE_UNLIMITED} or other to determinate state */ private void setQuotaInformation(long usedSpace, long totalSpace, int relative, long quotaValue) { - if (GetUserInfoRemoteOperation.SPACE_UNLIMITED == quotaValue) { - mQuotaTextPercentage.setText(String.format( - getString(R.string.drawer_quota_unlimited), - DisplayUtils.bytesToHumanReadable(usedSpace))); - } else { - mQuotaTextPercentage.setText(String.format( - getString(R.string.drawer_quota), - DisplayUtils.bytesToHumanReadable(usedSpace), - DisplayUtils.bytesToHumanReadable(totalSpace))); - } + String usageText = String.format( + getString(R.string.drawer_quota_usage), + DisplayUtils.bytesToHumanReadable(usedSpace), + DisplayUtils.bytesToHumanReadable(totalSpace)); + + mQuotaTextUsage.setText(StringUtils.makeTextBold(usageText, DisplayUtils.bytesToHumanReadable(usedSpace))); mQuotaProgressBar.setProgress(relative); + mQuotaTextPercentage.setText(String.format( + getString(R.string.drawer_quota_percentage), relative)); + if (relative < RELATIVE_THRESHOLD_WARNING) { - viewThemeUtils.material.colorProgressBar(mQuotaProgressBar); + viewThemeUtils.material.colorProgressBar(mQuotaProgressBar, getResources().getColor(R.color.primary)); } else { viewThemeUtils.material.colorProgressBar(mQuotaProgressBar, getResources().getColor(R.color.infolevel_warning, getTheme())); @@ -844,10 +683,43 @@ public void onLoadFailed(Exception e, Drawable errorDrawable) { * @param menuItemId the menu item to be highlighted */ protected void setDrawerMenuItemChecked(int menuItemId) { + //NMC customisation + //if item is logout then do not show it as selected + if (menuItemId == R.id.nav_logout) { + //if previous checked item is not NONE then make it selected again + //to show it as selected bg color + if (mCheckedMenuItem != Menu.NONE) { + setDrawerMenuItemChecked(mCheckedMenuItem); + } + return; + } + if (mNavigationView != null && mNavigationView.getMenu().findItem(menuItemId) != null) { - viewThemeUtils.platform.colorNavigationView(mNavigationView); mCheckedMenuItem = menuItemId; - mNavigationView.getMenu().findItem(menuItemId).setChecked(true); + + //for NMC customization + MenuItem currentItem = mNavigationView.getMenu().findItem(menuItemId); + int drawerDefaultTxtColor = getResources().getColor(R.color.nav_txt_unselected_color); + int drawerActiveTxtColor = getResources().getColor(R.color.nav_txt_selected_color); + + int drawerDefaultIconColor = getResources().getColor(R.color.nav_icon_unselected_color); + int drawerActiveIconColor = getResources().getColor(R.color.nav_icon_selected_color); + + currentItem.setChecked(true); + + // For each menu item, change the color of the selected item, and of the other items + for (int i = 0; i < mNavigationView.getMenu().size(); i++) { + MenuItem menuItem = mNavigationView.getMenu().getItem(i); + if (menuItem.getIcon() != null) { + if (menuItem == currentItem) { + viewThemeUtils.platform.colorDrawable(currentItem.getIcon(), drawerActiveIconColor); + currentItem.setTitle(StringUtils.getColorSpan(currentItem.getTitle().toString(), drawerActiveTxtColor)); + } else { + viewThemeUtils.platform.colorDrawable(menuItem.getIcon(), drawerDefaultIconColor); + menuItem.setTitle(StringUtils.getColorSpan(menuItem.getTitle().toString(), drawerDefaultTxtColor)); + } + } + } } else { Log_OC.w(TAG, "setDrawerMenuItemChecked has been called with invalid menu-item-ID"); } @@ -1078,7 +950,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { * @return The view if found or null otherwise. */ private View findQuotaViewById(int id) { - View v = ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0).findViewById(id); + View v = ((NavigationView) findViewById(R.id.nav_view)).findViewById(id); if (v != null) { return v; diff --git a/app/src/main/java/com/owncloud/android/utils/StringUtils.java b/app/src/main/java/com/owncloud/android/utils/StringUtils.java index 5c6871dcab73..6c459423bdcf 100644 --- a/app/src/main/java/com/owncloud/android/utils/StringUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/StringUtils.java @@ -21,7 +21,13 @@ package com.owncloud.android.utils; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; + import java.util.Locale; +import android.graphics.Typeface; +import android.text.style.StyleSpan; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,6 +75,15 @@ String searchAndColor(@Nullable String text, @Nullable String searchText, } } + public static Spannable getColorSpan(@NonNull String title, @ColorInt int color) { + Spannable text = new SpannableString(title); + text.setSpan(new ForegroundColorSpan(color), + 0, + text.length(), + Spannable.SPAN_INCLUSIVE_INCLUSIVE); + return text; + } + public static @NonNull String removePrefix(@NonNull String s, @NonNull String prefix) { @@ -77,4 +92,19 @@ String removePrefix(@NonNull String s, @NonNull String prefix) { } return s; } + + /** + * make the passed text bold + * + * @param fullText actual text + * @param textToBold to be bold + * @return + */ + public static Spannable makeTextBold(String fullText, String textToBold) { + Spannable spannable = new SpannableString(fullText); + int indexStart = fullText.indexOf(textToBold); + int indexEnd = indexStart + textToBold.length(); + spannable.setSpan(new StyleSpan(Typeface.BOLD), indexStart, indexEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return spannable; + } } diff --git a/app/src/main/res/drawable/ic_magentacloud_product_logo.xml b/app/src/main/res/drawable/ic_magentacloud_product_logo.xml new file mode 100644 index 000000000000..287fc029a729 --- /dev/null +++ b/app/src/main/res/drawable/ic_magentacloud_product_logo.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/menu_background_color_state.xml b/app/src/main/res/drawable/menu_background_color_state.xml new file mode 100644 index 000000000000..1aee89b3ea28 --- /dev/null +++ b/app/src/main/res/drawable/menu_background_color_state.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/layout/drawer.xml b/app/src/main/res/layout/drawer.xml index 14728bb81357..255bd314ddfb 100644 --- a/app/src/main/res/layout/drawer.xml +++ b/app/src/main/res/layout/drawer.xml @@ -23,15 +23,14 @@ + + + + + android:drawablePadding="@dimen/alternate_half_padding" + android:visibility="gone" /> @@ -70,9 +92,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="@dimen/alternate_half_padding" - android:fontFamily="sans-serif-medium" + android:paddingLeft="@dimen/standard_padding" + android:paddingRight="@dimen/standard_padding" android:text="@string/drawer_quota" - android:textColor="@color/drawer_text_color" /> + android:textColor="@color/drawer_quota_txt_color" + android:textSize="@dimen/txt_size_14sp" /> diff --git a/app/src/main/res/menu/partial_drawer_entries.xml b/app/src/main/res/menu/partial_drawer_entries.xml index 246e19c9802f..21834fdcc0f4 100644 --- a/app/src/main/res/menu/partial_drawer_entries.xml +++ b/app/src/main/res/menu/partial_drawer_entries.xml @@ -32,6 +32,7 @@ android:title="@string/drawer_item_all_files"/> + android:title="@string/drawer_item_recent_files" + android:visible="false"/> + + + + #1E1E1E @android:color/white + + + #FFFFFF + @color/grey_30 + @color/grey_30 + #CCCCCC + @color/grey_70 + @color/grey_80 + #2D2D2D + @color/grey_70 + @color/grey_70 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_60 + @color/grey_0 + @color/grey_0 + @color/grey_30 + #FFFFFF + @color/grey_30 + @color/grey_80 + #FFFFFF + + + @color/grey_80 + @color/grey_30 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + @color/grey_80 + + + @color/grey_70 + @color/grey_60 + @color/grey_70 + @color/grey_60 + + + @color/grey_70 + @color/grey_70 + + + #FFFFFF + @color/grey_30 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_60 + @color/grey_0 + #FFFFFF + + + #121212 + @color/grey_0 + @color/grey_80 + @color/grey_80 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index d72d9d458f83..0ae14280757c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -80,4 +80,95 @@ @android:color/white #666666 #A5A5A5 + + + #191919 + @color/primary + #191919 + #191919 + @color/grey_30 + @android:color/white + #FFFFFF + @color/grey_0 + #CCCCCC + #77c4ff + #B3FFFFFF + @color/grey_10 + + + #101010 + #F2F2F2 + #E5E5E5 + #B2B2B2 + #666666 + #4C4C4C + #333333 + + + @color/design_snackbar_background_color + @color/white + + + #FFFFFF + #191919 + + + @color/grey_0 + #191919 + @color/primary + #191919 + @color/primary + @color/grey_30 + @color/white + #191919 + + + #FFFFFF + #191919 + #191919 + + + #FFFFFF + #191919 + #FFFFFF + + + @color/primary + #F399C7 + @color/grey_0 + @color/grey_0 + #FFFFFF + @color/grey_30 + @color/grey_0 + @color/grey_0 + + + @color/primary + @color/grey_30 + @color/grey_30 + #CCCCCC + + + #191919 + @color/grey_30 + #191919 + #191919 + #191919 + #191919 + @color/grey_30 + #191919 + #000000 + #191919 + #F6E5EB + #C16F81 + #0D39DF + #0099ff + + + @color/grey_0 + #191919 + @color/grey_0 + @color/grey_30 + #77b6bb + #5077b6bb diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000000..cc9e25255a10 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,31 @@ + + + 4dp + 16dp + 24dp + 6dp + 18sp + 15sp + 15dp + 56dp + 86dp + 80dp + 11sp + 30dp + 55dp + 258dp + 17sp + 20dp + 160dp + 50dp + 150dp + 55dp + 48dp + 48dp + 24dp + 26dp + 20sp + 145dp + 1dp + 13sp + \ No newline at end of file diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index 1d3150de76d6..c6ddef59e178 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -58,7 +58,7 @@ false true - false + true true @@ -91,7 +91,7 @@ - true + false https://f-droid.org/repository/browse/?fdid=com.nextcloud.android.beta https://download.nextcloud.com/android/dev/latest.apk diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8fc1cbc3cd8b..e436197bd9df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,8 +29,11 @@ Notifications %1$s of %2$s used %1$s used + %d %% Storage used + %1$s of %2$s Close sidebar Open sidebar + Recent files General More Manage accounts diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 400b7bb7d326..1f44e3e21ee5 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -320,7 +320,11 @@ end @color/transparent - @color/drawer_active_item_background + @color/text_color + + +