Skip to content

Commit

Permalink
use android Material3 system primaryColor
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVe committed Oct 19, 2023
1 parent 8d1e6d8 commit da0655a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import com.google.android.material.color.DynamicColors
import com.yubico.authenticator.logging.FlutterLog
import com.yubico.authenticator.oath.AppLinkMethodChannel
import com.yubico.authenticator.oath.OathManager
Expand Down Expand Up @@ -383,6 +384,11 @@ class MainActivity : FlutterFragmentActivity() {
methodCall.arguments as Boolean,
)
)

"getAndroidDynamicPrimaryColor" -> result.success(
getDynamicPrimaryColor(this@MainActivity)
)

"getAndroidSdkVersion" -> result.success(
Build.VERSION.SDK_INT
)
Expand Down Expand Up @@ -448,6 +454,25 @@ class MainActivity : FlutterFragmentActivity() {
return FLAG_SECURE != (window.attributes.flags and FLAG_SECURE)
}

private fun getDynamicPrimaryColor(context: Context): Int {
if (DynamicColors.isDynamicColorAvailable()) {
val dynamicColorContext = DynamicColors.wrapContextIfAvailable(
context,
com.google.android.material.R.style.ThemeOverlay_Material3_DynamicColors_DayNight
)

val typedArray = dynamicColorContext.obtainStyledAttributes(
intArrayOf(
android.R.attr.colorPrimary,
)
)
val primary = typedArray.getColor(0, 0)
typedArray.recycle()
return primary;
}
return 0
}

@SuppressLint("SourceLockedOrientationActivity")
private fun forcePortraitOrientation() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
Expand Down
5 changes: 5 additions & 0 deletions lib/android/app_methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ Future<int> getAndroidSdkVersion() async {
return await appMethodsChannel.invokeMethod('getAndroidSdkVersion');
}

Future<int> getAndroidDynamicPrimaryColor() async {
final color = await appMethodsChannel.invokeMethod('getAndroidDynamicPrimaryColor');
return color;
}

Future<void> setPrimaryClip(String toClipboard, bool isSensitive) async {
await appMethodsChannel.invokeMethod('setPrimaryClip',
{'toClipboard': toClipboard, 'isSensitive': isSensitive});
Expand Down
3 changes: 2 additions & 1 deletion lib/android/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ Future<Widget> initialize() async {
supportedThemesProvider
.overrideWith(
(ref) => ref.watch(androidSupportedThemesProvider),
)
),
systemPrimaryColorProvider.overrideWithValue(Color(await getAndroidDynamicPrimaryColor())),
],
child: DismissKeyboard(
child: YubicoAuthenticatorApp(page: Consumer(
Expand Down
39 changes: 24 additions & 15 deletions lib/app/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,35 +121,44 @@ class ThemeModeNotifier extends StateNotifier<ThemeMode> {
orElse: () => supportedThemes.first);
}

final systemPrimaryColorProvider = Provider<Color?>((ref) => null);

final darkThemeDataProvider =
StateNotifierProvider<ThemeDataNotifier, ThemeData>(
(ref) => ThemeDataNotifier(ThemeMode.dark),
(ref) =>
ThemeDataNotifier(ref.watch(systemPrimaryColorProvider), ThemeMode.dark),
);

final lightThemeDataProvider =
StateNotifierProvider<ThemeDataNotifier, ThemeData>(
(ref) => ThemeDataNotifier(ThemeMode.light),
(ref) =>
ThemeDataNotifier(ref.watch(systemPrimaryColorProvider), ThemeMode.light),
);

class ThemeDataNotifier extends StateNotifier<ThemeData> {
final Color? _systemPrimaryColor;
final ThemeMode _themeMode;

ThemeDataNotifier(this._themeMode) : super(getDefault(_themeMode));
ThemeDataNotifier(this._systemPrimaryColor, this._themeMode)
: super(_get(_systemPrimaryColor, _themeMode));

static ThemeData getDefault(ThemeMode themeMode) =>
static ThemeData _getDefault(ThemeMode themeMode) =>
themeMode == ThemeMode.light ? AppTheme.lightTheme : AppTheme.darkTheme;

void setPrimaryColor(Color? color) {
_log.debug('Set primary color to $color');
state = (color != null)
? getDefault(_themeMode).copyWith(
colorScheme: ColorScheme.fromSeed(
brightness: _themeMode == ThemeMode.dark
? Brightness.dark
: Brightness.light,
seedColor: color)
.copyWith(primary: color))
: getDefault(_themeMode);
static ThemeData _get(Color? primaryColor, ThemeMode themeMode) =>
(primaryColor != null)
? _getDefault(themeMode).copyWith(
colorScheme: ColorScheme.fromSeed(
brightness: themeMode == ThemeMode.dark
? Brightness.dark
: Brightness.light,
seedColor: primaryColor)
.copyWith(primary: primaryColor))
: _getDefault(themeMode);

void setPrimaryColor(Color? primaryColor) {
_log.debug('Set primary color to $primaryColor');
state = _get(primaryColor, _themeMode);
}
}

Expand Down

0 comments on commit da0655a

Please sign in to comment.