mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	* feat: locked/private view * feat: locked/private view * feat: mobile lock/private view * feat: mobile lock/private view * merge main * pr feedback * pr feedback * bottom sheet sizing * always lock when navigating away
		
			
				
	
	
		
			221 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:immich_mobile/constants/locales.dart';
 | 
						|
import 'package:immich_mobile/extensions/theme_extensions.dart';
 | 
						|
 | 
						|
class ImmichTheme {
 | 
						|
  final ColorScheme light;
 | 
						|
  final ColorScheme dark;
 | 
						|
 | 
						|
  const ImmichTheme({required this.light, required this.dark});
 | 
						|
}
 | 
						|
 | 
						|
ThemeData getThemeData({
 | 
						|
  required ColorScheme colorScheme,
 | 
						|
  required Locale locale,
 | 
						|
}) {
 | 
						|
  final isDark = colorScheme.brightness == Brightness.dark;
 | 
						|
 | 
						|
  return ThemeData(
 | 
						|
    useMaterial3: true,
 | 
						|
    brightness: colorScheme.brightness,
 | 
						|
    colorScheme: colorScheme,
 | 
						|
    primaryColor: colorScheme.primary,
 | 
						|
    hintColor: colorScheme.onSurfaceSecondary,
 | 
						|
    focusColor: colorScheme.primary,
 | 
						|
    scaffoldBackgroundColor: colorScheme.surface,
 | 
						|
    splashColor: colorScheme.primary.withValues(alpha: 0.1),
 | 
						|
    highlightColor: colorScheme.primary.withValues(alpha: 0.1),
 | 
						|
    bottomSheetTheme: BottomSheetThemeData(
 | 
						|
      backgroundColor: colorScheme.surfaceContainer,
 | 
						|
    ),
 | 
						|
    fontFamily: _getFontFamilyFromLocale(locale),
 | 
						|
    snackBarTheme: SnackBarThemeData(
 | 
						|
      contentTextStyle: TextStyle(
 | 
						|
        fontFamily: _getFontFamilyFromLocale(locale),
 | 
						|
        color: colorScheme.primary,
 | 
						|
        fontWeight: FontWeight.bold,
 | 
						|
      ),
 | 
						|
      backgroundColor: colorScheme.surfaceContainerHighest,
 | 
						|
    ),
 | 
						|
    appBarTheme: AppBarTheme(
 | 
						|
      titleTextStyle: TextStyle(
 | 
						|
        color: colorScheme.primary,
 | 
						|
        fontFamily: _getFontFamilyFromLocale(locale),
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
        fontSize: 18,
 | 
						|
      ),
 | 
						|
      backgroundColor:
 | 
						|
          isDark ? colorScheme.surfaceContainer : colorScheme.surface,
 | 
						|
      foregroundColor: colorScheme.primary,
 | 
						|
      elevation: 0,
 | 
						|
      scrolledUnderElevation: 0,
 | 
						|
      centerTitle: true,
 | 
						|
    ),
 | 
						|
    textTheme: const TextTheme(
 | 
						|
      displayLarge: TextStyle(
 | 
						|
        fontSize: 18,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
      displayMedium: TextStyle(
 | 
						|
        fontSize: 14,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
      displaySmall: TextStyle(
 | 
						|
        fontSize: 12,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
      titleSmall: TextStyle(
 | 
						|
        fontSize: 16.0,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
      titleMedium: TextStyle(
 | 
						|
        fontSize: 18.0,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
      titleLarge: TextStyle(
 | 
						|
        fontSize: 26.0,
 | 
						|
        fontWeight: FontWeight.w600,
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    elevatedButtonTheme: ElevatedButtonThemeData(
 | 
						|
      style: ElevatedButton.styleFrom(
 | 
						|
        backgroundColor: colorScheme.primary,
 | 
						|
        foregroundColor: isDark ? Colors.black87 : Colors.white,
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    chipTheme: const ChipThemeData(
 | 
						|
      side: BorderSide.none,
 | 
						|
    ),
 | 
						|
    sliderTheme: const SliderThemeData(
 | 
						|
      thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
 | 
						|
      trackHeight: 2.0,
 | 
						|
    ),
 | 
						|
    bottomNavigationBarTheme: const BottomNavigationBarThemeData(
 | 
						|
      type: BottomNavigationBarType.fixed,
 | 
						|
    ),
 | 
						|
    popupMenuTheme: const PopupMenuThemeData(
 | 
						|
      shape: RoundedRectangleBorder(
 | 
						|
        borderRadius: BorderRadius.all(Radius.circular(10)),
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    navigationBarTheme: NavigationBarThemeData(
 | 
						|
      backgroundColor:
 | 
						|
          isDark ? colorScheme.surfaceContainer : colorScheme.surface,
 | 
						|
      labelTextStyle: const WidgetStatePropertyAll(
 | 
						|
        TextStyle(
 | 
						|
          fontSize: 14,
 | 
						|
          fontWeight: FontWeight.w500,
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    inputDecorationTheme: InputDecorationTheme(
 | 
						|
      focusedBorder: OutlineInputBorder(
 | 
						|
        borderSide: BorderSide(
 | 
						|
          color: colorScheme.primary,
 | 
						|
        ),
 | 
						|
        borderRadius: const BorderRadius.all(Radius.circular(15)),
 | 
						|
      ),
 | 
						|
      enabledBorder: OutlineInputBorder(
 | 
						|
        borderSide: BorderSide(
 | 
						|
          color: colorScheme.outlineVariant,
 | 
						|
        ),
 | 
						|
        borderRadius: const BorderRadius.all(Radius.circular(15)),
 | 
						|
      ),
 | 
						|
      labelStyle: TextStyle(
 | 
						|
        color: colorScheme.primary,
 | 
						|
      ),
 | 
						|
      hintStyle: const TextStyle(
 | 
						|
        fontSize: 14.0,
 | 
						|
        fontWeight: FontWeight.normal,
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    textSelectionTheme: TextSelectionThemeData(
 | 
						|
      cursorColor: colorScheme.primary,
 | 
						|
    ),
 | 
						|
    dropdownMenuTheme: DropdownMenuThemeData(
 | 
						|
      menuStyle: const MenuStyle(
 | 
						|
        shape: WidgetStatePropertyAll<OutlinedBorder>(
 | 
						|
          RoundedRectangleBorder(
 | 
						|
            borderRadius: BorderRadius.all(Radius.circular(15)),
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
      inputDecorationTheme: InputDecorationTheme(
 | 
						|
        focusedBorder: OutlineInputBorder(
 | 
						|
          borderSide: BorderSide(
 | 
						|
            color: colorScheme.primary,
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
        enabledBorder: OutlineInputBorder(
 | 
						|
          borderSide: BorderSide(
 | 
						|
            color: colorScheme.outlineVariant,
 | 
						|
          ),
 | 
						|
          borderRadius: const BorderRadius.all(Radius.circular(15)),
 | 
						|
        ),
 | 
						|
        labelStyle: TextStyle(
 | 
						|
          color: colorScheme.primary,
 | 
						|
        ),
 | 
						|
        hintStyle: const TextStyle(
 | 
						|
          fontSize: 14.0,
 | 
						|
          fontWeight: FontWeight.normal,
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    ),
 | 
						|
    dialogTheme: DialogThemeData(backgroundColor: colorScheme.surfaceContainer),
 | 
						|
    progressIndicatorTheme: const ProgressIndicatorThemeData(
 | 
						|
      // ignore: deprecated_member_use
 | 
						|
      year2023: false,
 | 
						|
      // TODO: Uncommented after upgrade to version later than 3.29.2
 | 
						|
      // circularTrackColor: Colors.black12,
 | 
						|
      trackGap: 3,
 | 
						|
    ),
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// This method replaces all surface shades in ImmichTheme to a static ones
 | 
						|
// as we are creating the colorscheme through seedColor the default surfaces are
 | 
						|
// tinted with primary color
 | 
						|
ImmichTheme decolorizeSurfaces({
 | 
						|
  required ImmichTheme theme,
 | 
						|
}) {
 | 
						|
  return ImmichTheme(
 | 
						|
    light: theme.light.copyWith(
 | 
						|
      surface: const Color(0xFFf9f9f9),
 | 
						|
      onSurface: const Color(0xFF1b1b1b),
 | 
						|
      surfaceContainerLowest: const Color(0xFFffffff),
 | 
						|
      surfaceContainerLow: const Color(0xFFf3f3f3),
 | 
						|
      surfaceContainer: const Color(0xFFeeeeee),
 | 
						|
      surfaceContainerHigh: const Color(0xFFe8e8e8),
 | 
						|
      surfaceContainerHighest: const Color(0xFFe2e2e2),
 | 
						|
      surfaceDim: const Color(0xFFdadada),
 | 
						|
      surfaceBright: const Color(0xFFf9f9f9),
 | 
						|
      onSurfaceVariant: const Color(0xFF4c4546),
 | 
						|
      inverseSurface: const Color(0xFF303030),
 | 
						|
      onInverseSurface: const Color(0xFFf1f1f1),
 | 
						|
    ),
 | 
						|
    dark: theme.dark.copyWith(
 | 
						|
      surface: const Color(0xFF131313),
 | 
						|
      onSurface: const Color(0xFFE2E2E2),
 | 
						|
      surfaceContainerLowest: const Color(0xFF0E0E0E),
 | 
						|
      surfaceContainerLow: const Color(0xFF1B1B1B),
 | 
						|
      surfaceContainer: const Color(0xFF1F1F1F),
 | 
						|
      surfaceContainerHigh: const Color(0xFF242424),
 | 
						|
      surfaceContainerHighest: const Color(0xFF2E2E2E),
 | 
						|
      surfaceDim: const Color(0xFF131313),
 | 
						|
      surfaceBright: const Color(0xFF353535),
 | 
						|
      onSurfaceVariant: const Color(0xFFCfC4C5),
 | 
						|
      inverseSurface: const Color(0xFFE2E2E2),
 | 
						|
      onInverseSurface: const Color(0xFF303030),
 | 
						|
    ),
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
String? _getFontFamilyFromLocale(Locale locale) {
 | 
						|
  if (localesNotSupportedByOverpass.contains(locale)) {
 | 
						|
    // Let Flutter use the default font
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
  return 'Overpass';
 | 
						|
}
 |