Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mobile): Auto switching server URLs #14437

Merged
merged 40 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c911211
feat: new settings card
alextran1502 Nov 23, 2024
4fbc146
Add networking settings
alextran1502 Nov 23, 2024
6acd215
wip
alextran1502 Nov 24, 2024
b0d34db
Merge branch 'main' of github.com:immich-app/immich into networking-s…
alextran1502 Nov 26, 2024
ff4db18
Merge branch 'main' of github.com:immich-app/immich into networking-s…
alextran1502 Nov 26, 2024
f1a99c8
feat: add correct permission to get WIFI name
alextran1502 Nov 27, 2024
59ca288
feat: validate aux endpoint
alextran1502 Nov 27, 2024
fc9dd6d
feat: validation on the go
alextran1502 Nov 27, 2024
6fb346e
reordering
alextran1502 Nov 27, 2024
0366b78
feat: new card UI
alextran1502 Nov 27, 2024
2db7942
new style
alextran1502 Nov 28, 2024
4cb8351
feat: enable switch
alextran1502 Nov 28, 2024
adbe438
refactor
alextran1502 Nov 28, 2024
4eaa8ca
visual for when the feature is disabled
alextran1502 Nov 28, 2024
6c4eb59
update
alextran1502 Nov 29, 2024
6ad6052
Save local connection info
alextran1502 Nov 30, 2024
4b80524
feat: auto switching endpoint on app resumed
alextran1502 Nov 30, 2024
22f1a61
feat: auto switch endpoint when app restart, handling endpoint offline
alextran1502 Dec 1, 2024
6c3d1c3
chore: clean up
alextran1502 Dec 1, 2024
15e5572
linting
alextran1502 Dec 1, 2024
f780548
pr feedback
alextran1502 Dec 2, 2024
01c2cc0
update rules
alextran1502 Dec 2, 2024
35b4296
Merge branch 'main' of github.com:immich-app/immich into networking-s…
alextran1502 Dec 2, 2024
ca94cd6
chore: translations strings
alextran1502 Dec 2, 2024
58a6ca6
remove toast message when switching endpoint
alextran1502 Dec 2, 2024
72ba8ac
log connection info instead
alextran1502 Dec 2, 2024
95f87a5
adding tests
alextran1502 Dec 2, 2024
a84f35a
Add more tests
alextran1502 Dec 2, 2024
32e1e88
Linting
alextran1502 Dec 2, 2024
04feb33
Background upload: android
alextran1502 Dec 3, 2024
9fa8972
Background upload: android
alextran1502 Dec 3, 2024
a352d8e
Background upload: ios wip
alextran1502 Dec 3, 2024
82432d3
Background upload: ios
alextran1502 Dec 4, 2024
dc9047e
permission request and clean up
alextran1502 Dec 4, 2024
a596198
chore: remove saved info on signout
alextran1502 Dec 4, 2024
23e6c24
merge main
alextran1502 Dec 4, 2024
900da27
merge main
alextran1502 Dec 4, 2024
c77ccc5
pr feedback
alextran1502 Dec 5, 2024
93e086f
lint
alextran1502 Dec 5, 2024
55f437a
pr feedback
alextran1502 Dec 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mobile/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ custom_lint:
- lib/widgets/album/album_thumbnail_listtile.dart
- lib/widgets/forms/login/login_form.dart
- lib/widgets/search/search_filter/{camera_picker,location_picker,people_picker}.dart
- lib/services/auth.service.dart # on ApiException

