Skip to content

Commit

Permalink
Merge branch 'main' into feat/galleryviewer-shortcuts
Browse files Browse the repository at this point in the history
  • Loading branch information
alextran1502 authored Nov 19, 2024
2 parents bf5f630 + 3a2e30e commit bd16873
Show file tree
Hide file tree
Showing 20 changed files with 417 additions and 280 deletions.
5 changes: 5 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@
"confirm": "Confirm",
"confirm_admin_password": "Confirm Admin Password",
"confirm_delete_shared_link": "Are you sure you want to delete this shared link?",
"confirm_keep_this_delete_others": "All other assets in the stack will be deleted except for this asset. Are you sure you want to continue?",
"confirm_password": "Confirm password",
"contain": "Contain",
"context": "Context",
Expand Down Expand Up @@ -514,6 +515,7 @@
"delete_key": "Delete key",
"delete_library": "Delete Library",
"delete_link": "Delete link",
"delete_others": "Delete others",
"delete_shared_link": "Delete shared link",
"delete_tag": "Delete tag",
"delete_tag_confirmation_prompt": "Are you sure you want to delete {tagName} tag?",
Expand Down Expand Up @@ -610,6 +612,7 @@
"failed_to_remove_product_key": "Failed to remove product key",
"failed_to_stack_assets": "Failed to stack assets",
"failed_to_unstack_assets": "Failed to un-stack assets",
"failed_to_keep_this_delete_others": "Failed to keep this asset and delete the other assets",
"import_path_already_exists": "This import path already exists.",
"incorrect_email_or_password": "Incorrect email or password",
"paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation",
Expand Down Expand Up @@ -1253,8 +1256,10 @@
"unselect_all_duplicates": "Unselect all duplicates",
"unstack": "Un-stack",
"unstacked_assets_count": "Un-stacked {count, plural, one {# asset} other {# assets}}",
"keep_this_delete_others": "Keep this, delete others",
"untracked_files": "Untracked files",
"untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"kept_this_deleted_others": "Kept this asset and deleted {count, plural, one {# asset} other {# assets}}",
"up_next": "Up next",
"updated_password": "Updated password",
"upload": "Upload",
Expand Down
4 changes: 2 additions & 2 deletions machine-learning/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG DEVICE=cpu

FROM python:3.11-bookworm@sha256:70f1eb2927a8ef72840254b17024d3a8aa8c3c9715a625d426a2861b5899bc62 AS builder-cpu
FROM python:3.11-bookworm@sha256:706d1233c61a31507c4f8939cfd6a924610b51174c095f33e2c537fb904a1e76 AS builder-cpu

FROM builder-cpu AS builder-openvino

Expand Down Expand Up @@ -34,7 +34,7 @@ RUN python3 -m venv /opt/venv
COPY poetry.lock pyproject.toml ./
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev

FROM python:3.11-slim-bookworm@sha256:5148c0e4bbb64271bca1d3322360ebf4bfb7564507ae32dd639322e4952a6b16 AS prod-cpu
FROM python:3.11-slim-bookworm@sha256:e8381c802593deb0c4d25bd3f4e05e94382f6bf33090de22679fc7488cd68bbb AS prod-cpu

FROM prod-cpu AS prod-openvino

Expand Down
443 changes: 226 additions & 217 deletions machine-learning/poetry.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions mobile/lib/constants/locales.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,8 @@ const Map<String, Locale> locales = {
};

const String translationsPath = 'assets/i18n';

const List<Locale> localesNotSupportedByOverpass = [
Locale('el', 'GR'),
Locale('sr', 'Cyrl'),
];
46 changes: 32 additions & 14 deletions mobile/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/locale_provider.dart';
import 'package:immich_mobile/utils/download.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:timezone/data/latest.dart';
Expand Down Expand Up @@ -191,6 +192,12 @@ class ImmichAppState extends ConsumerState<ImmichApp>
await ref.read(localNotificationService).setup();
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
Intl.defaultLocale = context.locale.toLanguageTag();
}

@override
initState() {
super.initState();
Expand All @@ -212,20 +219,31 @@ class ImmichAppState extends ConsumerState<ImmichApp>
final router = ref.watch(appRouterProvider);
final immichTheme = ref.watch(immichThemeProvider);

return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
debugShowCheckedModeBanner: true,
home: MaterialApp.router(
title: 'Immich',
debugShowCheckedModeBanner: false,
themeMode: ref.watch(immichThemeModeProvider),
darkTheme: getThemeData(colorScheme: immichTheme.dark),
theme: getThemeData(colorScheme: immichTheme.light),
routeInformationParser: router.defaultRouteParser(),
routerDelegate: router.delegate(
navigatorObservers: () => [TabNavigationObserver(ref: ref)],
return ProviderScope(
overrides: [
localeProvider.overrideWithValue(context.locale),
],
child: MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
debugShowCheckedModeBanner: true,
home: MaterialApp.router(
title: 'Immich',
debugShowCheckedModeBanner: false,
themeMode: ref.watch(immichThemeModeProvider),
darkTheme: getThemeData(
colorScheme: immichTheme.dark,
locale: context.locale,
),
theme: getThemeData(
colorScheme: immichTheme.light,
locale: context.locale,
),
routeInformationParser: router.defaultRouteParser(),
routerDelegate: router.delegate(
navigatorObservers: () => [TabNavigationObserver(ref: ref)],
),
),
),
);
Expand Down
2 changes: 2 additions & 0 deletions mobile/lib/pages/common/settings.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class SettingsPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
context.locale;
return Scaffold(
appBar: AppBar(
centerTitle: false,
Expand Down Expand Up @@ -129,6 +130,7 @@ class SettingsSubPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
context.locale;
return Scaffold(
appBar: AppBar(
centerTitle: false,
Expand Down
1 change: 1 addition & 0 deletions mobile/lib/pages/library/library.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LibraryPage extends ConsumerWidget {
const LibraryPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
context.locale;
final trashEnabled =
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));

Expand Down
44 changes: 23 additions & 21 deletions mobile/lib/pages/search/search.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -661,29 +661,31 @@ class SearchEmptyContent extends StatelessWidget {

@override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
SizedBox(height: 40),
Center(
child: Image.asset(
context.isDarkTheme
? 'assets/polaroid-dark.png'
: 'assets/polaroid-light.png',
height: 125,
return NotificationListener<ScrollNotification>(
onNotification: (_) => true,
child: ListView(
shrinkWrap: false,
children: [
SizedBox(height: 40),
Center(
child: Image.asset(
context.isDarkTheme
? 'assets/polaroid-dark.png'
: 'assets/polaroid-light.png',
height: 125,
),
),
),
SizedBox(height: 16),
Center(
child: Text(
"Search for your photos and videos",
style: context.textTheme.labelLarge,
SizedBox(height: 16),
Center(
child: Text(
"Search for your photos and videos",
style: context.textTheme.labelLarge,
),
),
),
SizedBox(height: 32),
QuickLinkList(),
],
SizedBox(height: 32),
QuickLinkList(),
],
),
);
}
}
Expand Down
44 changes: 26 additions & 18 deletions mobile/lib/providers/asset.provider.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/locale_provider.dart';
import 'package:immich_mobile/providers/memory.provider.dart';
import 'package:immich_mobile/repositories/asset_media.repository.dart';
import 'package:immich_mobile/services/album.service.dart';
Expand Down Expand Up @@ -328,24 +329,31 @@ final assetWatcher =
return db.assets.watchObject(asset.id, fireImmediately: true);
});

final assetsProvider = StreamProvider.family<RenderList, int?>((ref, userId) {
if (userId == null) return const Stream.empty();
final query = _commonFilterAndSort(
_assets(ref).where().ownerIdEqualToAnyChecksum(userId),
);
return renderListGenerator(query, ref);
});

final multiUserAssetsProvider =
StreamProvider.family<RenderList, List<int>>((ref, userIds) {
if (userIds.isEmpty) return const Stream.empty();
final query = _commonFilterAndSort(
_assets(ref)
.where()
.anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)),
);
return renderListGenerator(query, ref);
});
final assetsProvider = StreamProvider.family<RenderList, int?>(
(ref, userId) {
if (userId == null) return const Stream.empty();
ref.watch(localeProvider);
final query = _commonFilterAndSort(
_assets(ref).where().ownerIdEqualToAnyChecksum(userId),
);
return renderListGenerator(query, ref);
},
dependencies: [localeProvider],
);

final multiUserAssetsProvider = StreamProvider.family<RenderList, List<int>>(
(ref, userIds) {
if (userIds.isEmpty) return const Stream.empty();
ref.watch(localeProvider);
final query = _commonFilterAndSort(
_assets(ref)
.where()
.anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)),
);
return renderListGenerator(query, ref);
},
dependencies: [localeProvider],
);

