wip(mobile): unify-colors

This commit is contained in:
shalong-tanwen 2023-11-05 18:27:17 +05:30
parent f6180fccdc
commit d20801c65c
36 changed files with 420 additions and 516 deletions

View file

@ -1,5 +0,0 @@
import 'package:flutter/material.dart';
Color immichBackgroundColor = const Color(0xFFf6f8fe);
Color immichDarkBackgroundColor = const Color.fromARGB(255, 0, 0, 0);
Color immichDarkThemePrimaryColor = const Color.fromARGB(255, 173, 203, 250);

View file

@ -28,25 +28,33 @@ class AlbumThumbnailCard extends StatelessWidget {
var cardSize = constraints.maxWidth;
buildEmptyThumbnail() {
return Container(
return SizedBox(
height: cardSize,
width: cardSize,
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
),
child: Center(
child: Icon(
Icons.no_photography,
size: cardSize * .15,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Icon(
Icons.no_photography,
size: cardSize * .15,
),
),
),
);
}
buildAlbumThumbnail() => ImmichImage(
album.thumbnail.value,
width: cardSize,
height: cardSize,
buildAlbumThumbnail() => Card(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: ImmichImage(
album.thumbnail.value,
width: cardSize,
height: cardSize,
),
);
buildAlbumTextRow() {

View file

@ -21,39 +21,48 @@ class AlbumThumbnailListTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
var cardSize = 68.0;
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
buildEmptyThumbnail() {
return Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
),
child: SizedBox(
height: cardSize,
width: cardSize,
child: const Center(
child: Icon(Icons.no_photography),
return SizedBox(
height: cardSize,
width: cardSize,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Icon(
Icons.no_photography,
size: cardSize * .15,
),
),
),
);
}
buildAlbumThumbnail() {
return CachedNetworkImage(
width: cardSize,
height: cardSize,
fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 200),
imageUrl: getAlbumThumbnailUrl(
album,
type: ThumbnailFormat.JPEG,
return Card(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: CachedNetworkImage(
width: cardSize,
height: cardSize,
fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 200),
imageUrl: getAlbumThumbnailUrl(
album,
type: ThumbnailFormat.JPEG,
),
httpHeaders: {
"Authorization": "Bearer ${Store.get(StoreKey.accessToken)}",
},
cacheKey:
getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
errorWidget: (context, url, error) =>
const Icon(Icons.image_not_supported_outlined),
),
httpHeaders: {
"Authorization": "Bearer ${Store.get(StoreKey.accessToken)}",
},
cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
errorWidget: (context, url, error) =>
const Icon(Icons.image_not_supported_outlined),
);
}

View file

@ -151,7 +151,7 @@ class AlbumViewerPage extends HookConsumerWidget {
titleFocusNode: titleFocusNode,
)
: Padding(
padding: const EdgeInsets.only(left: 8.0),
padding: const EdgeInsets.only(left: 8.0, bottom: 20.0),
child: Text(
album.name,
style: const TextStyle(

View file

@ -21,7 +21,6 @@ class LibraryPage extends HookConsumerWidget {
final trashEnabled =
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
final albums = ref.watch(albumProvider);
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var settings = ref.watch(appSettingsServiceProvider);
useEffect(
@ -138,51 +137,55 @@ class LibraryPage extends HookConsumerWidget {
}
Widget buildCreateAlbumButton() {
return GestureDetector(
onTap: () {
AutoRouter.of(context).push(CreateAlbumRoute(isSharedAlbum: false));
return LayoutBuilder(
builder: (context, constraints) {
var cardSize = constraints.maxWidth;
return GestureDetector(
onTap: () {
AutoRouter.of(context)
.push(CreateAlbumRoute(isSharedAlbum: false));
},
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: cardSize,
width: cardSize,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Icon(
Icons.add_rounded,
size: 28,
color: Theme.of(context).primaryColor,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
bottom: 16,
left: 8.0,
),
child: const Text(
'library_page_new_album',
style: TextStyle(
fontWeight: FontWeight.bold,
),
).tr(),
),
],
),
),
);
},
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: isDarkMode
? const Color.fromARGB(255, 53, 53, 53)
: const Color.fromARGB(255, 203, 203, 203),
),
color: isDarkMode ? Colors.grey[900] : Colors.grey[50],
borderRadius: BorderRadius.circular(20),
),
child: Center(
child: Icon(
Icons.add_rounded,
size: 28,
color: Theme.of(context).primaryColor,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
bottom: 16,
),
child: const Text(
'library_page_new_album',
style: TextStyle(
fontWeight: FontWeight.bold,
),
).tr(),
),
],
),
),
);
}
@ -192,30 +195,19 @@ class LibraryPage extends HookConsumerWidget {
Function() onClick,
) {
return Expanded(
child: OutlinedButton.icon(
child: ElevatedButton.icon(
onPressed: onClick,
label: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
label,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13.0,
color: isDarkMode ? Colors.white : Colors.grey[800],
),
),
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
alignment: Alignment.centerLeft,
),
),
),
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
backgroundColor: isDarkMode ? Colors.grey[900] : Colors.grey[50],
side: BorderSide(
color: isDarkMode ? Colors.grey[800]! : Colors.grey[300]!,
),
alignment: Alignment.centerLeft,
),
icon: Icon(
icon,
color: Theme.of(context).primaryColor,
),
),
);
@ -293,7 +285,6 @@ class LibraryPage extends HookConsumerWidget {
sliver: SliverGrid(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: .7,
),

View file

@ -134,13 +134,12 @@ class SharingPage extends HookConsumerWidget {
Icons.photo_album_outlined,
size: 20,
),
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
alignment: Alignment.centerLeft,
),
label: const Text(
"sharing_silver_appbar_create_shared_album",
maxLines: 1,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 11,
),
).tr(),
),
),
@ -153,12 +152,11 @@ class SharingPage extends HookConsumerWidget {
Icons.link,
size: 20,
),
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
alignment: Alignment.centerLeft,
),
label: const Text(
"sharing_silver_appbar_shared_links",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 11,
),
maxLines: 1,
).tr(),
),
@ -198,7 +196,10 @@ class SharingPage extends HookConsumerWidget {
padding: const EdgeInsets.all(8.0),
child: Text(
'sharing_page_empty_list',
style: Theme.of(context).textTheme.displaySmall,
style: Theme.of(context)
.textTheme
.displaySmall
?.copyWith(color: Theme.of(context).primaryColor),
).tr(),
),
Padding(

View file

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/backup/ui/album_info_card.dart';
import 'package:immich_mobile/modules/backup/ui/album_info_list_tile.dart';
@ -148,13 +147,12 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
album.name,
style: TextStyle(
fontSize: 10,
color: isDarkTheme ? Colors.black : immichBackgroundColor,
color: Theme.of(context).colorScheme.surface,
fontWeight: FontWeight.bold,
),
),
backgroundColor: Colors.red[300],
deleteIconColor:
isDarkTheme ? Colors.black : immichBackgroundColor,
deleteIconColor: Theme.of(context).colorScheme.surface,
deleteIcon: const Icon(
Icons.cancel_rounded,
size: 15,

View file

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
class DisableMultiSelectButton extends ConsumerWidget {
class DisableMultiSelectButton extends StatelessWidget {
const DisableMultiSelectButton({
Key? key,
required this.onPressed,
@ -12,25 +11,29 @@ class DisableMultiSelectButton extends ConsumerWidget {
final int selectedItemCount;
@override
Widget build(BuildContext context, WidgetRef ref) {
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: ElevatedButton.icon(
onPressed: () {
onPressed();
},
icon: const Icon(Icons.close_rounded),
label: Text(
'$selectedItemCount',
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 18,
),
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: ElevatedButton.icon(
style: ElevatedButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.surface,
backgroundColor: Theme.of(context).colorScheme.primary,
),
onPressed: () {
onPressed();
},
icon: const Icon(Icons.close_rounded),
label: Text(
'$selectedItemCount',
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
),
);
}
}

View file

@ -6,6 +6,7 @@ import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
/// Build the Scroll Thumb and label using the current configuration
typedef ScrollThumbBuilder = Widget Function(
Color backgroundColor,
Color foregroundColor,
Animation<double> thumbAnimation,
Animation<double> labelAnimation,
double height, {
@ -33,6 +34,9 @@ class DraggableScrollbar extends StatefulWidget {
/// The background color of the label and thumb
final Color backgroundColor;
/// The foreground color of the arrows in the thumb
final Color foregroundColor;
/// The amount of padding that should surround the thumb
final EdgeInsetsGeometry? padding;
@ -66,6 +70,7 @@ class DraggableScrollbar extends StatefulWidget {
required this.scrollStateListener,
this.heightScrollThumb = 48.0,
this.backgroundColor = Colors.white,
this.foregroundColor = Colors.white,
this.padding,
this.scrollbarAnimationDuration = const Duration(milliseconds: 300),
this.scrollbarTimeToFade = const Duration(milliseconds: 600),
@ -85,6 +90,7 @@ class DraggableScrollbar extends StatefulWidget {
static buildScrollThumbAndLabel({
required Widget scrollThumb,
required Color backgroundColor,
required Color foregroundColor,
required Animation<double>? thumbAnimation,
required Animation<double>? labelAnimation,
required Text? labelText,
@ -123,6 +129,7 @@ class DraggableScrollbar extends StatefulWidget {
) {
return (
Color backgroundColor,
Color foregroundColor,
Animation<double> thumbAnimation,
Animation<double> labelAnimation,
double height, {
@ -131,7 +138,7 @@ class DraggableScrollbar extends StatefulWidget {
}) {
final scrollThumb = CustomPaint(
key: scrollThumbKey,
foregroundPainter: ArrowCustomPainter(Colors.white),
foregroundPainter: ArrowCustomPainter(foregroundColor),
child: Material(
elevation: 4.0,
color: backgroundColor,
@ -150,6 +157,7 @@ class DraggableScrollbar extends StatefulWidget {
return buildScrollThumbAndLabel(
scrollThumb: scrollThumb,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
thumbAnimation: thumbAnimation,
labelAnimation: labelAnimation,
labelText: labelText,
@ -286,6 +294,7 @@ class DraggableScrollbarState extends State<DraggableScrollbar>
padding: widget.padding,
child: widget.scrollThumbBuilder(
widget.backgroundColor,
widget.foregroundColor,
_thumbAnimation,
_labelAnimation,
widget.heightScrollThumb,

View file

@ -53,9 +53,12 @@ class GroupDividerTitle extends ConsumerWidget {
Icons.check_circle_rounded,
color: Theme.of(context).primaryColor,
)
: const Icon(
: Icon(
Icons.check_circle_outline_rounded,
color: Colors.grey,
color: Theme.of(context)
.colorScheme
.onBackground
.withAlpha(100),
),
),
],

View file

@ -221,11 +221,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
padding: const EdgeInsets.only(left: 12.0, top: 24.0),
child: Text(
title,
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Theme.of(context).textTheme.displayLarge?.color,
),
style: Theme.of(context).textTheme.titleLarge,
),
);
}
@ -243,7 +239,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
bottom: widget.margin,
right: i + 1 == num ? 0.0 : widget.margin,
),
color: Colors.grey,
color: Theme.of(context).colorScheme.surfaceVariant,
),
],
);
@ -328,8 +324,8 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
return Text(
DateFormat.yMMMM().format(date),
style: const TextStyle(
color: Colors.white,
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimary,
fontWeight: FontWeight.bold,
),
);
@ -372,7 +368,8 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
scrollStateListener: dragScrolling,
itemPositionsListener: _itemPositionsListener,
controller: _itemScrollController,
backgroundColor: Theme.of(context).hintColor,
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
labelTextBuilder: _labelBuilder,
labelConstraints: const BoxConstraints(maxHeight: 28),
scrollbarAnimationDuration: const Duration(milliseconds: 300),

View file

@ -43,9 +43,6 @@ class ThumbnailImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final assetContainerColor =
isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight;
// Assets from response DTOs do not have an isar id, querying which would give us the default autoIncrement id
final isFromDto = asset.id == Isar.autoIncrement;
@ -54,11 +51,13 @@ class ThumbnailImage extends StatelessWidget {
return Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: assetContainerColor,
color: Theme.of(context).colorScheme.surfaceVariant,
),
child: Icon(
Icons.check_circle_rounded,
color: Theme.of(context).primaryColor,
color: onDeselect == null
? Theme.of(context).colorScheme.primary.withAlpha(120)
: Theme.of(context).colorScheme.primary,
),
);
} else {
@ -132,9 +131,10 @@ class ThumbnailImage extends StatelessWidget {
}
Widget buildImage() {
final image = SizedBox(
final image = Container(
width: 300,
height: 300,
color: Theme.of(context).colorScheme.surfaceVariant,
child: Hero(
tag: isFromDto
? '${asset.remoteId}-$heroOffset'
@ -153,9 +153,9 @@ class ThumbnailImage extends StatelessWidget {
decoration: BoxDecoration(
border: Border.all(
width: 0,
color: onDeselect == null ? Colors.grey : assetContainerColor,
color: Theme.of(context).colorScheme.surfaceVariant,
),
color: onDeselect == null ? Colors.grey : assetContainerColor,
color: Theme.of(context).colorScheme.surfaceVariant,
),
child: ClipRRect(
borderRadius: const BorderRadius.only(
@ -197,14 +197,14 @@ class ThumbnailImage extends StatelessWidget {
},
child: Stack(
children: [
Container(
AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.decelerate,
decoration: BoxDecoration(
border: multiselectEnabled && isSelected
? Border.all(
color: onDeselect == null
? Colors.grey
: assetContainerColor,
width: 8,
color: Theme.of(context).colorScheme.surfaceVariant,
width: 12,
)
: const Border(),
),

View file

@ -42,7 +42,6 @@ class ControlBottomAppBar extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var hasRemote =
selectionAssetState.hasRemote || selectionAssetState.hasMerged;
var hasLocal = selectionAssetState.hasLocal;
@ -128,8 +127,6 @@ class ControlBottomAppBar extends ConsumerWidget {
ScrollController scrollController,
) {
return Card(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
surfaceTintColor: Colors.transparent,
elevation: 18.0,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(

View file

@ -127,9 +127,9 @@ class LoginForm extends HookConsumerWidget {
);
populateTestLoginInfo() {
usernameController.text = 'testuser@email.com';
passwordController.text = 'password';
serverEndpointController.text = 'http://10.1.15.216:2283/api';
usernameController.text = 'demo@immich.app';
passwordController.text = 'demo';
serverEndpointController.text = 'https://demo.immich.app';
}
login() async {
@ -303,7 +303,10 @@ class LoginForm extends HookConsumerWidget {
children: [
Text(
serverEndpointController.text,
style: Theme.of(context).textTheme.displaySmall,
style: Theme.of(context)
.textTheme
.displaySmall
?.copyWith(color: Theme.of(context).primaryColor),
textAlign: TextAlign.center,
),
if (isPasswordLoginEnable.value) ...[

View file

@ -120,6 +120,7 @@ class MapPageState extends ConsumerState<MapPage> {
final selectedAssets = useState(<Asset>{});
final showLoadingIndicator = useState(false);
final refetchMarkers = useState(true);
final themeData = isDarkTheme ? immichDarkTheme : immichLightTheme;
if (refetchMarkers.value) {
mapMarkerData.value = ref.watch(mapMarkersProvider).when(
@ -189,7 +190,7 @@ class MapPageState extends ConsumerState<MapPage> {
showDialog(
context: context,
builder: (context) => Theme(
data: isDarkTheme ? immichDarkTheme : immichLightTheme,
data: themeData,
child: LocationServiceDisabledDialog(),
),
);
@ -203,7 +204,7 @@ class MapPageState extends ConsumerState<MapPage> {
shouldRequestPermission = await showDialog(
context: context,
builder: (context) => Theme(
data: isDarkTheme ? immichDarkTheme : immichLightTheme,
data: themeData,
child: LocationPermissionDisabledDialog(),
),
);
@ -438,7 +439,7 @@ class MapPageState extends ConsumerState<MapPage> {
),
child: Theme(
// Override app theme based on map theme
data: isDarkTheme ? immichDarkTheme : immichLightTheme,
data: themeData,
child: Scaffold(
appBar: MapAppBar(
isDarkTheme: isDarkTheme,

View file

@ -17,7 +17,7 @@ class MemoryLane extends HookConsumerWidget {
.whenData(
(memories) => memories != null
? Container(
margin: const EdgeInsets.only(top: 10),
margin: const EdgeInsets.only(top: 10, left: 10),
height: 200,
child: ListView.builder(
scrollDirection: Axis.horizontal,

View file

@ -118,6 +118,7 @@ class PartnerPage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
@ -126,12 +127,15 @@ class PartnerPage extends HookConsumerWidget {
style: TextStyle(fontSize: 14),
).tr(),
),
ElevatedButton.icon(
onPressed: availableUsers.whenOrNull(
data: (data) => addNewUsersHandler,
Align(
alignment: Alignment.center,
child: ElevatedButton.icon(
onPressed: availableUsers.whenOrNull(
data: (data) => addNewUsersHandler,
),
icon: const Icon(Icons.person_add),
label: const Text("partner_page_add_partner").tr(),
),
icon: const Icon(Icons.person_add),
label: const Text("partner_page_add_partner").tr(),
),
],
),

View file

@ -30,8 +30,8 @@ class CuratedPeopleRow extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SizedBox(
width: imageSize,
height: imageSize,
width: 120,
height: 120,
child: ThumbnailWithInfo(
textInfo: '',
onTap: () {},

View file

@ -22,8 +22,6 @@ class ThumbnailWithInfo extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var textAndIconColor = isDarkMode ? Colors.grey[100] : Colors.grey[700];
return GestureDetector(
onTap: () {
onTap();
@ -34,7 +32,7 @@ class ThumbnailWithInfo extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
color: Theme.of(context).colorScheme.surfaceVariant,
),
child: imageUrl != null
? ClipRRect(
@ -43,6 +41,17 @@ class ThumbnailWithInfo extends StatelessWidget {
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
placeholder: (context, url) {
return SizedBox.square(
dimension: 250,
child: DecoratedBox(
decoration: BoxDecoration(
color:
Theme.of(context).colorScheme.surfaceVariant,
),
),
);
},
imageUrl: imageUrl!,
httpHeaders: {
"Authorization":
@ -55,7 +64,7 @@ class ThumbnailWithInfo extends StatelessWidget {
: Center(
child: Icon(
noImageIcon ?? Icons.not_listed_location,
color: textAndIconColor,
color: Theme.of(context).primaryColor,
),
),
),
@ -67,10 +76,10 @@ class ThumbnailWithInfo extends StatelessWidget {
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
Colors.grey.withOpacity(0.0),
Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.0),
textInfo == ''
? Colors.black.withOpacity(0.1)
: Colors.black.withOpacity(0.5),
? Theme.of(context).colorScheme.surface.withOpacity(0.1)
: Theme.of(context).colorScheme.surface.withOpacity(0.6),
],
stops: const [0.0, 1.0],
),

View file

@ -86,7 +86,6 @@ class AdvancedSettings extends HookConsumerWidget {
min: 1.0,
divisions: 7,
label: logLevel,
activeColor: Theme.of(context).primaryColor,
),
),
SettingsSwitchListTile(

View file

@ -50,7 +50,6 @@ class LayoutSettings extends HookConsumerWidget {
return Column(
children: [
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: Text(
"asset_list_layout_settings_dynamic_layout_title",
style: Theme.of(context)
@ -75,7 +74,6 @@ class LayoutSettings extends HookConsumerWidget {
).tr(),
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
title: Text(
"asset_list_layout_settings_group_by_month_day",
style: Theme.of(context).textTheme.labelLarge,
@ -86,7 +84,6 @@ class LayoutSettings extends HookConsumerWidget {
controlAffinity: ListTileControlAffinity.trailing,
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
title: Text(
"asset_list_layout_settings_group_by_month",
style: Theme.of(context).textTheme.labelLarge,
@ -97,7 +94,6 @@ class LayoutSettings extends HookConsumerWidget {
controlAffinity: ListTileControlAffinity.trailing,
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
title: Text(
"asset_list_layout_settings_group_automatically",
style: Theme.of(context).textTheme.labelLarge,

View file

@ -33,7 +33,6 @@ class StorageIndicator extends HookConsumerWidget {
);
return SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: Text(
"theme_setting_asset_list_storage_indicator_title",
style: Theme.of(context)

View file

@ -51,7 +51,6 @@ class TilesPerRow extends HookConsumerWidget {
max: 6,
divisions: 4,
label: "${itemsValue.value.toInt()}",
activeColor: Theme.of(context).primaryColor,
),
],
);

View file

@ -149,7 +149,6 @@ class NotificationSetting extends HookConsumerWidget {
max: 5.0,
divisions: 5,
label: formattedValue,
activeColor: Theme.of(context).primaryColor,
),
),
],

View file

@ -23,29 +23,31 @@ class SettingsSwitchListTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SwitchListTile.adaptive(
selectedTileColor: enabled ? null : Theme.of(context).disabledColor,
value: valueNotifier.value,
onChanged: (bool value) {
if (enabled) {
valueNotifier.value = value;
appSettingService.setSetting(settingsEnum, value);
}
if (onChanged != null) {
onChanged!(value);
}
},
activeColor: enabled
? Theme.of(context).primaryColor
: Theme.of(context).disabledColor,
onChanged: enabled
? (bool value) {
valueNotifier.value = value;
appSettingService.setSetting(settingsEnum, value);
if (onChanged != null) {
onChanged!(value);
}
}
: null,
dense: true,
title: Text(
title,
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
style: Theme.of(context).textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.bold,
color: enabled
? null
: Theme.of(context).colorScheme.onSurface.withAlpha(100),
),
),
subtitle: subtitle != null ? Text(subtitle!) : null,
subtitle: subtitle != null
? Text(
subtitle!,
)
: null,
);
}
}

View file

@ -24,7 +24,6 @@ class ThemeSetting extends HookConsumerWidget {
);
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
title: const Text(
'theme_setting_theme_title',
style: TextStyle(
@ -39,7 +38,6 @@ class ThemeSetting extends HookConsumerWidget {
).tr(),
children: [
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: Text(
'theme_setting_system_theme_switch',
style: Theme.of(context)
@ -77,7 +75,6 @@ class ThemeSetting extends HookConsumerWidget {
),
if (currentTheme.value != ThemeMode.system)
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
title: Text(
'theme_setting_dark_mode_switch',
style: Theme.of(context)

View file

@ -23,7 +23,6 @@ class ImmichAppBarDialog extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
BackUpState backupState = ref.watch(backupProvider);
final theme = Theme.of(context);
bool isDarkTheme = theme.brightness == Brightness.dark;
bool isHorizontal = MediaQuery.of(context).size.width > 600;
final horizontalPadding = isHorizontal ? 100.0 : 20.0;
final user = ref.watch(currentUserProvider);
@ -135,11 +134,8 @@ class ImmichAppBarDialog extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 3),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4),
decoration: BoxDecoration(
color: isDarkTheme
? Theme.of(context).scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
),
decoration:
BoxDecoration(color: Theme.of(context).colorScheme.surface),
child: ListTile(
minLeadingWidth: 50,
leading: Icon(
@ -161,7 +157,8 @@ class ImmichAppBarDialog extends HookConsumerWidget {
child: LinearProgressIndicator(
minHeight: 5.0,
value: backupState.serverInfo.diskUsagePercentage / 100.0,
backgroundColor: Colors.grey,
backgroundColor:
Theme.of(context).colorScheme.onSurface.withAlpha(50),
color: theme.primaryColor,
),
),

View file

@ -18,7 +18,6 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
AuthenticationState authState = ref.watch(authenticationProvider);
final uploadProfileImageStatus =
ref.watch(uploadProfileImageProvider).status;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final user = Store.tryGet(StoreKey.currentUser);
buildUserProfileImage() {
@ -91,9 +90,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? Theme.of(context).scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
@ -111,7 +108,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
bottom: -5,
right: -8,
child: Material(
color: isDarkMode ? Colors.blueGrey[800] : Colors.white,
color: Theme.of(context).colorScheme.primaryContainer,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),

View file

@ -39,9 +39,7 @@ class AppBarServerInfo extends HookConsumerWidget {
padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? Theme.of(context).scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
@ -139,7 +137,7 @@ class AppBarServerInfo extends HookConsumerWidget {
child: Text(
serverInfoState.serverVersion.major > 0
? "${serverInfoState.serverVersion.major}.${serverInfoState.serverVersion.minor}.${serverInfoState.serverVersion.patch}"
: "?",
: "--",
style: TextStyle(
fontSize: 11,
color: Theme.of(context)
@ -190,9 +188,7 @@ class AppBarServerInfo extends HookConsumerWidget {
borderRadius: BorderRadius.circular(10),
),
textStyle: TextStyle(
color: Theme.of(context).brightness == Brightness.dark
? Colors.black
: Colors.white,
color: Theme.of(context).colorScheme.onPrimary,
fontWeight: FontWeight.bold,
),
message: getServerUrl() ?? '--',

View file

@ -9,7 +9,7 @@ class CustomDraggingHandle extends StatelessWidget {
height: 5,
width: 30,
decoration: BoxDecoration(
color: Colors.grey[500],
color: Theme.of(context).dividerColor,
borderRadius: BorderRadius.circular(16),
),
);

View file

@ -28,7 +28,6 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
final ServerInfo serverInfoState = ref.watch(serverInfoProvider);
AuthenticationState authState = ref.watch(authenticationProvider);
final user = Store.tryGet(StoreKey.currentUser);
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
const widgetSize = 30.0;
buildProfileIndicator() {
@ -69,9 +68,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
);
}
getBackupBadgeIcon() {
final iconColor = isDarkMode ? Colors.white : Colors.black;
Widget? getBackupBadgeIcon() {
if (isEnableAutoBackup) {
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
return Container(
@ -79,7 +76,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
child: CircularProgressIndicator(
strokeWidth: 2,
strokeCap: StrokeCap.round,
valueColor: AlwaysStoppedAnimation<Color>(iconColor),
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
);
} else if (backupState.backupProgress !=
@ -88,7 +85,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
return Icon(
Icons.check_outlined,
size: 9,
color: iconColor,
color: Theme.of(context).colorScheme.onSurfaceVariant,
);
}
}
@ -97,14 +94,14 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
return Icon(
Icons.cloud_off_rounded,
size: 9,
color: iconColor,
color: Theme.of(context).colorScheme.onSurfaceVariant,
);
}
return null;
}
buildBackupIndicator() {
final indicatorIcon = getBackupBadgeIcon();
final badgeBackground = isDarkMode ? Colors.blueGrey[800] : Colors.white;
return InkWell(
onTap: () => AutoRouter.of(context).push(const BackupControllerRoute()),
@ -114,11 +111,11 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
width: widgetSize / 2,
height: widgetSize / 2,
decoration: BoxDecoration(
color: badgeBackground,
border: Border.all(
color: isDarkMode ? Colors.black : Colors.grey,
color: Theme.of(context).colorScheme.surface,
),
borderRadius: BorderRadius.circular(widgetSize / 2),
color: Theme.of(context).colorScheme.surfaceVariant,
),
child: indicatorIcon,
),
@ -126,10 +123,9 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
alignment: Alignment.bottomRight,
isLabelVisible: indicatorIcon != null,
offset: const Offset(2, 2),
child: Icon(
child: const Icon(
Icons.backup_rounded,
size: widgetSize,
color: Theme.of(context).primaryColor,
),
),
);
@ -158,12 +154,13 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
),
Container(
margin: const EdgeInsets.only(left: 10),
child: const Text(
child: Text(
'IMMICH',
style: TextStyle(
fontFamily: 'SnowburstOne',
fontWeight: FontWeight.bold,
fontSize: 24,
color: Theme.of(context).primaryColor,
),
),
),

View file

@ -32,8 +32,8 @@ class ImmichImage extends StatelessWidget {
Widget build(BuildContext context) {
if (this.asset == null) {
return Container(
decoration: const BoxDecoration(
color: Colors.grey,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant,
),
child: SizedBox(
width: width,
@ -60,10 +60,12 @@ class ImmichImage extends StatelessWidget {
return Stack(
children: [
if (useGrayBoxPlaceholder)
const SizedBox.square(
SizedBox.square(
dimension: 250,
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.grey),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
),
if (useProgressIndicator)
@ -109,10 +111,12 @@ class ImmichImage extends StatelessWidget {
return Stack(
children: [
if (useGrayBoxPlaceholder)
const SizedBox.square(
SizedBox.square(
dimension: 250,
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.grey),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
),
if (useProgressIndicator)

View file

@ -13,7 +13,7 @@ class PhotoViewDefaultError extends StatelessWidget {
child: Center(
child: Icon(
Icons.broken_image,
color: Colors.grey[400],
color: Theme.of(context).primaryColor,
size: 40.0,
),
),

View file

@ -79,8 +79,9 @@ class SplashScreenPage extends HookConsumerWidget {
[],
);
return const Scaffold(
body: Center(
return Scaffold(
appBar: AppBar(),
body: const Center(
child: Image(
image: AssetImage('assets/immich-logo-no-outline.png'),
width: 80,

View file

@ -24,7 +24,7 @@ class TabControllerPage extends HookConsumerWidget {
children: [
icon,
Positioned(
right: -14,
right: -16,
child: SizedBox(
height: 12,
width: 12,
@ -114,9 +114,8 @@ class TabControllerPage extends HookConsumerWidget {
Icons.photo_library_outlined,
),
selectedIcon: buildIcon(
Icon(
const Icon(
Icons.photo_library,
color: Theme.of(context).primaryColor,
),
),
),
@ -125,9 +124,8 @@ class TabControllerPage extends HookConsumerWidget {
icon: const Icon(
Icons.search_rounded,
),
selectedIcon: Icon(
selectedIcon: const Icon(
Icons.search,
color: Theme.of(context).primaryColor,
),
),
NavigationDestination(
@ -135,9 +133,8 @@ class TabControllerPage extends HookConsumerWidget {
icon: const Icon(
Icons.group_outlined,
),
selectedIcon: Icon(
selectedIcon: const Icon(
Icons.group,
color: Theme.of(context).primaryColor,
),
),
NavigationDestination(
@ -146,9 +143,8 @@ class TabControllerPage extends HookConsumerWidget {
Icons.photo_album_outlined,
),
selectedIcon: buildIcon(
Icon(
const Icon(
Icons.photo_album_rounded,
color: Theme.of(context).primaryColor,
),
),
),

View file

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
@ -20,259 +19,157 @@ final immichThemeProvider = StateProvider<ThemeMode>((ref) {
}
});
ThemeData base = ThemeData(
chipTheme: const ChipThemeData(
side: BorderSide.none,
),
sliderTheme: const SliderThemeData(
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
trackHeight: 2.0,
),
);
ThemeData immichLightTheme = ThemeData(
useMaterial3: true,
ColorScheme _lightColorScheme = const ColorScheme(
brightness: Brightness.light,
primarySwatch: Colors.indigo,
primaryColor: Colors.indigo,
hintColor: Colors.indigo,
focusColor: Colors.indigo,
splashColor: Colors.indigo.withOpacity(0.15),
fontFamily: 'WorkSans',
scaffoldBackgroundColor: immichBackgroundColor,
snackBarTheme: const SnackBarThemeData(
contentTextStyle: TextStyle(
fontFamily: 'WorkSans',
color: Colors.indigo,
fontWeight: FontWeight.bold,
),
backgroundColor: Colors.white,
),
appBarTheme: AppBarTheme(
titleTextStyle: const TextStyle(
fontFamily: 'WorkSans',
color: Colors.indigo,
fontWeight: FontWeight.bold,
fontSize: 18,
),
backgroundColor: immichBackgroundColor,
foregroundColor: Colors.indigo,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true,
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed,
backgroundColor: immichBackgroundColor,
selectedItemColor: Colors.indigo,
),
cardTheme: const CardTheme(
surfaceTintColor: Colors.transparent,
),
drawerTheme: DrawerThemeData(
backgroundColor: immichBackgroundColor,
),
textTheme: const TextTheme(
displayLarge: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.indigo,
),
displayMedium: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
displaySmall: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.indigo,
),
titleSmall: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
titleMedium: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
titleLarge: TextStyle(
fontSize: 26.0,
fontWeight: FontWeight.bold,
),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.indigo,
foregroundColor: Colors.white,
),
),
chipTheme: base.chipTheme,
sliderTheme: base.sliderTheme,
popupMenuTheme: const PopupMenuThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
surfaceTintColor: Colors.transparent,
color: Colors.white,
),
navigationBarTheme: NavigationBarThemeData(
indicatorColor: Colors.indigo.withOpacity(0.15),
iconTheme: MaterialStatePropertyAll(
IconThemeData(color: Colors.grey[700]),
),
backgroundColor: immichBackgroundColor,
surfaceTintColor: Colors.transparent,
labelTextStyle: MaterialStatePropertyAll(
TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.grey[700],
),
),
),
dialogTheme: const DialogTheme(
surfaceTintColor: Colors.transparent,
),
inputDecorationTheme: const InputDecorationTheme(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.indigo,
),
),
labelStyle: TextStyle(
color: Colors.indigo,
),
hintStyle: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
),
),
textSelectionTheme: const TextSelectionThemeData(
cursorColor: Colors.indigo,
),
primary: Color(0xff4755b5),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xffdfe0ff),
onPrimaryContainer: Color(0xff000d60),
secondary: Color(0xff5b5d72),
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xFFD6D8FF),
onSecondaryContainer: Color(0xff181a2c),
tertiary: Color(0xff77536c),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xffffd7f0),
onTertiaryContainer: Color(0xff2d1127),
error: Color(0xffba1a1a),
onError: Color(0xffffffff),
errorContainer: Color(0xffffdad6),
onErrorContainer: Color(0xff410002),
background: Color(0xfff9f6fc),
onBackground: Color(0xff1b1b1f),
surface: Color(0xfff9f6fc),
onSurface: Color(0xff1b1b1f),
surfaceVariant: Color(0xffdeddea),
onSurfaceVariant: Color(0xff46464f),
outline: Color(0xff777680),
outlineVariant: Color(0xffc7c5d0),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xff303137),
onInverseSurface: Color(0xfff3f0f4),
inversePrimary: Color(0xffbcc3ff),
surfaceTint: Color(0xff4755b5),
);
ThemeData immichDarkTheme = ThemeData(
useMaterial3: true,
ColorScheme _darkColorScheme = const ColorScheme(
brightness: Brightness.dark,
primarySwatch: Colors.indigo,
primaryColor: immichDarkThemePrimaryColor,
scaffoldBackgroundColor: immichDarkBackgroundColor,
hintColor: Colors.grey[600],
fontFamily: 'WorkSans',
snackBarTheme: SnackBarThemeData(
contentTextStyle: TextStyle(
fontFamily: 'WorkSans',
color: immichDarkThemePrimaryColor,
fontWeight: FontWeight.bold,
),
backgroundColor: Colors.grey[900],
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: immichDarkThemePrimaryColor,
),
),
appBarTheme: AppBarTheme(
titleTextStyle: TextStyle(
fontFamily: 'WorkSans',
color: immichDarkThemePrimaryColor,
fontWeight: FontWeight.bold,
fontSize: 18,
),
backgroundColor: const Color.fromARGB(255, 32, 33, 35),
foregroundColor: immichDarkThemePrimaryColor,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true,
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed,
backgroundColor: const Color.fromARGB(255, 35, 36, 37),
selectedItemColor: immichDarkThemePrimaryColor,
),
drawerTheme: DrawerThemeData(
backgroundColor: immichDarkBackgroundColor,
scrimColor: Colors.white.withOpacity(0.1),
),
textTheme: TextTheme(
displayLarge: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 255, 255, 255),
),
displayMedium: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 255, 255, 255),
),
displaySmall: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: immichDarkThemePrimaryColor,
),
titleSmall: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
titleMedium: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
titleLarge: const TextStyle(
fontSize: 26.0,
fontWeight: FontWeight.bold,
),
),
cardColor: Colors.grey[900],
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black87,
backgroundColor: immichDarkThemePrimaryColor,
),
),
chipTheme: base.chipTheme,
sliderTheme: base.sliderTheme,
popupMenuTheme: const PopupMenuThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
surfaceTintColor: Colors.transparent,
),
navigationBarTheme: NavigationBarThemeData(
indicatorColor: immichDarkThemePrimaryColor.withOpacity(0.4),
iconTheme: MaterialStatePropertyAll(
IconThemeData(color: Colors.grey[500]),
),
backgroundColor: Colors.grey[900],
surfaceTintColor: Colors.transparent,
labelTextStyle: MaterialStatePropertyAll(
TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Colors.grey[500],
),
),
),
dialogTheme: const DialogTheme(
surfaceTintColor: Colors.transparent,
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: immichDarkThemePrimaryColor,
),
),
labelStyle: TextStyle(
color: immichDarkThemePrimaryColor,
),
hintStyle: const TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
),
),
textSelectionTheme: TextSelectionThemeData(
cursorColor: immichDarkThemePrimaryColor,
),
primary: Color(0xffa4c8ff),
onPrimary: Color(0xff00315e),
primaryContainer: Color(0xFF182C40),
onPrimaryContainer: Color(0xffd4e3ff),
secondary: Color(0xffbcc7dc),
onSecondary: Color(0xff37474f),
secondaryContainer: Color(0xff3d4758),
onSecondaryContainer: Color(0xffd8e3f8),
tertiary: Color(0xffdabde2),
onTertiary: Color(0xff3d2946),
tertiaryContainer: Color(0xff543f5e),
onTertiaryContainer: Color(0xfff6d9ff),
error: Color(0xffffb4ab),
onError: Color(0xff690005),
errorContainer: Color(0xff93000a),
onErrorContainer: Color(0xffffb4ab),
background: Color(0xff101214),
onBackground: Color(0xffe2e2e5),
surface: Color(0xff101214),
onSurface: Color(0xffe2e2e5),
surfaceVariant: Color(0xff363c42),
onSurfaceVariant: Color(0xffc1c7ce),
outline: Color(0xff8b9198),
outlineVariant: Color(0xff41474d),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xffeeeef1),
onInverseSurface: Color(0xff2e3133),
inversePrimary: Color(0xff1c5fa5),
surfaceTint: Color(0xff90caf9),
);
ThemeData getThemeForScheme(ColorScheme scheme) {
return ThemeData(
useMaterial3: true,
brightness: scheme.brightness,
colorScheme: scheme,
primaryColor: scheme.primary,
scaffoldBackgroundColor: scheme.background,
fontFamily: 'WorkSans',
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(color: scheme.primary),
titleTextStyle: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: scheme.primary,
),
),
cardTheme: const CardTheme(elevation: 2.0),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
visualDensity: VisualDensity.standard,
textStyle: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 11,
),
shadowColor: scheme.shadow,
foregroundColor: scheme.onPrimary,
backgroundColor: scheme.primary,
),
),
navigationBarTheme: NavigationBarThemeData(
iconTheme: MaterialStateProperty.resolveWith<IconThemeData?>((states) {
if (states.contains(MaterialState.selected)) {
return IconThemeData(color: scheme.primary);
}
return null;
}),
),
textTheme: TextTheme(
displayLarge: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: scheme.primary,
),
displayMedium: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
displaySmall: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
titleSmall: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
titleMedium: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
titleLarge: TextStyle(
fontSize: 26.0,
fontWeight: FontWeight.bold,
color: scheme.primary,
),
),
chipTheme: const ChipThemeData(
side: BorderSide.none,
),
sliderTheme: const SliderThemeData(
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
trackHeight: 2.0,
),
inputDecorationTheme: InputDecorationTheme(
labelStyle: TextStyle(
color: scheme.primary,
),
hintStyle: const TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
),
),
);
}
ThemeData immichLightTheme = getThemeForScheme(_lightColorScheme);
ThemeData immichDarkTheme = getThemeForScheme(_darkColorScheme);