Skip to content

Commit

Permalink
WIP deep links (android only)
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-anders committed Jan 12, 2025
1 parent fcc09d4 commit c5a3b59
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 0 deletions.
30 changes: 30 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
<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:host="lichess.org" android:scheme="https"
android:pathPrefix="/player" />
<!-- TODO comment in once we support tournaments -->
<!--<data-->
<!-- android:host="lichess.org" android:scheme="https"-->
<!-- android:pathPrefix="/tournament" />-->
<data
android:host="lichess.org" android:scheme="https"
android:pathPrefix="/training" />
<data
android:host="lichess.org" android:scheme="https"
android:pathPrefix="/study" />
<!-- Either game or challenge -->
<data
android:host="lichess.org" android:scheme="https"
android:pathPattern="/........" />
<data
android:host="lichess.org" android:scheme="https"
android:pathPattern="/......../black" />
<data
android:host="lichess.org" android:scheme="https"
android:pathPattern="/......../white" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
Expand Down
1 change: 1 addition & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ targets:
- lib/src/model/**/*.dart
- lib/src/network/*.dart
- lib/src/db/*.dart
- lib/src/app_links.dart
- lib/src/**/*_providers.dart
69 changes: 69 additions & 0 deletions lib/src/app_links.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'dart:async';

import 'package:app_links/app_links.dart' as lib_app_links;
import 'package:dartchess/dartchess.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/widgets.dart';
import 'package:lichess_mobile/src/model/common/id.dart';
import 'package:lichess_mobile/src/model/puzzle/puzzle_angle.dart';
import 'package:lichess_mobile/src/view/game/archived_game_screen.dart';
import 'package:lichess_mobile/src/view/puzzle/puzzle_screen.dart';
import 'package:lichess_mobile/src/view/study/study_screen.dart';
import 'package:lichess_mobile/src/view/game/game_screen.dart';
import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'app_links.g.dart';

final _logger = Logger('App Links');

WidgetBuilder? resolveAppLinkUri(Uri appLinkUri) {
if (appLinkUri.pathSegments.length < 2 || appLinkUri.pathSegments[1].isEmpty) {
return null;
}

final id = appLinkUri.pathSegments[1];

switch (appLinkUri.pathSegments[0]) {
case 'study':
return (context) => StudyScreen(id: StudyId(id));
case 'training':
return (context) => PuzzleScreen(angle: PuzzleAngle.fromKey('mix'), puzzleId: PuzzleId(id));
case _:
{
final gameId = GameId(appLinkUri.pathSegments[0]);
final orientation = appLinkUri.pathSegments.getOrNull(2);
if (gameId.isValid) {
return (context) => ArchivedGameScreen(
gameId: gameId,
// TODO preload game and check if it's our own game, then set orientation to our pov
orientation: orientation == 'black' ? Side.black : Side.white,
);
} else {
// TODO if it's not a game, it's a challenge
}
}
}
}

/// TODO doc
@Riverpod(keepAlive: true)
class AppLinks extends _$AppLinks {
StreamSubscription<Uri>? _appLinkSubscription;

@override
Future<Uri?> build() {
ref.onDispose(() {
_appLinkSubscription?.cancel();
});

_appLinkSubscription?.cancel();

_appLinkSubscription = lib_app_links.AppLinks().uriLinkStream.listen((uri) {
_logger.info('Received new app link: $uri');
state = AsyncValue.data(uri);
});

return lib_app_links.AppLinks().getInitialLink();
}
}
16 changes: 16 additions & 0 deletions lib/src/navigation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import 'package:lichess_mobile/src/view/settings/settings_tab_screen.dart';
import 'package:lichess_mobile/src/view/tools/tools_tab_screen.dart';
import 'package:lichess_mobile/src/view/watch/watch_tab_screen.dart';
import 'package:lichess_mobile/src/widgets/feedback.dart';
import 'package:lichess_mobile/src/utils/navigation.dart';
import 'package:lichess_mobile/src/app_links.dart';

enum BottomTab {
home,
Expand Down Expand Up @@ -127,6 +129,20 @@ class BottomNavScaffold extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final currentTab = ref.watch(currentBottomTabProvider);

ref.listen(appLinksProvider, (_, appLinkUri) {
switch (appLinkUri) {
case AsyncData(:final Uri value):
{
final builder = resolveAppLinkUri(value);
if (builder != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
pushPlatformRoute(context, rootNavigator: true, builder: builder);
});
}
}
}
});

switch (Theme.of(context).platform) {
case TargetPlatform.android:
return Scaffold(
Expand Down
40 changes: 40 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
app_links:
dependency: "direct main"
description:
name: app_links
sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950"
url: "https://pub.dev"
source: hosted
version: "6.3.3"
app_links_linux:
dependency: transitive
description:
name: app_links_linux
sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
url: "https://pub.dev"
source: hosted
version: "1.0.3"
app_links_platform_interface:
dependency: transitive
description:
name: app_links_platform_interface
sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
app_links_web:
dependency: transitive
description:
name: app_links_web
sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
url: "https://pub.dev"
source: hosted
version: "1.0.4"
app_settings:
dependency: "direct main"
description:
Expand Down Expand Up @@ -747,6 +779,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
gtk:
dependency: transitive
description:
name: gtk
sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
url: "https://pub.dev"
source: hosted
version: "2.1.0"
hotreloader:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ environment:
flutter: "3.28.0-0.1.pre"

dependencies:
app_links: ^6.3.3
app_settings: ^5.1.1
async: ^2.10.0
auto_size_text: ^3.0.0
Expand Down

0 comments on commit c5a3b59

Please sign in to comment.