Skip to content

Commit

Permalink
Merge branch 'main' into feat/notification-email-template
Browse files Browse the repository at this point in the history
  • Loading branch information
TimVanOnckelen authored Nov 29, 2024
2 parents ad7bd7b + 56d2309 commit e5b1e58
Show file tree
Hide file tree
Showing 56 changed files with 905 additions and 538 deletions.
31 changes: 14 additions & 17 deletions docker/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,26 +125,23 @@ services:
ports:
- 5432:5432
healthcheck:
test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command:
[
'postgres',
'-c',
'shared_preload_libraries=vectors.so',
'-c',
'search_path="$$user", public, vectors',
'-c',
'logging_collector=on',
'-c',
'max_wal_size=2GB',
'-c',
'shared_buffers=512MB',
'-c',
'wal_compression=on',
]
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
# immich-prometheus:
Expand Down
31 changes: 14 additions & 17 deletions docker/docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,23 @@ services:
ports:
- 5432:5432
healthcheck:
test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command:
[
'postgres',
'-c',
'shared_preload_libraries=vectors.so',
'-c',
'search_path="$$user", public, vectors',
'-c',
'logging_collector=on',
'-c',
'max_wal_size=2GB',
'-c',
'shared_buffers=512MB',
'-c',
'wal_compression=on',
]
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
restart: always

# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
Expand Down
31 changes: 14 additions & 17 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,23 @@ services:
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
healthcheck:
test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command:
[
'postgres',
'-c',
'shared_preload_libraries=vectors.so',
'-c',
'search_path="$$user", public, vectors',
'-c',
'logging_collector=on',
'-c',
'max_wal_size=2GB',
'-c',
'shared_buffers=512MB',
'-c',
'wal_compression=on',
]
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
restart: always

volumes:
Expand Down
1 change: 1 addition & 0 deletions docs/docs/developer/pr-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ When contributing code through a pull request, please check the following:
- [ ] `npm run lint` (linting via ESLint)
- [ ] `npm run format` (formatting via Prettier)
- [ ] `npm run check:svelte` (Type checking via SvelteKit)
- [ ] `npm run check:typescript` (check typescript)
- [ ] `npm test` (unit tests)