dart_code_metrics:
metrics:
Expand Down
1 change: 1 addition & 0 deletions mobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- Foreground service permission -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Expand Down
14 changes: 10 additions & 4 deletions mobile/assets/i18n/en-US.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"networking_settings": "Networking",
"networking_subtitle": "Manage the server endpoint settings",
"advanced_settings_tile_subtitle": "Manage advanced settings",
"asset_viewer_settings_subtitle": "Manage your detail viewer settings",
"backup_setting_subtitle": "Manage background and foreground upload settings",
"setting_languages_subtitle": "Change the app's language",
"setting_notifications_subtitle": "Manage your notification settings",
"preferences_settings_subtitle": "Manage the app's preferences",
"asset_list_settings_subtitle": "Manage the look of the timeline",
"action_common_back": "Back",
"action_common_cancel": "Cancel",
"action_common_clear": "Clear",
Expand All @@ -16,7 +25,6 @@
"advanced_settings_proxy_headers_title": "Proxy Headers",
"advanced_settings_self_signed_ssl_subtitle": "Skips SSL certificate verification for the server endpoint. Required for self-signed certificates.",
"advanced_settings_self_signed_ssl_title": "Allow self-signed SSL certificates",
"advanced_settings_tile_subtitle": "Advanced user's settings",
"advanced_settings_tile_title": "Advanced",
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
"advanced_settings_troubleshooting_title": "Troubleshooting",
Expand Down Expand Up @@ -56,7 +64,6 @@
"asset_list_layout_settings_group_by_month": "Month",
"asset_list_layout_settings_group_by_month_day": "Month + day",
"asset_list_layout_sub_title": "Layout",
"asset_list_settings_subtitle": "Photo grid layout settings",
"asset_list_settings_title": "Photo Grid",
"asset_restored_successfully": "Asset restored successfully",
"assets_deleted_permanently": "{} asset(s) deleted permanently",
Expand Down Expand Up @@ -489,7 +496,6 @@
"setting_notifications_notify_seconds": "{} seconds",
"setting_notifications_single_progress_subtitle": "Detailed upload progress information per asset",
"setting_notifications_single_progress_title": "Show background backup detail progress",
"setting_notifications_subtitle": "Adjust your notification preferences",
"setting_notifications_title": "Notifications",
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
"setting_notifications_total_progress_title": "Show background backup total progress",
Expand Down Expand Up @@ -622,4 +628,4 @@
"viewer_remove_from_stack": "Remove from Stack",
"viewer_stack_use_as_main_asset": "Use as Main Asset",
"viewer_unstack": "Un-Stack"
}
}
8 changes: 8 additions & 0 deletions mobile/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ post_install do |installer|

## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_CRITICAL_ALERTS=1'

## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
## macro.
##
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
'PERMISSION_LOCATION_WHENINUSE=0',
]