QueryBuilder<Asset, Asset, QAfterSortBy>? getRemoteAssetQuery(WidgetRef ref) {
final userId = ref.watch(currentUserProvider)?.isarId;
Expand Down
4 changes: 4 additions & 0 deletions mobile/lib/providers/locale_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'package:flutter/widgets.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final localeProvider = Provider<Locale>((_) => throw UnimplementedError());
20 changes: 16 additions & 4 deletions mobile/lib/utils/immich_app_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/constants/locales.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
Expand Down Expand Up @@ -145,7 +146,18 @@ ImmichTheme _decolorizeSurfaces({
);
}

ThemeData getThemeData({required ColorScheme colorScheme}) {
String? getFontFamilyFromLocale(Locale locale) {
if (localesNotSupportedByOverpass.contains(locale)) {
// Let Flutter use the default font
return null;
}
return 'Overpass';
}

ThemeData getThemeData({
required ColorScheme colorScheme,
required Locale locale,
}) {
var isDark = colorScheme.brightness == Brightness.dark;
var primaryColor = colorScheme.primary;

Expand All @@ -163,10 +175,10 @@ ThemeData getThemeData({required ColorScheme colorScheme}) {
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: colorScheme.surfaceContainer,
),
fontFamily: 'Overpass',
fontFamily: getFontFamilyFromLocale(locale),
snackBarTheme: SnackBarThemeData(
contentTextStyle: TextStyle(
fontFamily: 'Overpass',
fontFamily: getFontFamilyFromLocale(locale),
color: primaryColor,
fontWeight: FontWeight.bold,
),
Expand All @@ -175,7 +187,7 @@ ThemeData getThemeData({required ColorScheme colorScheme}) {
appBarTheme: AppBarTheme(
titleTextStyle: TextStyle(
color: primaryColor,
fontFamily: 'Overpass',
fontFamily: getFontFamilyFromLocale(locale),
fontWeight: FontWeight.bold,
fontSize: 18,
),
Expand Down
6 changes: 4 additions & 2 deletions mobile/lib/widgets/map/map_theme_override.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/locale_provider.dart';
import 'package:immich_mobile/providers/map/map_state.provider.dart';
import 'package:immich_mobile/utils/immich_app_theme.dart';

Expand Down Expand Up @@ -71,6 +72,7 @@ class _MapThemeOverideState extends ConsumerState<MapThemeOveride>
_theme = widget.themeMode ??
ref.watch(mapStateNotifierProvider.select((v) => v.themeMode));
var appTheme = ref.watch(immichThemeProvider);
final locale = ref.watch(localeProvider);

useValueChanged<ThemeMode, void>(_theme, (_, __) {
if (_theme == ThemeMode.system) {
Expand All @@ -85,8 +87,8 @@ class _MapThemeOverideState extends ConsumerState<MapThemeOveride>

return Theme(
data: _isDarkTheme
? getThemeData(colorScheme: appTheme.dark)
: getThemeData(colorScheme: appTheme.light),
? getThemeData(colorScheme: appTheme.dark, locale: locale)
: getThemeData(colorScheme: appTheme.light, locale: locale),
child: widget.mapBuilder.call(
ref.watch(
mapStateNotifierProvider.select(
Expand Down
6 changes: 5 additions & 1 deletion mobile/test/modules/map/map_theme_override_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/models/map/map_state.model.dart';
import 'package:immich_mobile/providers/locale_provider.dart';
import 'package:immich_mobile/providers/map/map_state.provider.dart';
import 'package:immich_mobile/widgets/map/map_theme_override.dart';

Expand All @@ -24,7 +25,10 @@ void main() {
setUp(() {
mapState = MapState(themeMode: ThemeMode.dark);
mapStateNotifier = MockMapStateNotifier(mapState);
overrides = [mapStateNotifierProvider.overrideWith(() => mapStateNotifier)];
overrides = [
mapStateNotifierProvider.overrideWith(() => mapStateNotifier),
localeProvider.overrideWithValue(Locale("en")),
];
});

testWidgets("Return dark theme style when theme mode is dark",
Expand Down
1 change: 1 addition & 0 deletions web/src/lib/components/asset-viewer/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type ActionMap = {
[AssetAction.ADD]: { asset: AssetResponseDto };
[AssetAction.ADD_TO_ALBUM]: { asset: AssetResponseDto; album: AlbumResponseDto };
[AssetAction.UNSTACK]: { assets: AssetResponseDto[] };
[AssetAction.KEEP_THIS_DELETE_OTHERS]: { asset: AssetResponseDto };
};

export type Action = {
Expand Down
Loading

0 comments on commit bd16873

Please sign in to comment.