## Documentation
Expand Down
1 change: 1 addition & 0 deletions e2e/src/api/specs/server.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ describe('/server', () => {
userDeleteDelay: 7,
isInitialized: true,
externalDomain: '',
publicUsers: true,
isOnboarded: false,
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
Expand Down
9 changes: 8 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"user_usage_stats": "Account usage statistics",
"user_usage_stats_description": "View account usage statistics",
"about": "Refresh",
"account": "Account",
"account_settings": "Account Settings",
Expand Down Expand Up @@ -222,6 +224,8 @@
"send_welcome_email": "Send welcome email",
"server_external_domain_settings": "External domain",
"server_external_domain_settings_description": "Domain for public shared links, including http(s)://",
"server_public_users": "Public Users",
"server_public_users_description": "All users (name and email) are listed when adding a user to shared albums. When disabled, the user list will only be available to admin users.",
"server_settings": "Server Settings",
"server_settings_description": "Manage server settings",
"server_welcome_message": "Welcome message",
Expand Down Expand Up @@ -1312,6 +1316,7 @@
"view_all_users": "View all users",
"view_in_timeline": "View in timeline",
"view_links": "View links",
"view_name": "View",
"view_next_asset": "View next asset",
"view_previous_asset": "View previous asset",
"view_stack": "View Stack",
Expand All @@ -1325,5 +1330,7 @@
"years_ago": "{years, plural, one {# year} other {# years}} ago",
"yes": "Yes",
"you_dont_have_any_shared_links": "You don't have any shared links",
"zoom_image": "Zoom Image"
"zoom_image": "Zoom Image",
"timeline": "Timeline",
"total": "Total"
}
2 changes: 1 addition & 1 deletion mobile/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ custom_lint:
- lib/models/server_info/server_{config,disk_info,features,version}.model.dart
- lib/models/shared_link/shared_link.model.dart
- lib/providers/asset_viewer/asset_people.provider.dart
- lib/providers/authentication.provider.dart
- lib/providers/auth.provider.dart
- lib/providers/image/immich_remote_{image,thumbnail}_provider.dart
- lib/providers/map/map_state.provider.dart
- lib/providers/search/{search,search_filter}.provider.dart
Expand Down
5 changes: 5 additions & 0 deletions mobile/lib/interfaces/auth.interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'package:immich_mobile/interfaces/database.interface.dart';

abstract interface class IAuthRepository implements IDatabaseRepository {
Future<void> clearLocalData();
}
9 changes: 9 additions & 0 deletions mobile/lib/interfaces/auth_api.interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:immich_mobile/models/auth/login_response.model.dart';

abstract interface class IAuthApiRepository {
Future<LoginResponse> login(String email, String password);

Future<void> logout();

Future<void> changePassword(String newPassword);
}
Original file line number Diff line number Diff line change
@@ -1,62 +1,58 @@
class AuthenticationState {
class AuthState {
final String deviceId;
final String userId;
final String userEmail;
final bool isAuthenticated;
final String name;
final bool isAdmin;
final bool shouldChangePassword;
final String profileImagePath;
AuthenticationState({

AuthState({
required this.deviceId,
required this.userId,
required this.userEmail,
required this.isAuthenticated,
required this.name,
required this.isAdmin,
required this.shouldChangePassword,
required this.profileImagePath,
});

AuthenticationState copyWith({
AuthState copyWith({
String? deviceId,
String? userId,
String? userEmail,
bool? isAuthenticated,
String? name,
bool? isAdmin,
bool? shouldChangePassword,
String? profileImagePath,
}) {
return AuthenticationState(
return AuthState(
deviceId: deviceId ?? this.deviceId,
userId: userId ?? this.userId,
userEmail: userEmail ?? this.userEmail,
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
name: name ?? this.name,
isAdmin: isAdmin ?? this.isAdmin,
shouldChangePassword: shouldChangePassword ?? this.shouldChangePassword,
profileImagePath: profileImagePath ?? this.profileImagePath,
);
}

@override
String toString() {
return 'AuthenticationState(deviceId: $deviceId, userId: $userId, userEmail: $userEmail, isAuthenticated: $isAuthenticated, name: $name, isAdmin: $isAdmin, shouldChangePassword: $shouldChangePassword, profileImagePath: $profileImagePath)';
return 'AuthenticationState(deviceId: $deviceId, userId: $userId, userEmail: $userEmail, isAuthenticated: $isAuthenticated, name: $name, isAdmin: $isAdmin, profileImagePath: $profileImagePath)';
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is AuthenticationState &&
return other is AuthState &&
other.deviceId == deviceId &&
other.userId == userId &&
other.userEmail == userEmail &&
other.isAuthenticated == isAuthenticated &&
other.name == name &&
other.isAdmin == isAdmin &&
other.shouldChangePassword == shouldChangePassword &&
other.profileImagePath == profileImagePath;
}

Expand All @@ -68,7 +64,6 @@ class AuthenticationState {
isAuthenticated.hashCode ^
name.hashCode ^
isAdmin.hashCode ^
shouldChangePassword.hashCode ^
profileImagePath.hashCode;
}
}
30 changes: 30 additions & 0 deletions mobile/lib/models/auth/login_response.model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class LoginResponse {
final String accessToken;

final bool isAdmin;

final String name;

final String profileImagePath;

final bool shouldChangePassword;

final String userEmail;

final String userId;

LoginResponse({
required this.accessToken,
required this.isAdmin,
required this.name,
required this.profileImagePath,
required this.shouldChangePassword,
required this.userEmail,
required this.userId,
});

@override
String toString() {
return 'LoginResponse[accessToken=$accessToken, isAdmin=$isAdmin, name=$name, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, userEmail=$userEmail, userId=$userId]';
}
}
4 changes: 2 additions & 2 deletions mobile/lib/pages/common/album_options.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/album/album.provider.dart';
import 'package:immich_mobile/providers/authentication.provider.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/entities/album.entity.dart';
Expand All @@ -25,7 +25,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final sharedUsers = useState(album.sharedUsers.toList());
final owner = album.owner.value;
final userId = ref.watch(authenticationProvider).userId;
final userId = ref.watch(authProvider).userId;
final activityEnabled = useState(album.activityEnabled);
final isProcessing = useProcessingOverlay();
final isOwner = owner?.id == userId;
Expand Down
4 changes: 2 additions & 2 deletions mobile/lib/pages/common/album_viewer.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:immich_mobile/utils/immich_loading_overlay.dart';
import 'package:immich_mobile/widgets/album/album_action_filled_button.dart';
import 'package:immich_mobile/widgets/album/album_viewer_editable_title.dart';
import 'package:immich_mobile/providers/multiselect.provider.dart';
import 'package:immich_mobile/providers/authentication.provider.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/widgets/album/album_viewer_appbar.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/entities/album.entity.dart';
Expand All @@ -42,7 +42,7 @@ class AlbumViewerPage extends HookConsumerWidget {
() => ref.read(currentAlbumProvider.notifier).set(value),
),
);
final userId = ref.watch(authenticationProvider).userId;
final userId = ref.watch(authProvider).userId;
final isProcessing = useProcessingOverlay();

Future<bool> onRemoveFromAlbumPressed(Iterable<Asset> assets) async {
Expand Down
13 changes: 3 additions & 10 deletions mobile/lib/pages/common/splash_screen.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/backup/backup.provider.dart';
import 'package:immich_mobile/providers/authentication.provider.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:logging/logging.dart';

@RoutePage()
Expand All @@ -16,7 +15,6 @@ class SplashScreenPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final apiService = ref.watch(apiServiceProvider);
final serverUrl = Store.tryGet(StoreKey.serverUrl);
final endpoint = Store.tryGet(StoreKey.serverEndpoint);
final accessToken = Store.tryGet(StoreKey.accessToken);
Expand All @@ -26,14 +24,9 @@ class SplashScreenPage extends HookConsumerWidget {
bool isAuthSuccess = false;

if (accessToken != null && serverUrl != null && endpoint != null) {
apiService.setEndpoint(endpoint);

try {
isAuthSuccess = await ref
.read(authenticationProvider.notifier)
.setSuccessLoginInfo(
isAuthSuccess = await ref.read(authProvider.notifier).saveAuthInfo(
accessToken: accessToken,
serverUrl: serverUrl,
);
} catch (error, stackTrace) {
log.severe(
Expand All @@ -53,7 +46,7 @@ class SplashScreenPage extends HookConsumerWidget {
log.severe(
'Unable to login using offline or online methods - Logging out completely',
);
ref.read(authenticationProvider.notifier).logout();
ref.read(authProvider.notifier).logout();
context.replaceRoute(const LoginRoute());
return;
}
Expand Down
Loading

0 comments on commit e5b1e58

Please sign in to comment.