end
Expand Down
8 changes: 7 additions & 1 deletion mobile/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ PODS:
- maplibre_gl (0.0.1):
- Flutter
- MapLibre (= 5.14.0-pre3)
- network_info_plus (0.0.1):
- Flutter
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
Expand Down Expand Up @@ -115,6 +117,7 @@ DEPENDENCIES:
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
- maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`)
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
Expand Down Expand Up @@ -168,6 +171,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/isar_flutter_libs/ios"
maplibre_gl:
:path: ".symlinks/plugins/maplibre_gl/ios"
network_info_plus:
:path: ".symlinks/plugins/network_info_plus/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
Expand Down Expand Up @@ -210,6 +215,7 @@ SPEC CHECKSUMS:
isar_flutter_libs: fdf730ca925d05687f36d7f1d355e482529ed097
MapLibre: 620fc933c1d6029b33738c905c1490d024e5d4ef
maplibre_gl: a2efec727dd340e4c65e26d2b03b584f14881fd9
network_info_plus: 6613d9d7cdeb0e6f366ed4dbe4b3c51c52d567a9
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
Expand All @@ -226,6 +232,6 @@ SPEC CHECKSUMS:
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1

PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
PODFILE CHECKSUM: ce7b774cad91ffe346f37165386904091e110c79

COCOAPODS: 1.15.2
6 changes: 5 additions & 1 deletion mobile/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E0E99CDC17B3EB7FA8BA2332 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
F7101BB0391A314774615E89 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
FA9973382CF6DF4B000EF859 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
FAC7416727DB9F5500C668D8 /* RunnerProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerProfile.entitlements; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -126,6 +127,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
FA9973382CF6DF4B000EF859 /* Runner.entitlements */,
65DD438629917FAD0047FFA8 /* BackgroundSync */,
FAC7416727DB9F5500C668D8 /* RunnerProfile.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
Expand Down Expand Up @@ -541,6 +543,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 184;
Expand All @@ -553,7 +556,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.121.0;
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.debug;
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.vdebug;
PRODUCT_NAME = "Immich-Debug";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
Expand All @@ -569,6 +572,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 184;
Expand Down
6 changes: 6 additions & 0 deletions mobile/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,11 @@
<true/>
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSLocationUsageDescription</key>
<string>We require this permission to access the WIFI information</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We require this permission to access the WIFI information</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We require this permission to access the WIFI information</string>
</dict>
</plist>
5 changes: 4 additions & 1 deletion mobile/ios/Runner/Runner.entitlements
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>com.apple.developer.networking.wifi-info</key>
<true/>
</dict>
</plist>
2 changes: 2 additions & 0 deletions mobile/ios/Runner/RunnerProfile.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.networking.wifi-info</key>
<true/>
</dict>
</plist>
6 changes: 6 additions & 0 deletions mobile/lib/entities/store.entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ enum StoreKey<T> {
colorfulInterface<bool>(130, type: bool),

syncAlbums<bool>(131, type: bool),

// Auto endpoint switching
autoEndpointSwitching<bool>(132, type: bool),
preferredWifiName<String>(133, type: String),
localEndpoint<String>(134, type: String),
externalEndpointList<String>(135, type: String),
;

const StoreKey(
Expand Down
4 changes: 4 additions & 0 deletions mobile/lib/extensions/build_context_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ extension ContextHelper on BuildContext {

// Managing focus within the widget tree from the current context
FocusScopeNode get focusScope => FocusScope.of(this);

// Show SnackBars from the current context
void showSnackBar(SnackBar snackBar) =>
ScaffoldMessenger.of(this).showSnackBar(snackBar);
}
1 change: 1 addition & 0 deletions mobile/lib/interfaces/auth.interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import 'package:immich_mobile/interfaces/database.interface.dart';

abstract interface class IAuthRepository implements IDatabaseRepository {
Future<void> clearLocalData();
String getAccessToken();
}
8 changes: 8 additions & 0 deletions mobile/lib/interfaces/network.interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
abstract interface class INetworkRepository {
Future<String?> getWifiName();
Future<String?> getWifiIp();

Future<bool> isWifiConnected();
Future<bool> isVpnConnected();
Future<bool> isMobileDataConnected();
alextran1502 marked this conversation as resolved.
Show resolved Hide resolved
}
105 changes: 105 additions & 0 deletions mobile/lib/models/auth/auxilary_endpoint.model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

class AuxilaryEndpoint {
final String url;
final AuxCheckStatus status;

AuxilaryEndpoint({
required this.url,
required this.status,
});

AuxilaryEndpoint copyWith({
String? url,
AuxCheckStatus? status,
}) {
return AuxilaryEndpoint(
url: url ?? this.url,
status: status ?? this.status,
);
}

@override
String toString() => 'AuxilaryEndpoint(url: $url, status: $status)';

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

return other.url == url && other.status == status;
}

@override
int get hashCode => url.hashCode ^ status.hashCode;

Map<String, dynamic> toMap() {
return <String, dynamic>{
'url': url,
'status': status.toMap(),
};
}

factory AuxilaryEndpoint.fromMap(Map<String, dynamic> map) {
return AuxilaryEndpoint(
url: map['url'] as String,
status: AuxCheckStatus.fromMap(map['status'] as Map<String, dynamic>),
);
}

String toJson() => json.encode(toMap());

factory AuxilaryEndpoint.fromJson(String source) =>
AuxilaryEndpoint.fromMap(json.decode(source) as Map<String, dynamic>);
}

class AuxCheckStatus {
final String name;
AuxCheckStatus({
required this.name,
});
const AuxCheckStatus._(this.name);

static const loading = AuxCheckStatus._('loading');
static const valid = AuxCheckStatus._('valid');
static const error = AuxCheckStatus._('error');
static const unknown = AuxCheckStatus._('unknown');

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

return other.name == name;
}

@override
int get hashCode => name.hashCode;

AuxCheckStatus copyWith({
String? name,
}) {
return AuxCheckStatus(
name: name ?? this.name,
);
}

Map<String, dynamic> toMap() {
return <String, dynamic>{
'name': name,
};
}

factory AuxCheckStatus.fromMap(Map<String, dynamic> map) {
return AuxCheckStatus(
name: map['name'] as String,
);
}

String toJson() => json.encode(toMap());

factory AuxCheckStatus.fromJson(String source) =>
AuxCheckStatus.fromMap(json.decode(source) as Map<String, dynamic>);

@override
String toString() => 'AuxCheckStatus(name: $name)';
}
Loading
Loading