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

[mob][photos] Implement deep linking for public links #3386

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
130418e
[mob][photos] add configurations for opening links in mobile app
AmanRajSinghMourya Sep 21, 2024
add3278
[mob][photos] fuction to handle deeplinks
AmanRajSinghMourya Sep 21, 2024
fd3991b
[mob][photos] updated public_url.dart to store additional information…
AmanRajSinghMourya Sep 21, 2024
119ae6d
[mob][photos] remove redundant logging
AmanRajSinghMourya Sep 23, 2024
886d7e9
[mob][photos] minor changes
AmanRajSinghMourya Sep 24, 2024
71e87ad
[mob][photos] Updated public_url to save shared public link data
AmanRajSinghMourya Sep 24, 2024
bda3ec2
[mob][photos] added a new gallery type for shared public link
AmanRajSinghMourya Sep 24, 2024
a8d1a80
Merge branch 'main' into deeplinks
AmanRajSinghMourya Sep 25, 2024
d6bed95
[mob][photos] made shared_public_collection to handle public link sep…
AmanRajSinghMourya Sep 25, 2024
1bcacc9
[mob][photos] fixed album name not displaying and app bar fixes
AmanRajSinghMourya Sep 27, 2024
ac656cf
[mob][photos] cached public collectionID
AmanRajSinghMourya Sep 27, 2024
38311cf
[mob][photos] show error dialog when something goes wrong
AmanRajSinghMourya Sep 27, 2024
2b85630
[mob][photos] skip deleted files
AmanRajSinghMourya Oct 1, 2024
0ace359
[mob][photos] media_extension fix to support deeplinks
AmanRajSinghMourya Oct 5, 2024
4f19c40
Media extension fix for deeplinks (#3584)
ashilkn Oct 7, 2024
27bce43
Merge branch 'main' into deeplinks
ashilkn Oct 7, 2024
e6590a7
[mob][photos] Wrap GalleryFilesState over SharedPublicCollectionPage …
ashilkn Oct 7, 2024
22737f1
[mob][photos] Hide file owner if file is a public shared file
AmanRajSinghMourya Oct 8, 2024
45ba656
[mob][photos] hide owner avatar if file is from a public link
AmanRajSinghMourya Oct 8, 2024
6ea51a7
[mob][photos] using ReceiveSharingIntent to listen to deeplink & show…
AmanRajSinghMourya Oct 8, 2024
86b70ab
[mob][photos] hide "add photos" for deeplinks, will implement after v1
AmanRajSinghMourya Oct 9, 2024
191a03c
[mob][photos] change accepted links from albums.ente.io to albums.ent…
AmanRajSinghMourya Oct 17, 2024
641aaf9
[mob][photos] Resolve merge conflicts and merge main
ashilkn Oct 18, 2024
24bb6f2
Merge branch 'main' into deeplinks
ashilkn Oct 24, 2024
7be790d
[mob][photos] Bump up to v0.9.54
ashilkn Oct 24, 2024
9d045f5
[mob][photos] resolve merge conflicts
AmanRajSinghMourya Oct 24, 2024
020033b
[mob][photos] Ask permission to enable deeplinks for github & fdroid …
AmanRajSinghMourya Oct 24, 2024
621df27
[mob][photos] added android_intent_plus to open app settings for perm…
AmanRajSinghMourya Oct 24, 2024
10ca0b7
Merge branch 'deeplinks' of https://github.com/ente-io/ente into deep…
AmanRajSinghMourya Oct 24, 2024
b3f332c
[mob][photos] open owned collection without fetching from the server
AmanRajSinghMourya Oct 26, 2024
c849ea1
[mob][photos] use better dialog widget to ask permissions
AmanRajSinghMourya Oct 26, 2024
b05373c
[mob][photos] Change configuration in iOS to open albums.ente.sh inst…
ashilkn Oct 28, 2024
a86b6dd
[mob][photos] Resolve merge conflicts and merge main
ashilkn Nov 18, 2024
e7d6ea0
[mob][photos] Cancel subscription to linkStream in passkey page after…
ashilkn Nov 18, 2024
0a6e1a5
[mob][photos] Configure clicking on albums.ente.sh links to open up t…
ashilkn Nov 19, 2024
cda749d
[mob][photos] Remove stale code
ashilkn Nov 20, 2024
1db6c99
[mob][photos] Handle deep link from public album by opening the album…
ashilkn Nov 20, 2024
6c7d403
[mob][photos] Fix red screen error caused by the dialog asking for pe…
ashilkn Nov 21, 2024
45bf98c
Merge branch 'main' into deeplinks
ashilkn Nov 21, 2024
7d96f38
[mob][photos] Only show dialog asking for permission to open public l…
ashilkn Nov 21, 2024
5056977
[mob][photos] Change copies
ashilkn Nov 21, 2024
8c36fdb
[mob][photos] Fix null check used in null value error
ashilkn Nov 21, 2024
a53efda
[mob][photos] Update media_extension ref
ashilkn Nov 21, 2024
aaab52c
Merge branch 'main' into deeplinks
ashilkn Nov 21, 2024
4706fff
[mob][photos] Fix issue when opening links in app
ashilkn Nov 22, 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
12 changes: 11 additions & 1 deletion mobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
android:fullBackupContent="false"
android:largeHeap="true">

<activity android:name=".MainActivity" android:launchMode="singleTop"
<activity android:name=".MainActivity" android:launchMode="singleTask"
android:theme="@style/LaunchTheme"
android:exported="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down Expand Up @@ -46,6 +46,16 @@
<data android:mimeType="video/*" />
</intent-filter>

<!-- App Link -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="albums.ente.sh"/>
</intent-filter>

<!-- file provider to share files having a file:// URI -->

<!--Filter
Expand Down
225 changes: 116 additions & 109 deletions mobile/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
@@ -1,118 +1,125 @@
<?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>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.transistorsoft.fetch</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Ente Photos</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>MinimumOSVersion</key>
<string>12.1</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlegmail</string>
<string>x-dispatch</string>
<string>readdle-spark</string>
<string>airmail</string>
<string>ms-outlook</string>
<string>ymail</string>
<string>fastmail</string>
<string>superhuman</string>
<string>protonmail</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>io.ente.frame</string>
<key>CFBundleURLSchemes</key>
<array>
<string>ente</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
<true/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.transistorsoft.fetch</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Ente Photos</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>MinimumOSVersion</key>
<string>12.1</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlegmail</string>
<string>x-dispatch</string>
<string>readdle-spark</string>
<string>airmail</string>
<string>ms-outlook</string>
<string>ymail</string>
<string>fastmail</string>
<string>superhuman</string>
<string>protonmail</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>io.ente.frame</string>
<key>CFBundleURLSchemes</key>
<array>
<string>ente</string>
</array>
</dict>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>CFBundleURLName</key>
<string>albums.ente.sh</string>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
</dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>FLTEnableImpeller</key>
<true />
<key>FLTEnableWideGamut</key>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>Please allow ente to lock itself with FaceID or TouchID</string>
<key>NSCameraUsageDescription</key>
<string>Please allow access to your camera so that you can take photos within ente</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please allow access to your photos so that ente can encrypt and back them up.</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
<true/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSBonjourServices</key>
<array>
<string>_googlecast._tcp</string>
<string>_F5BCEC64._googlecast._tcp</string>
</array>

<key>NSLocalNetworkUsageDescription</key>
<string>${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi
network.</string>
</dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>FLTEnableImpeller</key>
<true/>
<key>FLTEnableWideGamut</key>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>Please allow ente to lock itself with FaceID or TouchID</string>
<key>NSCameraUsageDescription</key>
<string>Please allow access to your camera so that you can take photos within ente</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please allow access to your photos so that ente can encrypt and back them up.</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>NSBonjourServices</key>
<array>
<string>_googlecast._tcp</string>
<string>_F5BCEC64._googlecast._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi
network.</string>
</dict>
</plist>
1 change: 1 addition & 0 deletions mobile/ios/Runner/Runner.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<key>com.apple.developer.associated-domains</key>
<array>
<string>webcredentials:web.ente.io</string>
<string>applinks:albums.ente.sh</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
Expand Down
7 changes: 6 additions & 1 deletion mobile/lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,12 @@ class _EnteAppState extends State<EnteApp> with WidgetsBindingObserver {
theme: lightTheme,
darkTheme: dartTheme,
home: AppLifecycleService.instance.mediaExtensionAction.action ==
IntentAction.view
IntentAction.view &&
(AppLifecycleService.instance.mediaExtensionAction.type ==
MediaType.image ||
AppLifecycleService
.instance.mediaExtensionAction.type ==
MediaType.video)
? const FileViewer()
: const HomeWidget(),
debugShowCheckedModeBanner: false,
Expand Down
2 changes: 2 additions & 0 deletions mobile/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import "package:photos/l10n/l10n.dart";
import "package:photos/service_locator.dart";
import 'package:photos/services/app_lifecycle_service.dart';
import 'package:photos/services/collections_service.dart';
import "package:photos/services/deeplink_service.dart";
import 'package:photos/services/favorites_service.dart';
import "package:photos/services/filedata/filedata_service.dart";
import 'package:photos/services/home_widget_service.dart';
Expand Down Expand Up @@ -212,6 +213,7 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
_logger.info("_logFGHeartBeatInfo done $tlog");
unawaited(_scheduleHeartBeat(preferences, isBackground));
NotificationService.instance.init(preferences);
DeeplinkService.instance.init(preferences);
AppLifecycleService.instance.init(preferences);
if (isBackground) {
AppLifecycleService.instance.onAppInBackground('init via: $via $tlog');
Expand Down
46 changes: 46 additions & 0 deletions mobile/lib/models/api/collection/public_url.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
class SharedPublicURL {
String? nonce;
int? opsLimit;
int? memLimit;

SharedPublicURL({
this.nonce,
this.opsLimit,
this.memLimit,
});

Map<String, dynamic> toMap() {
return {
'nonce': nonce,
'opsLimit': opsLimit,
'memLimit': memLimit,
};
}

static SharedPublicURL? fromMap(Map<String, dynamic>? map) {
if (map == null) return null;

return SharedPublicURL(
nonce: map['nonce'],
opsLimit: map['opsLimit'],
memLimit: map['memLimit'],
);
}
}

class PublicURL {
String url;
int deviceLimit;
int validTill;
bool enableDownload;
bool enableCollect;
bool passwordEnabled;
String? nonce;
int? opsLimit;
int? memLimit;
SharedPublicURL? sharedPublicURL;

PublicURL({
required this.url,
Expand All @@ -13,6 +47,10 @@ class PublicURL {
this.enableDownload = true,
this.passwordEnabled = false,
this.enableCollect = false,
this.nonce,
this.opsLimit,
this.memLimit,
this.sharedPublicURL,
});

Map<String, dynamic> toMap() {
Expand All @@ -23,6 +61,10 @@ class PublicURL {
'enableDownload': enableDownload,
'passwordEnabled': passwordEnabled,
'enableCollect': enableCollect,
'nonce': nonce,
'memLimit': memLimit,
'opsLimit': opsLimit,
'sharedPublicURL': sharedPublicURL?.toMap(),
};
}

Expand All @@ -42,6 +84,10 @@ class PublicURL {
enableDownload: map['enableDownload'] ?? true,
passwordEnabled: map['passwordEnabled'] ?? false,
enableCollect: map['enableCollect'] ?? false,
nonce: map['nonce'],
opsLimit: map['opsLimit'],
memLimit: map['memLimit'],
sharedPublicURL: SharedPublicURL.fromMap(map),
);
}
}
14 changes: 14 additions & 0 deletions mobile/lib/models/collection/collection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ class Collection {
return (owner?.id ?? 0) == userID;
}

bool isPublicDownload() {
if (publicURLs == null || publicURLs!.isEmpty) {
return false;
}
return publicURLs?.first?.enableDownload ?? true;
}

bool isEnableCollect() {
if (publicURLs == null || publicURLs!.isEmpty) {
return false;
}
return publicURLs?.first?.enableDownload ?? false;
}

CollectionParticipantRole getRole(int userID) {
if (isOwner(userID)) {
return CollectionParticipantRole.owner;
Expand Down
Loading