Skip to content

Commit

Permalink
More dark mode refinements
Browse files Browse the repository at this point in the history
- Tweak service dark colors
- Alter image brightness in grid
- Use setDefaultNightMode
- Fix DN login
  • Loading branch information
nickbutcher committed Apr 26, 2019
1 parent f4b81ab commit e85e17d
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 68 deletions.
28 changes: 13 additions & 15 deletions app/src/main/java/io/plaidapp/ui/HomeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
Expand Down Expand Up @@ -97,7 +97,7 @@

import static io.plaidapp.dagger.Injector.inject;

public class HomeActivity extends FragmentActivity {
public class HomeActivity extends AppCompatActivity {

private static final int RC_SEARCH = 0;
private static final int RC_NEW_DESIGNER_NEWS_STORY = 4;
Expand Down Expand Up @@ -140,7 +140,7 @@ protected void onCreate(Bundle savedInstanceState) {

inject(this);

adapter = new FeedAdapter(this, columns, pocketInstalled);
adapter = new FeedAdapter(this, columns, pocketInstalled, ColorUtils.isNightMode(this));

if (connectivityChecker != null) {
getLifecycle().addObserver(connectivityChecker);
Expand Down Expand Up @@ -185,7 +185,7 @@ protected void onCreate(Bundle savedInstanceState) {
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

setActionBar(toolbar);
setupToolbar();
if (savedInstanceState == null) {
animateToolbar();
}
Expand Down Expand Up @@ -347,26 +347,24 @@ public void onLayoutChange(View v, int l, int t, int r, int b,
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
final MenuItem toggleTheme = menu.findItem(R.id.menu_theme);
private void setupToolbar() {
toolbar.inflateMenu(R.menu.main);
final MenuItem toggleTheme = toolbar.getMenu().findItem(R.id.menu_theme);
final View actionView = toggleTheme.getActionView();
if (actionView instanceof CheckBox) {
final CheckBox toggle = (CheckBox) actionView;
toggle.setButtonDrawable(R.drawable.asl_theme);
toggle.setChecked(
AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);
toggle.setChecked(ColorUtils.isNightMode(this));
toggle.setOnCheckedChangeListener((buttonView, isChecked) -> {
AppCompatDelegate.setDefaultNightMode(isChecked ?
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
// delay to allow the toggle anim to run
toggle.postDelayed(() -> {
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
recreate();
AppCompatDelegate.setDefaultNightMode(isChecked ?
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
getDelegate().applyDayNight();
}, 800L);
});
}
return true;
setActionBar(toolbar);
}

@Override
Expand Down
10 changes: 8 additions & 2 deletions app/src/main/java/io/plaidapp/ui/PlaidApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package io.plaidapp.ui
import android.app.Activity
import android.app.Application
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
import io.plaidapp.core.dagger.CoreComponent
import io.plaidapp.core.dagger.DaggerCoreComponent

Expand All @@ -27,9 +29,13 @@ import io.plaidapp.core.dagger.DaggerCoreComponent
*/
class PlaidApplication : Application() {

override fun onCreate() {
super.onCreate()
setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM)
}

private val coreComponent: CoreComponent by lazy {
DaggerCoreComponent
.create()
DaggerCoreComponent.create()
}

companion object {
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/drawable/dialog_background.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dialog_corners" />
<solid android:color="@color/background_light" />
</shape>
<solid android:color="?attr/colorSurface" />
</shape>
7 changes: 4 additions & 3 deletions core/src/main/java/io/plaidapp/core/feed/FeedAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class FeedAdapter(
// we need to hold on to an activity ref for the shared element transitions :/
private val host: Activity,
private val columns: Int,
private val pocketIsInstalled: Boolean
private val pocketIsInstalled: Boolean,
private val isNightMode: Boolean
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), ListPreloader.PreloadModelProvider<Shot> {
private val layoutInflater: LayoutInflater = LayoutInflater.from(host)
private val shotLoadingPlaceholders: Array<ColorDrawable?>
Expand Down Expand Up @@ -203,8 +204,8 @@ class FeedAdapter(
private fun createDribbbleShotHolder(parent: ViewGroup): DribbbleShotHolder {
return DribbbleShotHolder(
layoutInflater.inflate(R.layout.dribbble_shot_item, parent, false),
initialGifBadgeColor
) { view, position ->
initialGifBadgeColor,
isNightMode) { view, position ->
val intent = intentTo(Activities.Dribbble.Shot)
intent.putExtra(
Activities.Dribbble.Shot.EXTRA_SHOT_ID,
Expand Down
40 changes: 28 additions & 12 deletions core/src/main/java/io/plaidapp/core/ui/DribbbleShotHolder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package io.plaidapp.core.ui
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.drawable.Drawable
import android.view.MotionEvent
Expand All @@ -31,9 +32,12 @@ import io.plaidapp.core.util.AnimUtils
import io.plaidapp.core.util.ObservableColorMatrix
import io.plaidapp.core.util.asGif

private const val NIGHT_MODE_RGB_SCALE = 0.85f

class DribbbleShotHolder constructor(
itemView: View,
private val initialGifBadgeColor: Int,
private val isNightMode: Boolean,
private val onItemClicked: (image: View, position: Int) -> Unit
) : RecyclerView.ViewHolder(itemView) {

Expand All @@ -49,21 +53,23 @@ class DribbbleShotHolder constructor(
// check if it's an event we care about, else bail fast
val action = event.action
if (!(action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_CANCEL)) {
action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_CANCEL)
) {
return@setOnTouchListener false
}

// get the image and check if it's an animated GIF
val drawable = image.getDrawable() ?: return@setOnTouchListener false
val drawable = image.drawable ?: return@setOnTouchListener false
val gif = drawable.asGif() ?: return@setOnTouchListener false
// GIF found, start/stop it on press/lift
when (action) {
MotionEvent.ACTION_DOWN -> gif!!.start()
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> gif!!.stop()
MotionEvent.ACTION_DOWN -> gif.start()
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> gif.stop()
}
return@setOnTouchListener false
}
darkenImage()
}

fun reset() {
Expand All @@ -75,20 +81,18 @@ class DribbbleShotHolder constructor(
fun fade() {
image.setHasTransientState(true)
val cm = ObservableColorMatrix()
val saturationAnimator = ObjectAnimator.ofFloat(
cm, ObservableColorMatrix.SATURATION, 0f, 1f)
saturationAnimator.apply {
addUpdateListener { _ ->
// just animating the color matrix does not invalidate the
ObjectAnimator.ofFloat(cm, ObservableColorMatrix.SATURATION, 0f, 1f).apply {
addUpdateListener {
// Setting the saturation overwrites any darkening so need to reapply.
// Just animating the color matrix does not invalidate the
// drawable so need this update listener. Also have to create a
// new CMCF as the matrix is immutable :(
image.colorFilter = ColorMatrixColorFilter(cm)
darkenImage(cm)
}
duration = 2000L
interpolator = AnimUtils.getFastOutSlowInInterpolator(image.context)
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
image.clearColorFilter()
image.setHasTransientState(false)
}
})
Expand All @@ -103,4 +107,16 @@ class DribbbleShotHolder constructor(
this.transitionName = transitionName
}
}

private fun darkenImage(colorMatrix: ColorMatrix = ColorMatrix()) {
if (isNightMode) {
colorMatrix.setScale(
NIGHT_MODE_RGB_SCALE,
NIGHT_MODE_RGB_SCALE,
NIGHT_MODE_RGB_SCALE,
1f
)
}
image.colorFilter = ColorMatrixColorFilter(colorMatrix)
}
}
6 changes: 6 additions & 0 deletions core/src/main/java/io/plaidapp/core/util/ColorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package io.plaidapp.core.util;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
Expand Down Expand Up @@ -172,6 +173,11 @@ public static int getThemeColor(@NonNull Context context, @AttrRes int attrResId
return color;
}

public static boolean isNightMode(@NonNull Context context) {
return (context.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}

@Retention(RetentionPolicy.SOURCE)
@IntDef({IS_LIGHT, IS_DARK, LIGHTNESS_UNKNOWN})
public @interface Lightness {
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
<color name="color_background">#ff292929</color>

<!-- designer news -->
<color name="designer_news">#0d47a1</color> <!-- blue 900 -->-->
<!--<color name="designer_news">#0d47a1</color>--> <!-- blue 900 -->
<color name="designer_news">#003c8f</color>
<color name="designer_news_variant">#0b3c87</color>

<!-- product hunt-->
<color name="product_hunt">#ffbf360c</color> <!--deep orange 900 -->-->
<!--<color name="product_hunt">#ffbf360c</color>--> <!--deep orange 900 -->
<color name="product_hunt">#7f311a</color>

</resources>
22 changes: 9 additions & 13 deletions core/src/main/res/values-w600dp/colors.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Google Inc.
Copyright (c) 2019 Google Inc.
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
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
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.
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.
-->

<resources>

<!-- designer news -->
<color name="designer_news_story_comment_background">@color/background_light</color>
<color name="designer_news_story_comment_background">?attr/colorSurface</color>

</resources>
1 change: 1 addition & 0 deletions core/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<color name="designer_news_secondary">#03a9f4</color> <!--*not* varied in -night -->-->
<color name="designer_news_variant">#039be5</color> <!-- light blue 600 -->
<color name="designer_news_link_highlight">#b303a9f4</color>
<color name="designer_news_story_comment_background">@android:color/transparent</color>

<color name="designer_news_super_dark">#000133</color>

Expand Down
4 changes: 0 additions & 4 deletions core/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@
<dimen name="comment_actions_height">40dp</dimen>
<dimen name="comment_like_margin_adjustment">-8dp</dimen>

<!-- dribbble player -->
<dimen name="large_avatar_size">120dp</dimen> <!-- 2 * actionBarSize - 2 * avatar_padding -->
<dimen name="large_avatar_height">160dp</dimen> <!-- large_avatar_margin + large_avatar_size + avatar_margin -->

<!-- bottom sheet -->
<dimen name="bottom_sheet_width">@dimen/match_parent</dimen>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,12 @@ public class StoryActivity extends AppCompatActivity {

private Story story;

@Inject StoryViewModel viewModel;
@Inject LoginRepository loginRepository;
@Inject Markdown markdown;
@Inject
StoryViewModel viewModel;
@Inject
LoginRepository loginRepository;
@Inject
Markdown markdown;

private CustomTabActivityHelper customTab;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/sign_up"
android:textColor="?android:colorAccent"
android:textColor="?attr/colorSecondary"
android:onClick="@{() -> viewModel.signup()}"
style="@style/Widget.MaterialComponents.Button.TextButton" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:paddingTop="@dimen/designer_news_story_comments_vertical_padding"
android:elevation="@dimen/designer_news_story_comment_elevation"
android:background="?attr/colorSurface"
android:background="@color/designer_news_story_comment_background"
android:orientation="vertical"
android:transitionGroup="false"
android:clipToPadding="false">
Expand Down
15 changes: 11 additions & 4 deletions designernews/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,26 @@

<style name="Plaid.DesignerNews.PostStory">
<item name="android:windowAnimationStyle">@null</item>
<item name="android:statusBarColor">@color/background_super_dark</item>
<item name="android:statusBarColor">@color/background_super_dark</item>
<item name="android:navigationBarColor">@color/background_super_dark</item>
<item name="android:colorControlNormal">@color/hint_disabled_dark</item>
</style>

<style name="TextAppearance.DesignerNewsDescription" parent="@android:style/TextAppearance.Material.Subhead">
<item name="android:textColor">@color/text_secondary_dark</item>
<style name="TextAppearance.DesignerNewsDescription" parent="@style/TextAppearance.MaterialComponents.Subtitle1">
<item name="android:textColor">?android:attr/textColorSecondary</item>
<item name="android:letterSpacing">0.01</item>
<item name="lineHeightHint">24sp</item>
</style>

<style name="Widget.Plaid.TextEntry" parent="@style/Widget.MaterialComponents.TextInputLayout.FilledBox">
<item name="boxBackgroundColor">@color/surface_contrast</item>
<item name="materialThemeOverlay">@style/ThemeOverlay.Plaid.TextEntry</item>
</style>

<!-- Set colorPrimary to colorSecondary as this doesn't vary in dark mode
i.e. contrasts on a dark colorSurface-->
<style name="ThemeOverlay.Plaid.TextEntry" parent="@style/ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
<item name="colorPrimary">?attr/colorSecondary</item>
</style>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ class ShotActivity : AppCompatActivity() {
R.layout.activity_dribbble_shot
)

private var largeAvatarSize: Int = 0

private val shotLoadListener = object : RequestListener<Drawable> {
override fun onResourceReady(
resource: Drawable,
Expand Down Expand Up @@ -116,8 +114,6 @@ class ShotActivity : AppCompatActivity() {

inject(shotId)

largeAvatarSize = resources.getDimensionPixelSize(io.plaidapp.R.dimen.large_avatar_size)

binding.viewModel = viewModel.also { vm ->
vm.openLink.observe(this, EventObserver { openLink(it) })
vm.shareShot.observe(this, EventObserver { shareShot(it) })
Expand Down
Loading

0 comments on commit e85e17d

Please sign in to comment.