From db95de88299eca2f35395fc4cdc0af91175a0ab2 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 16 Apr 2024 09:55:01 +0530
Subject: [PATCH 001/367] [mob][photos] Add cast pkg dependency
---
mobile/pubspec.lock | 25 +++++++++++++++++++++++++
mobile/pubspec.yaml | 4 ++++
2 files changed, 29 insertions(+)
diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock
index bab6f37ca..3c9ff792c 100644
--- a/mobile/pubspec.lock
+++ b/mobile/pubspec.lock
@@ -209,6 +209,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.1"
+ cast:
+ dependency: "direct main"
+ description:
+ path: "."
+ ref: multicast_version
+ resolved-ref: "1f39cd4d6efa9363e77b2439f0317bae0c92dda1"
+ url: "https://github.com/guyluz11/flutter_cast.git"
+ source: git
+ version: "2.0.9"
characters:
dependency: transitive
description:
@@ -1416,6 +1425,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
+ multicast_dns:
+ dependency: transitive
+ description:
+ name: multicast_dns
+ sha256: "316cc47a958d4bd3c67bd238fe8b44fdfb6133bad89cb191c0c3bd3edb14e296"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.2+6"
nested:
dependency: transitive
description:
@@ -1729,6 +1746,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
+ protobuf:
+ dependency: transitive
+ description:
+ name: protobuf
+ sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
provider:
dependency: "direct main"
description:
diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml
index f1575bdf8..bc0d4ba2d 100644
--- a/mobile/pubspec.yaml
+++ b/mobile/pubspec.yaml
@@ -27,6 +27,10 @@ dependencies:
battery_info: ^1.1.1
bip39: ^1.0.6
cached_network_image: ^3.0.0
+ cast:
+ git:
+ url: https://github.com/guyluz11/flutter_cast.git
+ ref: multicast_version
chewie:
git:
url: https://github.com/ente-io/chewie.git
From f645fff31c53c8f5dab6ad52102c589c67882e45 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 16 Apr 2024 15:38:41 +0530
Subject: [PATCH 002/367] [mob][photos] Add hook to show cast devices
---
mobile/ios/Runner/Info.plist | 9 +++++
.../gallery/gallery_app_bar_widget.dart | 38 +++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/mobile/ios/Runner/Info.plist b/mobile/ios/Runner/Info.plist
index 037996520..cdbc23774 100644
--- a/mobile/ios/Runner/Info.plist
+++ b/mobile/ios/Runner/Info.plist
@@ -105,5 +105,14 @@
UIApplicationSupportsIndirectInputEvents
+ NSBonjourServices
+
+ _googlecast._tcp
+ F5BCEC64._googlecast._tcp
+
+
+ NSLocalNetworkUsageDescription
+ ${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi
+ network.
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 1026bd7fd..aa09e49b2 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
+import "package:cast/device.dart";
+import "package:cast/discovery_service.dart";
import "package:flutter/cupertino.dart";
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
@@ -576,6 +578,9 @@ class _GalleryAppBarWidgetState extends State {
),
);
}
+ if (widget.collection != null) {
+ actions.add(castWidget(context));
+ }
if (items.isNotEmpty) {
actions.add(
PopupMenuButton(
@@ -642,6 +647,39 @@ class _GalleryAppBarWidgetState extends State {
return actions;
}
+ Widget castWidget(BuildContext context) {
+ return FutureBuilder>(
+ future: CastDiscoveryService().search(),
+ builder: (context, snapshot) {
+ if (snapshot.hasError) {
+ return Center(
+ child: Text(
+ 'Error: ${snapshot.error.toString()}',
+ ),
+ );
+ } else if (!snapshot.hasData) {
+ return const Center(
+ child: CircularProgressIndicator(),
+ );
+ }
+
+ if (snapshot.data!.isEmpty) {
+ return const Text('No device');
+ }
+
+ return Column(
+ children: snapshot.data!.map((device) {
+ return Text(device.name);
+
+ }).toList(),
+ );
+ },
+ );
+ }
+
+ Future _connectToYourApp(
+ BuildContext contect, CastDevice device,) async {}
+
Future onCleanUncategorizedClick(BuildContext buildContext) async {
final actionResult = await showChoiceActionSheet(
context,
From da1d778eeb1562080c238b5c62a7097be0caba64 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Mon, 22 Apr 2024 10:47:49 +0530
Subject: [PATCH 003/367] [mob][photos] Add hook to connect to cast device
---
.../gallery/gallery_app_bar_widget.dart | 46 +++++++++++++++++--
1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index aa09e49b2..5431e15a2 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -4,6 +4,8 @@ import 'dart:math' as math;
import "package:cast/device.dart";
import "package:cast/discovery_service.dart";
+import "package:cast/session.dart";
+import "package:cast/session_manager.dart";
import "package:flutter/cupertino.dart";
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
@@ -669,8 +671,16 @@ class _GalleryAppBarWidgetState extends State {
return Column(
children: snapshot.data!.map((device) {
- return Text(device.name);
-
+ return GestureDetector(
+ onTap: () async {
+ try {
+ await _connectToYourApp(context, device);
+ } catch (e) {
+ showGenericErrorDialog(context: context, error: e).ignore();
+ }
+ },
+ child: Text( device.name),
+ );
}).toList(),
);
},
@@ -678,7 +688,37 @@ class _GalleryAppBarWidgetState extends State {
}
Future _connectToYourApp(
- BuildContext contect, CastDevice device,) async {}
+ BuildContext context,
+ CastDevice object,
+ ) async {
+ final session = await CastSessionManager().startSession(object);
+
+ session.stateStream.listen((state) {
+ if (state == CastSessionState.connected) {
+ const snackBar = SnackBar(content: Text('Connected'));
+ ScaffoldMessenger.of(context).showSnackBar(snackBar);
+
+ _sendPairingRequestToTV(session);
+ }
+ });
+
+ session.messageStream.listen((message) {
+ print('receive message: $message');
+ });
+
+ session.sendMessage(CastSession.kNamespaceReceiver, {
+ 'type': 'LAUNCH',
+ 'appId': 'F5BCEC64', // set the appId of your app here
+ });
+
+ _sendPairingRequestToTV(session);
+ }
+
+ void _sendPairingRequestToTV(CastSession session) {
+ print('_sendMessageToYourApp');
+
+ session.sendMessage('urn:x-cast:pair-request', {});
+ }
Future onCleanUncategorizedClick(BuildContext buildContext) async {
final actionResult = await showChoiceActionSheet(
From 89646ac4698820f86574a916840f979049a1267a Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:55:22 +0530
Subject: [PATCH 004/367] [mob][cast] Refactor + add multiple cast plugin to
gracefully handle fdroid
---
mobile/lib/service_locator.dart | 28 +-
.../gallery/gallery_app_bar_widget.dart | 42 +--
mobile/plugins/ente_cast/.metadata | 10 +
.../plugins/ente_cast/analysis_options.yaml | 1 +
mobile/plugins/ente_cast/lib/ente_cast.dart | 1 +
mobile/plugins/ente_cast/lib/src/service.dart | 7 +
mobile/plugins/ente_cast/pubspec.yaml | 19 +
mobile/plugins/ente_cast_none/.metadata | 10 +
.../ente_cast_none/analysis_options.yaml | 1 +
.../ente_cast_none/lib/ente_cast_none.dart | 1 +
.../ente_cast_none/lib/src/service.dart | 17 +
mobile/plugins/ente_cast_none/pubspec.yaml | 18 +
mobile/plugins/ente_cast_normal/.metadata | 10 +
.../ente_cast_normal/analysis_options.yaml | 1 +
.../lib/ente_cast_normal.dart | 1 +
.../ente_cast_normal/lib/src/service.dart | 37 ++
mobile/plugins/ente_cast_normal/pubspec.lock | 333 ++++++++++++++++++
mobile/plugins/ente_cast_normal/pubspec.yaml | 22 ++
mobile/pubspec.lock | 16 +-
mobile/pubspec.yaml | 8 +-
20 files changed, 532 insertions(+), 51 deletions(-)
create mode 100644 mobile/plugins/ente_cast/.metadata
create mode 100644 mobile/plugins/ente_cast/analysis_options.yaml
create mode 100644 mobile/plugins/ente_cast/lib/ente_cast.dart
create mode 100644 mobile/plugins/ente_cast/lib/src/service.dart
create mode 100644 mobile/plugins/ente_cast/pubspec.yaml
create mode 100644 mobile/plugins/ente_cast_none/.metadata
create mode 100644 mobile/plugins/ente_cast_none/analysis_options.yaml
create mode 100644 mobile/plugins/ente_cast_none/lib/ente_cast_none.dart
create mode 100644 mobile/plugins/ente_cast_none/lib/src/service.dart
create mode 100644 mobile/plugins/ente_cast_none/pubspec.yaml
create mode 100644 mobile/plugins/ente_cast_normal/.metadata
create mode 100644 mobile/plugins/ente_cast_normal/analysis_options.yaml
create mode 100644 mobile/plugins/ente_cast_normal/lib/ente_cast_normal.dart
create mode 100644 mobile/plugins/ente_cast_normal/lib/src/service.dart
create mode 100644 mobile/plugins/ente_cast_normal/pubspec.lock
create mode 100644 mobile/plugins/ente_cast_normal/pubspec.yaml
diff --git a/mobile/lib/service_locator.dart b/mobile/lib/service_locator.dart
index 0fec75b46..eb79aab0f 100644
--- a/mobile/lib/service_locator.dart
+++ b/mobile/lib/service_locator.dart
@@ -1,7 +1,25 @@
import "package:dio/dio.dart";
+import "package:ente_cast/ente_cast.dart";
+import "package:ente_cast_normal/ente_cast_normal.dart";
import "package:ente_feature_flag/ente_feature_flag.dart";
import "package:shared_preferences/shared_preferences.dart";
+CastService? _castService;
+CastService get castService {
+ _castService ??= CastServiceImpl();
+ return _castService!;
+}
+
+FlagService? _flagService;
+
+FlagService get flagService {
+ _flagService ??= FlagService(
+ ServiceLocator.instance.prefs,
+ ServiceLocator.instance.enteDio,
+ );
+ return _flagService!;
+}
+
class ServiceLocator {
late final SharedPreferences prefs;
late final Dio enteDio;
@@ -16,13 +34,3 @@ class ServiceLocator {
this.enteDio = enteDio;
}
}
-
-FlagService? _flagService;
-
-FlagService get flagService {
- _flagService ??= FlagService(
- ServiceLocator.instance.prefs,
- ServiceLocator.instance.enteDio,
- );
- return _flagService!;
-}
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 6c6c1e2ad..f433b336c 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -2,10 +2,6 @@ import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
-import "package:cast/device.dart";
-import "package:cast/discovery_service.dart";
-import "package:cast/session.dart";
-import "package:cast/session_manager.dart";
import "package:flutter/cupertino.dart";
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
@@ -580,7 +576,7 @@ class _GalleryAppBarWidgetState extends State {
),
);
}
- if (widget.collection != null) {
+ if (widget.collection != null && castService.isSupported) {
actions.add(castWidget(context));
}
if (items.isNotEmpty) {
@@ -650,8 +646,8 @@ class _GalleryAppBarWidgetState extends State {
}
Widget castWidget(BuildContext context) {
- return FutureBuilder>(
- future: CastDiscoveryService().search(),
+ return FutureBuilder>(
+ future: castService.searchDevices(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
@@ -679,7 +675,7 @@ class _GalleryAppBarWidgetState extends State {
showGenericErrorDialog(context: context, error: e).ignore();
}
},
- child: Text( device.name),
+ child: Text(device.toString()),
);
}).toList(),
);
@@ -689,35 +685,9 @@ class _GalleryAppBarWidgetState extends State {
Future _connectToYourApp(
BuildContext context,
- CastDevice object,
+ Object castDevice,
) async {
- final session = await CastSessionManager().startSession(object);
-
- session.stateStream.listen((state) {
- if (state == CastSessionState.connected) {
- const snackBar = SnackBar(content: Text('Connected'));
- ScaffoldMessenger.of(context).showSnackBar(snackBar);
-
- _sendPairingRequestToTV(session);
- }
- });
-
- session.messageStream.listen((message) {
- print('receive message: $message');
- });
-
- session.sendMessage(CastSession.kNamespaceReceiver, {
- 'type': 'LAUNCH',
- 'appId': 'F5BCEC64', // set the appId of your app here
- });
-
- _sendPairingRequestToTV(session);
- }
-
- void _sendPairingRequestToTV(CastSession session) {
- print('_sendMessageToYourApp');
-
- session.sendMessage('urn:x-cast:pair-request', {});
+ await castService.connectDevice(context, castDevice);
}
Future onCleanUncategorizedClick(BuildContext buildContext) async {
diff --git a/mobile/plugins/ente_cast/.metadata b/mobile/plugins/ente_cast/.metadata
new file mode 100644
index 000000000..9fc7ede54
--- /dev/null
+++ b/mobile/plugins/ente_cast/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 0b8abb4724aa590dd0f429683339b1e045a1594d
+ channel: stable
+
+project_type: plugin
diff --git a/mobile/plugins/ente_cast/analysis_options.yaml b/mobile/plugins/ente_cast/analysis_options.yaml
new file mode 100644
index 000000000..fac60e247
--- /dev/null
+++ b/mobile/plugins/ente_cast/analysis_options.yaml
@@ -0,0 +1 @@
+include: ../../analysis_options.yaml
\ No newline at end of file
diff --git a/mobile/plugins/ente_cast/lib/ente_cast.dart b/mobile/plugins/ente_cast/lib/ente_cast.dart
new file mode 100644
index 000000000..66a7132d8
--- /dev/null
+++ b/mobile/plugins/ente_cast/lib/ente_cast.dart
@@ -0,0 +1 @@
+export 'src/service.dart';
diff --git a/mobile/plugins/ente_cast/lib/src/service.dart b/mobile/plugins/ente_cast/lib/src/service.dart
new file mode 100644
index 000000000..74834f79d
--- /dev/null
+++ b/mobile/plugins/ente_cast/lib/src/service.dart
@@ -0,0 +1,7 @@
+import "package:flutter/widgets.dart";
+
+abstract class CastService {
+ bool get isSupported;
+ Future> searchDevices();
+ Future connectDevice(BuildContext context, Object device);
+}
diff --git a/mobile/plugins/ente_cast/pubspec.yaml b/mobile/plugins/ente_cast/pubspec.yaml
new file mode 100644
index 000000000..8ed1e7412
--- /dev/null
+++ b/mobile/plugins/ente_cast/pubspec.yaml
@@ -0,0 +1,19 @@
+name: ente_cast
+version: 0.0.1
+publish_to: none
+
+environment:
+ sdk: '>=3.3.0 <4.0.0'
+
+dependencies:
+ collection:
+ dio: ^4.0.6
+ flutter:
+ sdk: flutter
+ shared_preferences: ^2.0.5
+ stack_trace:
+
+dev_dependencies:
+ flutter_lints:
+
+flutter:
\ No newline at end of file
diff --git a/mobile/plugins/ente_cast_none/.metadata b/mobile/plugins/ente_cast_none/.metadata
new file mode 100644
index 000000000..9fc7ede54
--- /dev/null
+++ b/mobile/plugins/ente_cast_none/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 0b8abb4724aa590dd0f429683339b1e045a1594d
+ channel: stable
+
+project_type: plugin
diff --git a/mobile/plugins/ente_cast_none/analysis_options.yaml b/mobile/plugins/ente_cast_none/analysis_options.yaml
new file mode 100644
index 000000000..fac60e247
--- /dev/null
+++ b/mobile/plugins/ente_cast_none/analysis_options.yaml
@@ -0,0 +1 @@
+include: ../../analysis_options.yaml
\ No newline at end of file
diff --git a/mobile/plugins/ente_cast_none/lib/ente_cast_none.dart b/mobile/plugins/ente_cast_none/lib/ente_cast_none.dart
new file mode 100644
index 000000000..66a7132d8
--- /dev/null
+++ b/mobile/plugins/ente_cast_none/lib/ente_cast_none.dart
@@ -0,0 +1 @@
+export 'src/service.dart';
diff --git a/mobile/plugins/ente_cast_none/lib/src/service.dart b/mobile/plugins/ente_cast_none/lib/src/service.dart
new file mode 100644
index 000000000..964f4e472
--- /dev/null
+++ b/mobile/plugins/ente_cast_none/lib/src/service.dart
@@ -0,0 +1,17 @@
+import "package:ente_cast/ente_cast.dart";
+import "package:flutter/widgets.dart";
+
+class CastServiceImpl extends CastService {
+ @override
+ Future connectDevice(BuildContext context, Object device) {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future> searchDevices() {
+ throw UnimplementedError();
+ }
+
+ @override
+ bool get isSupported => false;
+}
diff --git a/mobile/plugins/ente_cast_none/pubspec.yaml b/mobile/plugins/ente_cast_none/pubspec.yaml
new file mode 100644
index 000000000..0484f000f
--- /dev/null
+++ b/mobile/plugins/ente_cast_none/pubspec.yaml
@@ -0,0 +1,18 @@
+name: ente_cast_none
+version: 0.0.1
+publish_to: none
+
+environment:
+ sdk: '>=3.3.0 <4.0.0'
+
+dependencies:
+ ente_cast:
+ path: ../ente_cast
+ flutter:
+ sdk: flutter
+ stack_trace:
+
+dev_dependencies:
+ flutter_lints:
+
+flutter:
\ No newline at end of file
diff --git a/mobile/plugins/ente_cast_normal/.metadata b/mobile/plugins/ente_cast_normal/.metadata
new file mode 100644
index 000000000..9fc7ede54
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 0b8abb4724aa590dd0f429683339b1e045a1594d
+ channel: stable
+
+project_type: plugin
diff --git a/mobile/plugins/ente_cast_normal/analysis_options.yaml b/mobile/plugins/ente_cast_normal/analysis_options.yaml
new file mode 100644
index 000000000..fac60e247
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/analysis_options.yaml
@@ -0,0 +1 @@
+include: ../../analysis_options.yaml
\ No newline at end of file
diff --git a/mobile/plugins/ente_cast_normal/lib/ente_cast_normal.dart b/mobile/plugins/ente_cast_normal/lib/ente_cast_normal.dart
new file mode 100644
index 000000000..66a7132d8
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/lib/ente_cast_normal.dart
@@ -0,0 +1 @@
+export 'src/service.dart';
diff --git a/mobile/plugins/ente_cast_normal/lib/src/service.dart b/mobile/plugins/ente_cast_normal/lib/src/service.dart
new file mode 100644
index 000000000..1664511b6
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/lib/src/service.dart
@@ -0,0 +1,37 @@
+import "package:cast/cast.dart";
+import "package:ente_cast/ente_cast.dart";
+import "package:flutter/material.dart";
+
+class CastServiceImpl extends CastService {
+ @override
+ Future connectDevice(BuildContext context, Object device) async {
+ final CastDevice castDevice = device as CastDevice;
+ final session = await CastSessionManager().startSession(castDevice);
+
+ session.stateStream.listen((state) {
+ if (state == CastSessionState.connected) {
+ const snackBar = SnackBar(content: Text('Connected'));
+ ScaffoldMessenger.of(context).showSnackBar(snackBar);
+ session.sendMessage('urn:x-cast:pair-request', {});
+ }
+ });
+ session.messageStream.listen((message) {
+ print('receive message: $message');
+ });
+
+ session.sendMessage(CastSession.kNamespaceReceiver, {
+ 'type': 'LAUNCH',
+ 'appId': 'F5BCEC64', // set the appId of your app here
+ });
+ session.sendMessage('urn:x-cast:pair-request', {});
+ }
+
+ @override
+ Future> searchDevices() {
+ // TODO: implement searchDevices
+ throw UnimplementedError();
+ }
+
+ @override
+ bool get isSupported => true;
+}
diff --git a/mobile/plugins/ente_cast_normal/pubspec.lock b/mobile/plugins/ente_cast_normal/pubspec.lock
new file mode 100644
index 000000000..86051800c
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/pubspec.lock
@@ -0,0 +1,333 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.11.0"
+ cast:
+ dependency: "direct main"
+ description:
+ path: "."
+ ref: multicast_version
+ resolved-ref: "1f39cd4d6efa9363e77b2439f0317bae0c92dda1"
+ url: "https://github.com/guyluz11/flutter_cast.git"
+ source: git
+ version: "2.0.9"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.18.0"
+ dio:
+ dependency: transitive
+ description:
+ name: dio
+ sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.6"
+ ente_cast:
+ dependency: "direct main"
+ description:
+ path: "../ente_cast"
+ relative: true
+ source: path
+ version: "0.0.1"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.0"
+ fixnum:
+ dependency: transitive
+ description:
+ name: fixnum
+ sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.2"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.11.0"
+ multicast_dns:
+ dependency: transitive
+ description:
+ name: multicast_dns
+ sha256: "316cc47a958d4bd3c67bd238fe8b44fdfb6133bad89cb191c0c3bd3edb14e296"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.2+6"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.9.0"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.4"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.8"
+ protobuf:
+ dependency: transitive
+ description:
+ name: protobuf
+ sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
+ shared_preferences:
+ dependency: transitive
+ description:
+ name: shared_preferences
+ sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.3"
+ shared_preferences_android:
+ dependency: transitive
+ description:
+ name: shared_preferences_android
+ sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.2"
+ shared_preferences_foundation:
+ dependency: transitive
+ description:
+ name: shared_preferences_foundation
+ sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.5"
+ shared_preferences_linux:
+ dependency: transitive
+ description:
+ name: shared_preferences_linux
+ sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
+ shared_preferences_platform_interface:
+ dependency: transitive
+ description:
+ name: shared_preferences_platform_interface
+ sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
+ shared_preferences_web:
+ dependency: transitive
+ description:
+ name: shared_preferences_web
+ sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.0"
+ shared_preferences_windows:
+ dependency: transitive
+ description:
+ name: shared_preferences_windows
+ sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.10.0"
+ stack_trace:
+ dependency: "direct main"
+ description:
+ name: stack_trace
+ sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.11.1"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.0"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.2"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.1"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.4.0"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.4"
+sdks:
+ dart: ">=3.3.0 <4.0.0"
+ flutter: ">=3.19.0"
diff --git a/mobile/plugins/ente_cast_normal/pubspec.yaml b/mobile/plugins/ente_cast_normal/pubspec.yaml
new file mode 100644
index 000000000..17d172121
--- /dev/null
+++ b/mobile/plugins/ente_cast_normal/pubspec.yaml
@@ -0,0 +1,22 @@
+name: ente_cast_normal
+version: 0.0.1
+publish_to: none
+
+environment:
+ sdk: '>=3.3.0 <4.0.0'
+
+dependencies:
+ cast:
+ git:
+ url: https://github.com/guyluz11/flutter_cast.git
+ ref: multicast_version
+ ente_cast:
+ path: ../ente_cast
+ flutter:
+ sdk: flutter
+ stack_trace:
+
+dev_dependencies:
+ flutter_lints:
+
+flutter:
\ No newline at end of file
diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock
index 882967ff0..f776c0909 100644
--- a/mobile/pubspec.lock
+++ b/mobile/pubspec.lock
@@ -210,7 +210,7 @@ packages:
source: hosted
version: "1.1.1"
cast:
- dependency: "direct main"
+ dependency: transitive
description:
path: "."
ref: multicast_version
@@ -443,6 +443,20 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.17"
+ ente_cast:
+ dependency: "direct main"
+ description:
+ path: "plugins/ente_cast"
+ relative: true
+ source: path
+ version: "0.0.1"
+ ente_cast_normal:
+ dependency: "direct main"
+ description:
+ path: "plugins/ente_cast_normal"
+ relative: true
+ source: path
+ version: "0.0.1"
ente_feature_flag:
dependency: "direct main"
description:
diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml
index a641211ea..da2f4e089 100644
--- a/mobile/pubspec.yaml
+++ b/mobile/pubspec.yaml
@@ -27,10 +27,6 @@ dependencies:
battery_info: ^1.1.1
bip39: ^1.0.6
cached_network_image: ^3.0.0
- cast:
- git:
- url: https://github.com/guyluz11/flutter_cast.git
- ref: multicast_version
chewie:
git:
url: https://github.com/ente-io/chewie.git
@@ -51,6 +47,10 @@ dependencies:
dotted_border: ^2.1.0
dropdown_button2: ^2.0.0
email_validator: ^2.0.1
+ ente_cast:
+ path: plugins/ente_cast
+ ente_cast_normal:
+ path: plugins/ente_cast_normal
ente_feature_flag:
path: plugins/ente_feature_flag
equatable: ^2.0.5
From bd225ced041a9de92b8af6d951d36f08a6f0f156 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Tue, 23 Apr 2024 16:08:16 +0530
Subject: [PATCH 005/367] [mob][cast] Return name and castDevice as record
---
mobile/lib/service_locator.dart | 32 +++++++++----------
.../gallery/gallery_app_bar_widget.dart | 8 +++--
.../plugins/ente_cast/analysis_options.yaml | 2 +-
mobile/plugins/ente_cast/lib/src/service.dart | 2 +-
mobile/plugins/ente_cast/pubspec.yaml | 2 +-
.../ente_cast_none/analysis_options.yaml | 2 +-
.../ente_cast_none/lib/src/service.dart | 9 +++---
mobile/plugins/ente_cast_none/pubspec.yaml | 2 +-
.../ente_cast_normal/analysis_options.yaml | 2 +-
.../ente_cast_normal/lib/src/service.dart | 7 ++--
mobile/plugins/ente_cast_normal/pubspec.yaml | 2 +-
11 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/mobile/lib/service_locator.dart b/mobile/lib/service_locator.dart
index eb79aab0f..397703761 100644
--- a/mobile/lib/service_locator.dart
+++ b/mobile/lib/service_locator.dart
@@ -4,22 +4,6 @@ import "package:ente_cast_normal/ente_cast_normal.dart";
import "package:ente_feature_flag/ente_feature_flag.dart";
import "package:shared_preferences/shared_preferences.dart";
-CastService? _castService;
-CastService get castService {
- _castService ??= CastServiceImpl();
- return _castService!;
-}
-
-FlagService? _flagService;
-
-FlagService get flagService {
- _flagService ??= FlagService(
- ServiceLocator.instance.prefs,
- ServiceLocator.instance.enteDio,
- );
- return _flagService!;
-}
-
class ServiceLocator {
late final SharedPreferences prefs;
late final Dio enteDio;
@@ -34,3 +18,19 @@ class ServiceLocator {
this.enteDio = enteDio;
}
}
+
+FlagService? _flagService;
+
+FlagService get flagService {
+ _flagService ??= FlagService(
+ ServiceLocator.instance.prefs,
+ ServiceLocator.instance.enteDio,
+ );
+ return _flagService!;
+}
+
+CastService? _castService;
+CastService get castService {
+ _castService ??= CastServiceImpl();
+ return _castService!;
+}
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index f433b336c..a33fc9628 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -646,7 +646,7 @@ class _GalleryAppBarWidgetState extends State {
}
Widget castWidget(BuildContext context) {
- return FutureBuilder>(
+ return FutureBuilder>(
future: castService.searchDevices(),
builder: (context, snapshot) {
if (snapshot.hasError) {
@@ -666,7 +666,9 @@ class _GalleryAppBarWidgetState extends State {
}
return Column(
- children: snapshot.data!.map((device) {
+ children: snapshot.data!.map((result) {
+ final device = result.$2;
+ final name = result.$1;
return GestureDetector(
onTap: () async {
try {
@@ -675,7 +677,7 @@ class _GalleryAppBarWidgetState extends State {
showGenericErrorDialog(context: context, error: e).ignore();
}
},
- child: Text(device.toString()),
+ child: Text(name),
);
}).toList(),
);
diff --git a/mobile/plugins/ente_cast/analysis_options.yaml b/mobile/plugins/ente_cast/analysis_options.yaml
index fac60e247..f04c6cf0f 100644
--- a/mobile/plugins/ente_cast/analysis_options.yaml
+++ b/mobile/plugins/ente_cast/analysis_options.yaml
@@ -1 +1 @@
-include: ../../analysis_options.yaml
\ No newline at end of file
+include: ../../analysis_options.yaml
diff --git a/mobile/plugins/ente_cast/lib/src/service.dart b/mobile/plugins/ente_cast/lib/src/service.dart
index 74834f79d..230269bb3 100644
--- a/mobile/plugins/ente_cast/lib/src/service.dart
+++ b/mobile/plugins/ente_cast/lib/src/service.dart
@@ -2,6 +2,6 @@ import "package:flutter/widgets.dart";
abstract class CastService {
bool get isSupported;
- Future> searchDevices();
+ Future> searchDevices();
Future connectDevice(BuildContext context, Object device);
}
diff --git a/mobile/plugins/ente_cast/pubspec.yaml b/mobile/plugins/ente_cast/pubspec.yaml
index 8ed1e7412..967e147e9 100644
--- a/mobile/plugins/ente_cast/pubspec.yaml
+++ b/mobile/plugins/ente_cast/pubspec.yaml
@@ -16,4 +16,4 @@ dependencies:
dev_dependencies:
flutter_lints:
-flutter:
\ No newline at end of file
+flutter:
diff --git a/mobile/plugins/ente_cast_none/analysis_options.yaml b/mobile/plugins/ente_cast_none/analysis_options.yaml
index fac60e247..f04c6cf0f 100644
--- a/mobile/plugins/ente_cast_none/analysis_options.yaml
+++ b/mobile/plugins/ente_cast_none/analysis_options.yaml
@@ -1 +1 @@
-include: ../../analysis_options.yaml
\ No newline at end of file
+include: ../../analysis_options.yaml
diff --git a/mobile/plugins/ente_cast_none/lib/src/service.dart b/mobile/plugins/ente_cast_none/lib/src/service.dart
index 964f4e472..166108c52 100644
--- a/mobile/plugins/ente_cast_none/lib/src/service.dart
+++ b/mobile/plugins/ente_cast_none/lib/src/service.dart
@@ -8,10 +8,11 @@ class CastServiceImpl extends CastService {
}
@override
- Future> searchDevices() {
- throw UnimplementedError();
- }
+ bool get isSupported => false;
@override
- bool get isSupported => false;
+ Future> searchDevices() {
+ // TODO: implement searchDevices
+ throw UnimplementedError();
+ }
}
diff --git a/mobile/plugins/ente_cast_none/pubspec.yaml b/mobile/plugins/ente_cast_none/pubspec.yaml
index 0484f000f..a4559fac5 100644
--- a/mobile/plugins/ente_cast_none/pubspec.yaml
+++ b/mobile/plugins/ente_cast_none/pubspec.yaml
@@ -15,4 +15,4 @@ dependencies:
dev_dependencies:
flutter_lints:
-flutter:
\ No newline at end of file
+flutter:
diff --git a/mobile/plugins/ente_cast_normal/analysis_options.yaml b/mobile/plugins/ente_cast_normal/analysis_options.yaml
index fac60e247..f04c6cf0f 100644
--- a/mobile/plugins/ente_cast_normal/analysis_options.yaml
+++ b/mobile/plugins/ente_cast_normal/analysis_options.yaml
@@ -1 +1 @@
-include: ../../analysis_options.yaml
\ No newline at end of file
+include: ../../analysis_options.yaml
diff --git a/mobile/plugins/ente_cast_normal/lib/src/service.dart b/mobile/plugins/ente_cast_normal/lib/src/service.dart
index 1664511b6..eac98ae51 100644
--- a/mobile/plugins/ente_cast_normal/lib/src/service.dart
+++ b/mobile/plugins/ente_cast_normal/lib/src/service.dart
@@ -27,9 +27,10 @@ class CastServiceImpl extends CastService {
}
@override
- Future> searchDevices() {
- // TODO: implement searchDevices
- throw UnimplementedError();
+ Future> searchDevices() {
+ return CastDiscoveryService().search().then((devices) {
+ return devices.map((device) => (device.name, device)).toList();
+ });
}
@override
diff --git a/mobile/plugins/ente_cast_normal/pubspec.yaml b/mobile/plugins/ente_cast_normal/pubspec.yaml
index 17d172121..c97d70a84 100644
--- a/mobile/plugins/ente_cast_normal/pubspec.yaml
+++ b/mobile/plugins/ente_cast_normal/pubspec.yaml
@@ -19,4 +19,4 @@ dependencies:
dev_dependencies:
flutter_lints:
-flutter:
\ No newline at end of file
+flutter:
From 1251a014b052082c0a044aad5a25e4bddc130c58 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 24 Apr 2024 10:57:28 +0530
Subject: [PATCH 006/367] [mob][cast] Show choice to auto and manual pair
---
mobile/lib/generated/intl/messages_en.dart | 2 +
mobile/lib/generated/l10n.dart | 20 +++++++
mobile/lib/l10n/intl_en.arb | 2 +
.../gallery/gallery_app_bar_widget.dart | 54 +++++++++++++++++++
4 files changed, 78 insertions(+)
diff --git a/mobile/lib/generated/intl/messages_en.dart b/mobile/lib/generated/intl/messages_en.dart
index eef309aa5..4de38ce12 100644
--- a/mobile/lib/generated/intl/messages_en.dart
+++ b/mobile/lib/generated/intl/messages_en.dart
@@ -357,6 +357,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Authentication failed, please try again"),
"authenticationSuccessful":
MessageLookupByLibrary.simpleMessage("Authentication successful!"),
+ "autoPair": MessageLookupByLibrary.simpleMessage("Auto pair"),
"available": MessageLookupByLibrary.simpleMessage("Available"),
"backedUpFolders":
MessageLookupByLibrary.simpleMessage("Backed up folders"),
@@ -982,6 +983,7 @@ class MessageLookup extends MessageLookupByLibrary {
"orPickAnExistingOne":
MessageLookupByLibrary.simpleMessage("Or pick an existing one"),
"pair": MessageLookupByLibrary.simpleMessage("Pair"),
+ "pairWithPin": MessageLookupByLibrary.simpleMessage("Pair with PIN"),
"passkey": MessageLookupByLibrary.simpleMessage("Passkey"),
"passkeyAuthTitle":
MessageLookupByLibrary.simpleMessage("Passkey verification"),
diff --git a/mobile/lib/generated/l10n.dart b/mobile/lib/generated/l10n.dart
index 3fa9c2209..7f5dc9614 100644
--- a/mobile/lib/generated/l10n.dart
+++ b/mobile/lib/generated/l10n.dart
@@ -8378,6 +8378,26 @@ class S {
);
}
+ /// `Auto pair`
+ String get autoPair {
+ return Intl.message(
+ 'Auto pair',
+ name: 'autoPair',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Pair with PIN`
+ String get pairWithPin {
+ return Intl.message(
+ 'Pair with PIN',
+ name: 'pairWithPin',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Device not found`
String get deviceNotFound {
return Intl.message(
diff --git a/mobile/lib/l10n/intl_en.arb b/mobile/lib/l10n/intl_en.arb
index 7115c6950..ee0049935 100644
--- a/mobile/lib/l10n/intl_en.arb
+++ b/mobile/lib/l10n/intl_en.arb
@@ -1195,6 +1195,8 @@
"verifyPasskey": "Verify passkey",
"playOnTv": "Play album on TV",
"pair": "Pair",
+ "autoPair": "Auto pair",
+ "pairWithPin": "Pair with PIN",
"deviceNotFound": "Device not found",
"castInstruction": "Visit cast.ente.io on the device you want to pair.\n\nEnter the code below to play the album on your TV.",
"deviceCodeHint": "Enter the code",
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index a33fc9628..35933272d 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -26,6 +26,7 @@ import 'package:photos/services/update_service.dart';
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
import 'package:photos/ui/components/action_sheet_widget.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
+import "package:photos/ui/components/dialog_widget.dart";
import 'package:photos/ui/components/models/button_type.dart';
import "package:photos/ui/map/enable_map.dart";
import "package:photos/ui/map/map_screen.dart";
@@ -892,6 +893,59 @@ class _GalleryAppBarWidgetState extends State {
final gw = CastGateway(NetworkClient.instance.enteDio);
// stop any existing cast session
gw.revokeAllTokens().ignore();
+ final result = await showDialogWidget(
+ context: context,
+ title: S.of(context).playOnTv,
+ body:
+ "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.\n\nPair with PIN works for any large screen device you want to play your album on.",
+ buttons: [
+ ButtonWidget(
+ labelText: S.of(context).autoPair,
+ icon: Icons.cast_outlined,
+ buttonType: ButtonType.trailingIconPrimary,
+ buttonSize: ButtonSize.large,
+ shouldStickToDarkTheme: true,
+ buttonAction: ButtonAction.first,
+ shouldSurfaceExecutionStates: true,
+ isInAlert: true,
+ onTap: () async {
+ showToast(context, "Coming soon");
+ // await _castAlbum(gw);
+ },
+ ),
+ ButtonWidget(
+ labelText: S.of(context).pairWithPin,
+ buttonType: ButtonType.trailingIconPrimary,
+ // icon for pairing with TV manually
+ icon: Icons.tv_outlined,
+ buttonSize: ButtonSize.large,
+ isInAlert: true,
+ shouldStickToDarkTheme: true,
+ buttonAction: ButtonAction.second,
+ shouldSurfaceExecutionStates: false,
+ ),
+ // cancel button
+ ],
+ );
+ _logger.info("Cast result: $result");
+ if (result == null) {
+ return;
+ }
+ if (result.action == ButtonAction.error) {
+ await showGenericErrorDialog(
+ context: context,
+ error: result.exception,
+ );
+ }
+ if (result.action == ButtonAction.first) {
+ showToast(context, "Coming soon");
+ }
+ if (result.action == ButtonAction.second) {
+ await _pairWithPin(gw);
+ }
+ }
+
+ Future _pairWithPin(CastGateway gw) async {
await showTextInputDialog(
context,
title: context.l10n.playOnTv,
From bed14d8ee98459e5f6871dbf6036a08af0561e8b Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 24 Apr 2024 11:38:22 +0530
Subject: [PATCH 007/367] [mob][photos] Use cast Icon in appbar
---
.../gallery/gallery_app_bar_widget.dart | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 35933272d..e29ca9d3b 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -578,7 +578,17 @@ class _GalleryAppBarWidgetState extends State {
);
}
if (widget.collection != null && castService.isSupported) {
- actions.add(castWidget(context));
+ actions.add(
+ Tooltip(
+ message: "Cast album",
+ child: IconButton(
+ icon: const Icon(Icons.cast_outlined),
+ onPressed: () async {
+ await _castChoiceDialog();
+ },
+ ),
+ ),
+ );
}
if (items.isNotEmpty) {
actions.add(
@@ -607,7 +617,7 @@ class _GalleryAppBarWidgetState extends State {
} else if (value == AlbumPopupAction.leave) {
await _leaveAlbum(context);
} else if (value == AlbumPopupAction.playOnTv) {
- await castAlbum();
+ await _castChoiceDialog();
} else if (value == AlbumPopupAction.freeUpSpace) {
await _deleteBackedUpFiles(context);
} else if (value == AlbumPopupAction.setCover) {
@@ -889,7 +899,7 @@ class _GalleryAppBarWidgetState extends State {
setState(() {});
}
- Future castAlbum() async {
+ Future _castChoiceDialog() async {
final gw = CastGateway(NetworkClient.instance.enteDio);
// stop any existing cast session
gw.revokeAllTokens().ignore();
@@ -908,10 +918,6 @@ class _GalleryAppBarWidgetState extends State {
buttonAction: ButtonAction.first,
shouldSurfaceExecutionStates: true,
isInAlert: true,
- onTap: () async {
- showToast(context, "Coming soon");
- // await _castAlbum(gw);
- },
),
ButtonWidget(
labelText: S.of(context).pairWithPin,
From 729e2adfd11c6d28f5dc38d228e27c94a5bcb589 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 24 Apr 2024 13:21:03 +0530
Subject: [PATCH 008/367] [mob] Use separate widget for auto-cast
---
mobile/lib/service_locator.dart | 2 +-
mobile/lib/ui/cast/auto.dart | 92 +++++++++++++++++++
.../gallery/gallery_app_bar_widget.dart | 56 ++---------
3 files changed, 101 insertions(+), 49 deletions(-)
create mode 100644 mobile/lib/ui/cast/auto.dart
diff --git a/mobile/lib/service_locator.dart b/mobile/lib/service_locator.dart
index 397703761..4d75d8e35 100644
--- a/mobile/lib/service_locator.dart
+++ b/mobile/lib/service_locator.dart
@@ -1,6 +1,6 @@
import "package:dio/dio.dart";
import "package:ente_cast/ente_cast.dart";
-import "package:ente_cast_normal/ente_cast_normal.dart";
+import "package:ente_cast_none/ente_cast_none.dart";
import "package:ente_feature_flag/ente_feature_flag.dart";
import "package:shared_preferences/shared_preferences.dart";
diff --git a/mobile/lib/ui/cast/auto.dart b/mobile/lib/ui/cast/auto.dart
new file mode 100644
index 000000000..5d8b64175
--- /dev/null
+++ b/mobile/lib/ui/cast/auto.dart
@@ -0,0 +1,92 @@
+import "dart:io";
+
+import "package:flutter/material.dart";
+import "package:photos/service_locator.dart";
+import "package:photos/theme/ente_theme.dart";
+import "package:photos/ui/common/loading_widget.dart";
+import "package:photos/utils/dialog_util.dart";
+
+class AutoCastDialog extends StatefulWidget {
+ AutoCastDialog({
+ Key? key,
+ }) : super(key: key) {}
+
+ @override
+ State createState() => _AutoCastDialogState();
+}
+
+class _AutoCastDialogState extends State {
+ final bool doesUserExist = true;
+
+ @override
+ Widget build(BuildContext context) {
+ final textStyle = getEnteTextTheme(context);
+
+ final AlertDialog alert = AlertDialog(
+ title: Text(
+ "Connect to device",
+ style: textStyle.largeBold,
+ ),
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ "You'll see available Cast devices here.",
+ style: textStyle.bodyMuted,
+ ),
+ if (Platform.isIOS)
+ Text(
+ "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.",
+ style: textStyle.bodyMuted,
+ ),
+ const SizedBox(height: 16),
+ FutureBuilder>(
+ future: castService.searchDevices(),
+ builder: (context, snapshot) {
+ if (snapshot.hasError) {
+ return Center(
+ child: Text(
+ 'Error: ${snapshot.error.toString()}',
+ ),
+ );
+ } else if (!snapshot.hasData) {
+ return const EnteLoadingWidget();
+ }
+
+ if (snapshot.data!.isEmpty) {
+ return const Center(child: Text('No device'));
+ }
+
+ return Column(
+ children: snapshot.data!.map((result) {
+ final device = result.$2;
+ final name = result.$1;
+ return GestureDetector(
+ onTap: () async {
+ try {
+ await _connectToYourApp(context, device);
+ } catch (e) {
+ showGenericErrorDialog(context: context, error: e)
+ .ignore();
+ }
+ },
+ child: Text(name),
+ );
+ }).toList(),
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ return alert;
+ }
+
+ Future _connectToYourApp(
+ BuildContext context,
+ Object castDevice,
+ ) async {
+ await castService.connectDevice(context, castDevice);
+ }
+}
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index e29ca9d3b..086343516 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -24,6 +24,7 @@ import 'package:photos/services/collections_service.dart';
import 'package:photos/services/sync_service.dart';
import 'package:photos/services/update_service.dart';
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
+import "package:photos/ui/cast/auto.dart";
import 'package:photos/ui/components/action_sheet_widget.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
import "package:photos/ui/components/dialog_widget.dart";
@@ -656,53 +657,6 @@ class _GalleryAppBarWidgetState extends State {
return actions;
}
- Widget castWidget(BuildContext context) {
- return FutureBuilder>(
- future: castService.searchDevices(),
- builder: (context, snapshot) {
- if (snapshot.hasError) {
- return Center(
- child: Text(
- 'Error: ${snapshot.error.toString()}',
- ),
- );
- } else if (!snapshot.hasData) {
- return const Center(
- child: CircularProgressIndicator(),
- );
- }
-
- if (snapshot.data!.isEmpty) {
- return const Text('No device');
- }
-
- return Column(
- children: snapshot.data!.map((result) {
- final device = result.$2;
- final name = result.$1;
- return GestureDetector(
- onTap: () async {
- try {
- await _connectToYourApp(context, device);
- } catch (e) {
- showGenericErrorDialog(context: context, error: e).ignore();
- }
- },
- child: Text(name),
- );
- }).toList(),
- );
- },
- );
- }
-
- Future _connectToYourApp(
- BuildContext context,
- Object castDevice,
- ) async {
- await castService.connectDevice(context, castDevice);
- }
-
Future onCleanUncategorizedClick(BuildContext buildContext) async {
final actionResult = await showChoiceActionSheet(
context,
@@ -944,7 +898,13 @@ class _GalleryAppBarWidgetState extends State {
);
}
if (result.action == ButtonAction.first) {
- showToast(context, "Coming soon");
+ await showDialog(
+ context: context,
+ barrierDismissible: true,
+ builder: (BuildContext context) {
+ return AutoCastDialog();
+ },
+ );
}
if (result.action == ButtonAction.second) {
await _pairWithPin(gw);
From aced4bb5cf2caea91c5ee97e0ac75fdb1b0d8aaf Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Wed, 24 Apr 2024 15:22:24 +0530
Subject: [PATCH 009/367] [mob][photos] Update cast selection dialog
---
mobile/lib/service_locator.dart | 2 +-
mobile/lib/ui/cast/choose.dart | 83 +++++++++++++++++++
.../gallery/gallery_app_bar_widget.dart | 47 +++--------
3 files changed, 94 insertions(+), 38 deletions(-)
create mode 100644 mobile/lib/ui/cast/choose.dart
diff --git a/mobile/lib/service_locator.dart b/mobile/lib/service_locator.dart
index 4d75d8e35..397703761 100644
--- a/mobile/lib/service_locator.dart
+++ b/mobile/lib/service_locator.dart
@@ -1,6 +1,6 @@
import "package:dio/dio.dart";
import "package:ente_cast/ente_cast.dart";
-import "package:ente_cast_none/ente_cast_none.dart";
+import "package:ente_cast_normal/ente_cast_normal.dart";
import "package:ente_feature_flag/ente_feature_flag.dart";
import "package:shared_preferences/shared_preferences.dart";
diff --git a/mobile/lib/ui/cast/choose.dart b/mobile/lib/ui/cast/choose.dart
new file mode 100644
index 000000000..0b82ea299
--- /dev/null
+++ b/mobile/lib/ui/cast/choose.dart
@@ -0,0 +1,83 @@
+import "package:flutter/material.dart";
+import "package:photos/generated/l10n.dart";
+import "package:photos/service_locator.dart";
+import "package:photos/theme/ente_theme.dart";
+import "package:photos/ui/components/buttons/button_widget.dart";
+import "package:photos/ui/components/models/button_type.dart";
+
+class CastChooseDialog extends StatefulWidget {
+ CastChooseDialog({
+ Key? key,
+ }) : super(key: key) {}
+
+ @override
+ State createState() => _AutoCastDialogState();
+}
+
+class _AutoCastDialogState extends State {
+ final bool doesUserExist = true;
+
+ @override
+ Widget build(BuildContext context) {
+ final textStyle = getEnteTextTheme(context);
+ final AlertDialog alert = AlertDialog(
+ title: Text(
+ "Play album on TV",
+ style: textStyle.largeBold,
+ ),
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(height: 8),
+ Text(
+ "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.",
+ style: textStyle.bodyMuted,
+ ),
+ const SizedBox(height: 12),
+ ButtonWidget(
+ labelText: S.of(context).autoPair,
+ icon: Icons.cast_outlined,
+ buttonType: ButtonType.primary,
+ buttonSize: ButtonSize.large,
+ shouldStickToDarkTheme: true,
+ buttonAction: ButtonAction.first,
+ shouldSurfaceExecutionStates: false,
+ isInAlert: true,
+ onTap: () async {
+ Navigator.of(context).pop(ButtonAction.first);
+ },
+ ),
+ const SizedBox(height: 36),
+ Text(
+ "Pair with PIN works for any large screen device you want to play your album on.",
+ style: textStyle.bodyMuted,
+ ),
+ const SizedBox(height: 12),
+ ButtonWidget(
+ labelText: S.of(context).pairWithPin,
+ buttonType: ButtonType.primary,
+ // icon for pairing with TV manually
+ icon: Icons.tv_outlined,
+ buttonSize: ButtonSize.large,
+ isInAlert: true,
+ onTap: () async {
+ Navigator.of(context).pop(ButtonAction.second);
+ },
+ shouldStickToDarkTheme: true,
+ buttonAction: ButtonAction.second,
+ shouldSurfaceExecutionStates: false,
+ ),
+ ],
+ ),
+ );
+ return alert;
+ }
+
+ Future _connectToYourApp(
+ BuildContext context,
+ Object castDevice,
+ ) async {
+ await castService.connectDevice(context, castDevice);
+ }
+}
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 086343516..7b45ae53f 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -25,9 +25,9 @@ import 'package:photos/services/sync_service.dart';
import 'package:photos/services/update_service.dart';
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
import "package:photos/ui/cast/auto.dart";
+import "package:photos/ui/cast/choose.dart";
import 'package:photos/ui/components/action_sheet_widget.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
-import "package:photos/ui/components/dialog_widget.dart";
import 'package:photos/ui/components/models/button_type.dart';
import "package:photos/ui/map/enable_map.dart";
import "package:photos/ui/map/map_screen.dart";
@@ -857,47 +857,20 @@ class _GalleryAppBarWidgetState extends State {
final gw = CastGateway(NetworkClient.instance.enteDio);
// stop any existing cast session
gw.revokeAllTokens().ignore();
- final result = await showDialogWidget(
+ final result = await showDialog(
context: context,
- title: S.of(context).playOnTv,
- body:
- "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.\n\nPair with PIN works for any large screen device you want to play your album on.",
- buttons: [
- ButtonWidget(
- labelText: S.of(context).autoPair,
- icon: Icons.cast_outlined,
- buttonType: ButtonType.trailingIconPrimary,
- buttonSize: ButtonSize.large,
- shouldStickToDarkTheme: true,
- buttonAction: ButtonAction.first,
- shouldSurfaceExecutionStates: true,
- isInAlert: true,
- ),
- ButtonWidget(
- labelText: S.of(context).pairWithPin,
- buttonType: ButtonType.trailingIconPrimary,
- // icon for pairing with TV manually
- icon: Icons.tv_outlined,
- buttonSize: ButtonSize.large,
- isInAlert: true,
- shouldStickToDarkTheme: true,
- buttonAction: ButtonAction.second,
- shouldSurfaceExecutionStates: false,
- ),
- // cancel button
- ],
+ barrierDismissible: true,
+ builder: (BuildContext context) {
+ return CastChooseDialog();
+ },
);
_logger.info("Cast result: $result");
if (result == null) {
return;
}
- if (result.action == ButtonAction.error) {
- await showGenericErrorDialog(
- context: context,
- error: result.exception,
- );
- }
- if (result.action == ButtonAction.first) {
+ // wait to allow the dialog to close
+ await Future.delayed(const Duration(milliseconds: 100));
+ if (result == ButtonAction.first) {
await showDialog(
context: context,
barrierDismissible: true,
@@ -906,7 +879,7 @@ class _GalleryAppBarWidgetState extends State {
},
);
}
- if (result.action == ButtonAction.second) {
+ if (result == ButtonAction.second) {
await _pairWithPin(gw);
}
}
From e903fbf9bcc15b2fb10a6f27c144e37e119ddae7 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 11:50:02 +0530
Subject: [PATCH 010/367] [mob][photos] Continue showing pair dialog in case of
error
---
.../ui/viewer/gallery/gallery_app_bar_widget.dart | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 7b45ae53f..9e53014ed 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -880,11 +880,11 @@ class _GalleryAppBarWidgetState extends State {
);
}
if (result == ButtonAction.second) {
- await _pairWithPin(gw);
+ await _pairWithPin(gw, '');
}
}
- Future _pairWithPin(CastGateway gw) async {
+ Future _pairWithPin(CastGateway gw, String code) async {
await showTextInputDialog(
context,
title: context.l10n.playOnTv,
@@ -892,12 +892,17 @@ class _GalleryAppBarWidgetState extends State {
submitButtonLabel: S.of(context).pair,
textInputType: TextInputType.streetAddress,
hintText: context.l10n.deviceCodeHint,
+ showOnlyLoadingState: true,
+ alwaysShowSuccessState: false,
+ initialValue: code,
onSubmit: (String text) async {
try {
- final code = text.trim();
+ code = text.trim();
final String? publicKey = await gw.getPublicKey(code);
if (publicKey == null) {
showToast(context, S.of(context).deviceNotFound);
+ // show _pairPin again
+ Future.delayed(Duration.zero, () => _pairWithPin(gw, code));
return;
}
final String castToken = const Uuid().v4().toString();
@@ -912,6 +917,7 @@ class _GalleryAppBarWidgetState extends State {
} catch (e, s) {
_logger.severe("Failed to cast album", e, s);
await showGenericErrorDialog(context: context, error: e);
+ Future.delayed(Duration.zero, () => _pairWithPin(gw, code));
}
},
);
From 36dbda895c3983114c8f527df6dc55cca86255e3 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 11:50:49 +0530
Subject: [PATCH 011/367] [mob][photos] Send pair req after getting receiver
status
---
.../ente_cast_normal/lib/src/service.dart | 32 +++++++++++++++----
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/mobile/plugins/ente_cast_normal/lib/src/service.dart b/mobile/plugins/ente_cast_normal/lib/src/service.dart
index eac98ae51..4c4624d8c 100644
--- a/mobile/plugins/ente_cast_normal/lib/src/service.dart
+++ b/mobile/plugins/ente_cast_normal/lib/src/service.dart
@@ -1,29 +1,49 @@
+import "dart:developer" as dev;
+
import "package:cast/cast.dart";
import "package:ente_cast/ente_cast.dart";
import "package:flutter/material.dart";
class CastServiceImpl extends CastService {
+ final String _appId = 'F5BCEC64';
+ final String _pairRequestNamespace = 'urn:x-cast:pair-request';
+ final Map sessionIDToDeviceID = {};
+
@override
Future connectDevice(BuildContext context, Object device) async {
final CastDevice castDevice = device as CastDevice;
final session = await CastSessionManager().startSession(castDevice);
+ session.messageStream.listen((message) {
+ if (message['type'] == "RECEIVER_STATUS") {
+ dev.log(
+ "got RECEIVER_STATUS, Send request to pair",
+ name: "CastServiceImpl",
+ );
+ session.sendMessage(_pairRequestNamespace, {});
+ } else {
+ print('receive message: $message');
+ }
+ });
session.stateStream.listen((state) {
if (state == CastSessionState.connected) {
const snackBar = SnackBar(content: Text('Connected'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
- session.sendMessage('urn:x-cast:pair-request', {});
+ sessionIDToDeviceID[session.sessionId] = castDevice;
+ debugPrint("Send request to pair");
+ session.sendMessage(_pairRequestNamespace, {});
+ } else if (state == CastSessionState.closed) {
+ dev.log('Session closed', name: 'CastServiceImpl');
+ sessionIDToDeviceID.remove(session.sessionId);
}
});
- session.messageStream.listen((message) {
- print('receive message: $message');
- });
+ debugPrint("Send request to launch");
session.sendMessage(CastSession.kNamespaceReceiver, {
'type': 'LAUNCH',
- 'appId': 'F5BCEC64', // set the appId of your app here
+ 'appId': _appId, // set the appId of your app here
});
- session.sendMessage('urn:x-cast:pair-request', {});
+ // session.sendMessage('urn:x-cast:pair-request', {});
}
@override
From f777bdba1b0952d176e102de5c0f425d34d84c93 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 12:44:46 +0530
Subject: [PATCH 012/367] [mob][photos] Extract strings
---
mobile/lib/generated/intl/messages_en.dart | 4 ++++
mobile/lib/generated/l10n.dart | 20 ++++++++++++++++++++
mobile/lib/l10n/intl_en.arb | 4 +++-
mobile/lib/ui/cast/choose.dart | 19 ++++++-------------
4 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/mobile/lib/generated/intl/messages_en.dart b/mobile/lib/generated/intl/messages_en.dart
index 4de38ce12..5c5a9fd4c 100644
--- a/mobile/lib/generated/intl/messages_en.dart
+++ b/mobile/lib/generated/intl/messages_en.dart
@@ -358,6 +358,8 @@ class MessageLookup extends MessageLookupByLibrary {
"authenticationSuccessful":
MessageLookupByLibrary.simpleMessage("Authentication successful!"),
"autoPair": MessageLookupByLibrary.simpleMessage("Auto pair"),
+ "autoPairGoogle": MessageLookupByLibrary.simpleMessage(
+ "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos."),
"available": MessageLookupByLibrary.simpleMessage("Available"),
"backedUpFolders":
MessageLookupByLibrary.simpleMessage("Backed up folders"),
@@ -903,6 +905,8 @@ class MessageLookup extends MessageLookupByLibrary {
"manageParticipants": MessageLookupByLibrary.simpleMessage("Manage"),
"manageSubscription":
MessageLookupByLibrary.simpleMessage("Manage subscription"),
+ "manualPairDesc": MessageLookupByLibrary.simpleMessage(
+ "Pair with PIN works for any large screen device you want to play your album on."),
"map": MessageLookupByLibrary.simpleMessage("Map"),
"maps": MessageLookupByLibrary.simpleMessage("Maps"),
"mastodon": MessageLookupByLibrary.simpleMessage("Mastodon"),
diff --git a/mobile/lib/generated/l10n.dart b/mobile/lib/generated/l10n.dart
index 7f5dc9614..7af032ce1 100644
--- a/mobile/lib/generated/l10n.dart
+++ b/mobile/lib/generated/l10n.dart
@@ -8583,6 +8583,26 @@ class S {
args: [],
);
}
+
+ /// `Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.`
+ String get autoPairGoogle {
+ return Intl.message(
+ 'Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.',
+ name: 'autoPairGoogle',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Pair with PIN works for any large screen device you want to play your album on.`
+ String get manualPairDesc {
+ return Intl.message(
+ 'Pair with PIN works for any large screen device you want to play your album on.',
+ name: 'manualPairDesc',
+ desc: '',
+ args: [],
+ );
+ }
}
class AppLocalizationDelegate extends LocalizationsDelegate {
diff --git a/mobile/lib/l10n/intl_en.arb b/mobile/lib/l10n/intl_en.arb
index ee0049935..0404e33f0 100644
--- a/mobile/lib/l10n/intl_en.arb
+++ b/mobile/lib/l10n/intl_en.arb
@@ -1214,5 +1214,7 @@
"endpointUpdatedMessage": "Endpoint updated successfully",
"customEndpoint": "Connected to {endpoint}",
"createCollaborativeLink": "Create collaborative link",
- "search": "Search"
+ "search": "Search",
+ "autoPairGoogle": "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.",
+ "manualPairDesc": "Pair with PIN works for any large screen device you want to play your album on."
}
\ No newline at end of file
diff --git a/mobile/lib/ui/cast/choose.dart b/mobile/lib/ui/cast/choose.dart
index 0b82ea299..f3ab39a62 100644
--- a/mobile/lib/ui/cast/choose.dart
+++ b/mobile/lib/ui/cast/choose.dart
@@ -1,6 +1,6 @@
import "package:flutter/material.dart";
import "package:photos/generated/l10n.dart";
-import "package:photos/service_locator.dart";
+import "package:photos/l10n/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/components/buttons/button_widget.dart";
import "package:photos/ui/components/models/button_type.dart";
@@ -11,10 +11,10 @@ class CastChooseDialog extends StatefulWidget {
}) : super(key: key) {}
@override
- State createState() => _AutoCastDialogState();
+ State createState() => _CastChooseDialogState();
}
-class _AutoCastDialogState extends State {
+class _CastChooseDialogState extends State {
final bool doesUserExist = true;
@override
@@ -22,7 +22,7 @@ class _AutoCastDialogState extends State {
final textStyle = getEnteTextTheme(context);
final AlertDialog alert = AlertDialog(
title: Text(
- "Play album on TV",
+ context.l10n.playOnTv,
style: textStyle.largeBold,
),
content: Column(
@@ -31,7 +31,7 @@ class _AutoCastDialogState extends State {
children: [
const SizedBox(height: 8),
Text(
- "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.",
+ S.of(context).autoPairGoogle,
style: textStyle.bodyMuted,
),
const SizedBox(height: 12),
@@ -50,7 +50,7 @@ class _AutoCastDialogState extends State {
),
const SizedBox(height: 36),
Text(
- "Pair with PIN works for any large screen device you want to play your album on.",
+ S.of(context).manualPairDesc,
style: textStyle.bodyMuted,
),
const SizedBox(height: 12),
@@ -73,11 +73,4 @@ class _AutoCastDialogState extends State {
);
return alert;
}
-
- Future _connectToYourApp(
- BuildContext context,
- Object castDevice,
- ) async {
- await castService.connectDevice(context, castDevice);
- }
}
From 864f5c1fd4c33abce43666dc25e766c2ee931054 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 16:25:04 +0530
Subject: [PATCH 013/367] [mob][photos] Extract strings
---
mobile/lib/generated/intl/messages_en.dart | 8 +++++
mobile/lib/generated/l10n.dart | 40 ++++++++++++++++++++++
mobile/lib/l10n/intl_en.arb | 6 +++-
mobile/lib/ui/cast/auto.dart | 9 ++---
4 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/mobile/lib/generated/intl/messages_en.dart b/mobile/lib/generated/intl/messages_en.dart
index 5c5a9fd4c..23ea9c5e2 100644
--- a/mobile/lib/generated/intl/messages_en.dart
+++ b/mobile/lib/generated/intl/messages_en.dart
@@ -357,6 +357,10 @@ class MessageLookup extends MessageLookupByLibrary {
"Authentication failed, please try again"),
"authenticationSuccessful":
MessageLookupByLibrary.simpleMessage("Authentication successful!"),
+ "autoCastDialogBody": MessageLookupByLibrary.simpleMessage(
+ "You\'ll see available Cast devices here."),
+ "autoCastiOSPermission": MessageLookupByLibrary.simpleMessage(
+ "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings."),
"autoPair": MessageLookupByLibrary.simpleMessage("Auto pair"),
"autoPairGoogle": MessageLookupByLibrary.simpleMessage(
"Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos."),
@@ -463,6 +467,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Confirm recovery key"),
"confirmYourRecoveryKey":
MessageLookupByLibrary.simpleMessage("Confirm your recovery key"),
+ "connectToDevice":
+ MessageLookupByLibrary.simpleMessage("Connect to device"),
"contactFamilyAdmin": m12,
"contactSupport":
MessageLookupByLibrary.simpleMessage("Contact support"),
@@ -941,6 +947,8 @@ class MessageLookup extends MessageLookupByLibrary {
"no": MessageLookupByLibrary.simpleMessage("No"),
"noAlbumsSharedByYouYet":
MessageLookupByLibrary.simpleMessage("No albums shared by you yet"),
+ "noDeviceFound":
+ MessageLookupByLibrary.simpleMessage("No device found"),
"noDeviceLimit": MessageLookupByLibrary.simpleMessage("None"),
"noDeviceThatCanBeDeleted": MessageLookupByLibrary.simpleMessage(
"You\'ve no files on this device that can be deleted"),
diff --git a/mobile/lib/generated/l10n.dart b/mobile/lib/generated/l10n.dart
index 7af032ce1..d55ab1795 100644
--- a/mobile/lib/generated/l10n.dart
+++ b/mobile/lib/generated/l10n.dart
@@ -8603,6 +8603,46 @@ class S {
args: [],
);
}
+
+ /// `Connect to device`
+ String get connectToDevice {
+ return Intl.message(
+ 'Connect to device',
+ name: 'connectToDevice',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You'll see available Cast devices here.`
+ String get autoCastDialogBody {
+ return Intl.message(
+ 'You\'ll see available Cast devices here.',
+ name: 'autoCastDialogBody',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.`
+ String get autoCastiOSPermission {
+ return Intl.message(
+ 'Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.',
+ name: 'autoCastiOSPermission',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `No device found`
+ String get noDeviceFound {
+ return Intl.message(
+ 'No device found',
+ name: 'noDeviceFound',
+ desc: '',
+ args: [],
+ );
+ }
}
class AppLocalizationDelegate extends LocalizationsDelegate {
diff --git a/mobile/lib/l10n/intl_en.arb b/mobile/lib/l10n/intl_en.arb
index 0404e33f0..72afd2a4b 100644
--- a/mobile/lib/l10n/intl_en.arb
+++ b/mobile/lib/l10n/intl_en.arb
@@ -1216,5 +1216,9 @@
"createCollaborativeLink": "Create collaborative link",
"search": "Search",
"autoPairGoogle": "Auto Pair requires connecting to Google servers and only works with Chromecast supported devices. Google will not receive sensitive data, such as your photos.",
- "manualPairDesc": "Pair with PIN works for any large screen device you want to play your album on."
+ "manualPairDesc": "Pair with PIN works for any large screen device you want to play your album on.",
+ "connectToDevice": "Connect to device",
+ "autoCastDialogBody": "You'll see available Cast devices here.",
+ "autoCastiOSPermission": "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.",
+ "noDeviceFound": "No device found"
}
\ No newline at end of file
diff --git a/mobile/lib/ui/cast/auto.dart b/mobile/lib/ui/cast/auto.dart
index 5d8b64175..64bae7cf3 100644
--- a/mobile/lib/ui/cast/auto.dart
+++ b/mobile/lib/ui/cast/auto.dart
@@ -1,6 +1,7 @@
import "dart:io";
import "package:flutter/material.dart";
+import "package:photos/generated/l10n.dart";
import "package:photos/service_locator.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/loading_widget.dart";
@@ -24,7 +25,7 @@ class _AutoCastDialogState extends State {
final AlertDialog alert = AlertDialog(
title: Text(
- "Connect to device",
+ S.of(context).connectToDevice,
style: textStyle.largeBold,
),
content: Column(
@@ -32,12 +33,12 @@ class _AutoCastDialogState extends State {
mainAxisSize: MainAxisSize.min,
children: [
Text(
- "You'll see available Cast devices here.",
+ S.of(context).autoCastDialogBody,
style: textStyle.bodyMuted,
),
if (Platform.isIOS)
Text(
- "Make sure Local Network permissions are turned on for the Ente Photos app, in Settings.",
+ S.of(context).autoCastiOSPermission,
style: textStyle.bodyMuted,
),
const SizedBox(height: 16),
@@ -55,7 +56,7 @@ class _AutoCastDialogState extends State {
}
if (snapshot.data!.isEmpty) {
- return const Center(child: Text('No device'));
+ return const Center(child: Text(S.of(context).noDeviceFound));
}
return Column(
From 483cfd1f3913109bb5c63e02d5bae8110e6f8149 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 16:28:30 +0530
Subject: [PATCH 014/367] [mob][photos] Lint suggestions
---
mobile/lib/ui/cast/auto.dart | 2 +-
mobile/lib/ui/cast/choose.dart | 4 ++--
mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mobile/lib/ui/cast/auto.dart b/mobile/lib/ui/cast/auto.dart
index 64bae7cf3..0b088a9d2 100644
--- a/mobile/lib/ui/cast/auto.dart
+++ b/mobile/lib/ui/cast/auto.dart
@@ -56,7 +56,7 @@ class _AutoCastDialogState extends State {
}
if (snapshot.data!.isEmpty) {
- return const Center(child: Text(S.of(context).noDeviceFound));
+ return Center(child: Text(S.of(context).noDeviceFound));
}
return Column(
diff --git a/mobile/lib/ui/cast/choose.dart b/mobile/lib/ui/cast/choose.dart
index f3ab39a62..1cfd275c8 100644
--- a/mobile/lib/ui/cast/choose.dart
+++ b/mobile/lib/ui/cast/choose.dart
@@ -6,9 +6,9 @@ import "package:photos/ui/components/buttons/button_widget.dart";
import "package:photos/ui/components/models/button_type.dart";
class CastChooseDialog extends StatefulWidget {
- CastChooseDialog({
+ const CastChooseDialog({
Key? key,
- }) : super(key: key) {}
+ }) : super(key: key);
@override
State createState() => _CastChooseDialogState();
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index 9e53014ed..d7b1b0190 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -861,7 +861,7 @@ class _GalleryAppBarWidgetState extends State {
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
- return CastChooseDialog();
+ return const CastChooseDialog();
},
);
_logger.info("Cast result: $result");
From dddbb959b53e1a1da80750507b01cb3fb01afb64 Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Thu, 25 Apr 2024 17:45:03 +0530
Subject: [PATCH 015/367] [mob][photos] Refactor
---
.../gallery/gallery_app_bar_widget.dart | 49 +++++++++++--------
1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
index d7b1b0190..d73662e19 100644
--- a/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
+++ b/mobile/lib/ui/viewer/gallery/gallery_app_bar_widget.dart
@@ -896,30 +896,37 @@ class _GalleryAppBarWidgetState extends State {
alwaysShowSuccessState: false,
initialValue: code,
onSubmit: (String text) async {
- try {
- code = text.trim();
- final String? publicKey = await gw.getPublicKey(code);
- if (publicKey == null) {
- showToast(context, S.of(context).deviceNotFound);
- // show _pairPin again
- Future.delayed(Duration.zero, () => _pairWithPin(gw, code));
- return;
- }
- final String castToken = const Uuid().v4().toString();
- final castPayload = CollectionsService.instance
- .getCastData(castToken, widget.collection!, publicKey);
- await gw.publishCastPayload(
- code,
- castPayload,
- widget.collection!.id,
- castToken,
- );
- } catch (e, s) {
- _logger.severe("Failed to cast album", e, s);
- await showGenericErrorDialog(context: context, error: e);
+ final bool paired = await _castPair(gw, text);
+ if (!paired) {
Future.delayed(Duration.zero, () => _pairWithPin(gw, code));
}
},
);
}
+
+ Future _castPair(CastGateway gw, String code) async {
+ try {
+ final String? publicKey = await gw.getPublicKey(code);
+ if (publicKey == null) {
+ showToast(context, S.of(context).deviceNotFound);
+
+ return false;
+ }
+ final String castToken = const Uuid().v4().toString();
+ final castPayload = CollectionsService.instance
+ .getCastData(castToken, widget.collection!, publicKey);
+ await gw.publishCastPayload(
+ code,
+ castPayload,
+ widget.collection!.id,
+ castToken,
+ );
+ showToast(context, "Pairing complete");
+ return true;
+ } catch (e, s) {
+ _logger.severe("Failed to cast album", e, s);
+ await showGenericErrorDialog(context: context, error: e);
+ return false;
+ }
+ }
}
From 4ce6fa790fa6c86a5a4892c63fd545c487860bde Mon Sep 17 00:00:00 2001
From: Neeraj Gupta <254676+ua741@users.noreply.github.com>
Date: Sat, 27 Apr 2024 12:16:48 +0530
Subject: [PATCH 016/367] [mob] Add method to close cast and keep track of
active casts
---
mobile/plugins/ente_cast/lib/ente_cast.dart | 1 +
mobile/plugins/ente_cast/lib/src/model.dart | 5 +++
mobile/plugins/ente_cast/lib/src/service.dart | 13 +++++-
.../ente_cast_none/lib/src/service.dart | 19 +++++++-
.../ente_cast_normal/lib/src/service.dart | 43 +++++++++++++++++--
5 files changed, 75 insertions(+), 6 deletions(-)
create mode 100644 mobile/plugins/ente_cast/lib/src/model.dart
diff --git a/mobile/plugins/ente_cast/lib/ente_cast.dart b/mobile/plugins/ente_cast/lib/ente_cast.dart
index 66a7132d8..f421a9297 100644
--- a/mobile/plugins/ente_cast/lib/ente_cast.dart
+++ b/mobile/plugins/ente_cast/lib/ente_cast.dart
@@ -1 +1,2 @@
+export 'src/model.dart';
export 'src/service.dart';
diff --git a/mobile/plugins/ente_cast/lib/src/model.dart b/mobile/plugins/ente_cast/lib/src/model.dart
new file mode 100644
index 000000000..e86582f76
--- /dev/null
+++ b/mobile/plugins/ente_cast/lib/src/model.dart
@@ -0,0 +1,5 @@
+// create enum for type of message for cast
+enum CastMessageType {
+ pairCode,
+ alreadyCasting,
+}
diff --git a/mobile/plugins/ente_cast/lib/src/service.dart b/mobile/plugins/ente_cast/lib/src/service.dart
index 230269bb3..82d8c5978 100644
--- a/mobile/plugins/ente_cast/lib/src/service.dart
+++ b/mobile/plugins/ente_cast/lib/src/service.dart
@@ -1,7 +1,18 @@
+import "package:ente_cast/src/model.dart";
import "package:flutter/widgets.dart";
abstract class CastService {
bool get isSupported;
Future> searchDevices();
- Future connectDevice(BuildContext context, Object device);
+ Future connectDevice(
+ BuildContext context,
+ Object device, {
+ int? collectionID,
+ // callback that take a map of string, dynamic
+ void Function(Map>)? onMessage,
+ });
+ // returns a map of sessionID to deviceNames
+ Future