Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit 04c51ac

Browse files
committed
feat: Adding BluetoothReceive.dart
1 parent 1619b30 commit 04c51ac

File tree

9 files changed

+168
-49
lines changed

9 files changed

+168
-49
lines changed

lib/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@
181181
"transferScreen_send_startTransfer": "Transfer",
182182
"transferScreen_receive_connect_description": "Received a transfer request. This is the PIN. Make sure the PIN matches the one on your old device. If it does, tap \"Connect\".",
183183
"transferScreen_receive_connected_label": "Please start the transfer on your old device now.",
184+
"bluetoothReceive_title": "Receive View Key",
185+
"bluetoothReceive_description": "Receive a view key from another device via Bluetooth",
186+
"bluetoothReceive_name_description": "This is your name visible to others:",
184187
"mainScreen_overview": "Overview",
185188
"mainScreen_createTask": "Create Task",
186189
"mainScreen_logs": "Logs",
@@ -199,6 +202,7 @@
199202
"mainScreen_importTask_action_importMethod_url": "Import URL",
200203
"mainScreen_importTask_action_importMethod_url_title": "Enter the URL of the task",
201204
"mainScreen_importTask_action_importMethod_file": "Import file",
205+
"mainScreen_importTask_action_importMethod_bluetooth": "Receive via Bluetooth",
202206
"mainScreen_importTask_action_importMethod_file_selectFile": "Select a ViewKey file to import",
203207
"mainScreen_importTask_action_import_isLoading": "Importing...",
204208
"mainScreen_importTask_action_name_title": "Enter a name for this view",

lib/screens/ImportTaskSheet.dart

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import 'package:provider/provider.dart';
1616

1717
import '../services/task_service.dart';
1818
import '../widgets/ModalSheet.dart';
19+
import 'import_task_sheet_widgets/BluetoothReceive.dart';
1920

2021
enum ImportScreen {
2122
ask,
2223
importFile,
2324
askURL,
2425
askName,
26+
bluetoothReceive,
2527
present,
2628
error,
2729
done,
@@ -43,8 +45,7 @@ class ImportTaskSheet extends StatefulWidget {
4345
State<ImportTaskSheet> createState() => _ImportTaskSheetState();
4446
}
4547

46-
class _ImportTaskSheetState extends State<ImportTaskSheet>
47-
with TickerProviderStateMixin {
48+
class _ImportTaskSheetState extends State<ImportTaskSheet> with TickerProviderStateMixin {
4849
final _nameController = TextEditingController();
4950
final _urlController = TextEditingController();
5051
ImportScreen _screen = ImportScreen.ask;
@@ -128,8 +129,7 @@ class _ImportTaskSheetState extends State<ImportTaskSheet>
128129
result = await FilePicker.platform.pickFiles(
129130
type: FileType.custom,
130131
allowedExtensions: ["json"],
131-
dialogTitle:
132-
l10n.mainScreen_importTask_action_importMethod_file_selectFile,
132+
dialogTitle: l10n.mainScreen_importTask_action_importMethod_file_selectFile,
133133
withData: true,
134134
);
135135
} catch (_) {
@@ -247,6 +247,11 @@ class _ImportTaskSheetState extends State<ImportTaskSheet>
247247
_screen = ImportScreen.askURL;
248248
});
249249
break;
250+
case ImportSelectionType.bluetooth:
251+
setState(() {
252+
_screen = ImportScreen.bluetoothReceive;
253+
});
254+
break;
250255
}
251256
},
252257
)
@@ -278,11 +283,12 @@ class _ImportTaskSheetState extends State<ImportTaskSheet>
278283
else if (errorMessage != null)
279284
Text(
280285
errorMessage!,
281-
style: getBodyTextTextStyle(context)
282-
.copyWith(color: getErrorColor(context)),
286+
style: getBodyTextTextStyle(context).copyWith(color: getErrorColor(context)),
283287
),
284288
],
285289
)
290+
else if (_screen == ImportScreen.bluetoothReceive)
291+
BluetoothReceive()
286292
else if (_screen == ImportScreen.present)
287293
ViewImportOverview(
288294
view: _taskView!,
@@ -305,8 +311,7 @@ class _ImportTaskSheetState extends State<ImportTaskSheet>
305311
else if (_screen == ImportScreen.error)
306312
Column(
307313
children: <Widget>[
308-
Icon(context.platformIcons.error,
309-
size: 64, color: getErrorColor(context)),
314+
Icon(context.platformIcons.error, size: 64, color: getErrorColor(context)),
310315
const SizedBox(height: MEDIUM_SPACE),
311316
Text(
312317
l10n.taskImportError,
@@ -315,8 +320,7 @@ class _ImportTaskSheetState extends State<ImportTaskSheet>
315320
const SizedBox(height: SMALL_SPACE),
316321
Text(
317322
errorMessage!,
318-
style: getBodyTextTextStyle(context)
319-
.copyWith(color: getErrorColor(context)),
323+
style: getBodyTextTextStyle(context).copyWith(color: getErrorColor(context)),
320324
),
321325
const SizedBox(height: LARGE_SPACE),
322326
PlatformElevatedButton(
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import 'package:english_words/english_words.dart';
2+
import 'package:flutter/widgets.dart';
3+
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
4+
import 'package:locus/constants/spacing.dart';
5+
import 'package:locus/utils/bluetooth.dart';
6+
import 'package:locus/utils/theme.dart';
7+
import 'package:locus/widgets/BluetoothPermissionRequiredScreen.dart';
8+
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
9+
import 'package:locus/widgets/Paper.dart';
10+
import 'package:lottie/lottie.dart';
11+
12+
class BluetoothReceive extends StatefulWidget {
13+
const BluetoothReceive({Key? key}) : super(key: key);
14+
15+
@override
16+
State<BluetoothReceive> createState() => _BluetoothReceiveState();
17+
}
18+
19+
class _BluetoothReceiveState extends State<BluetoothReceive> with BluetoothPermissionMixin {
20+
final String id = createIdentifier();
21+
String? connectionID;
22+
23+
static String createIdentifier() {
24+
final wordPair = generateWordPairs().first;
25+
26+
return "${wordPair.first} ${wordPair.second}";
27+
}
28+
29+
@override
30+
void initState() {
31+
super.initState();
32+
33+
checkBluetoothPermission();
34+
}
35+
36+
@override
37+
Widget build(BuildContext context) {
38+
final l10n = AppLocalizations.of(context);
39+
40+
return PlatformScaffold(
41+
body: SafeArea(
42+
child: Padding(
43+
padding: const EdgeInsets.all(MEDIUM_SPACE),
44+
child: Center(
45+
child: (() {
46+
if (!hasGrantedBluetoothPermission) {
47+
return BluetoothPermissionRequiredScreen(onRequest: checkBluetoothPermission);
48+
}
49+
50+
if (connectionID == null) {
51+
return Column(
52+
mainAxisAlignment: MainAxisAlignment.center,
53+
crossAxisAlignment: CrossAxisAlignment.center,
54+
children: <Widget>[
55+
Lottie.asset(
56+
"assets/lottie/bluetooth.json",
57+
frameRate: FrameRate.max,
58+
repeat: true,
59+
),
60+
Text(
61+
l10n.bluetoothReceive_title,
62+
style: getTitle2TextStyle(context),
63+
),
64+
const SizedBox(height: MEDIUM_SPACE),
65+
Text(l10n.bluetoothReceive_description),
66+
const SizedBox(height: LARGE_SPACE),
67+
Text(
68+
l10n.bluetoothReceive_name_description,
69+
style: getCaptionTextStyle(context),
70+
),
71+
const SizedBox(height: MEDIUM_SPACE),
72+
Paper(
73+
child: Padding(
74+
padding: const EdgeInsets.all(MEDIUM_SPACE),
75+
child: Text(id),
76+
),
77+
),
78+
],
79+
);
80+
}
81+
})(),
82+
),
83+
),
84+
),
85+
);
86+
}
87+
}

lib/screens/import_task_sheet_widgets/ImportSelection.dart

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:io';
2+
13
import 'package:flutter/material.dart';
24
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
35
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
@@ -8,6 +10,7 @@ import '../../utils/theme.dart';
810
enum ImportSelectionType {
911
url,
1012
file,
13+
bluetooth,
1114
}
1215

1316
class ImportSelection extends StatefulWidget {
@@ -44,8 +47,7 @@ class _ImportSelectionState extends State<ImportSelection> {
4447
if (errorMessage != null) ...[
4548
Text(
4649
errorMessage!,
47-
style: getBodyTextTextStyle(context)
48-
.copyWith(color: getErrorColor(context)),
50+
style: getBodyTextTextStyle(context).copyWith(color: getErrorColor(context)),
4951
),
5052
const SizedBox(height: MEDIUM_SPACE),
5153
],
@@ -74,6 +76,17 @@ class _ImportSelectionState extends State<ImportSelection> {
7476
},
7577
child: Text(l10n.mainScreen_importTask_action_importMethod_file),
7678
),
79+
if (Platform.isAndroid)
80+
PlatformElevatedButton(
81+
padding: const EdgeInsets.all(MEDIUM_SPACE),
82+
material: (_, __) => MaterialElevatedButtonData(
83+
icon: const Icon(Icons.bluetooth_audio_rounded),
84+
),
85+
onPressed: () async {
86+
widget.onSelect(ImportSelectionType.bluetooth);
87+
},
88+
child: Text(l10n.mainScreen_importTask_action_importMethod_bluetooth),
89+
)
7790
],
7891
),
7992
],

lib/screens/settings_screen_widgets/TransferSenderScreen.dart

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import 'package:locus/services/task_service.dart';
1414
import 'package:locus/utils/bluetooth.dart';
1515
import 'package:locus/utils/import_export_handler.dart';
1616
import 'package:locus/utils/theme.dart';
17+
import 'package:locus/widgets/BluetoothPermissionRequiredScreen.dart';
1718
import 'package:locus/widgets/PINView.dart';
1819
import 'package:lottie/lottie.dart';
1920
import 'package:nearby_connections/nearby_connections.dart';
20-
import 'package:permission_handler/permission_handler.dart';
2121
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
2222
import 'package:provider/provider.dart';
2323

@@ -148,20 +148,7 @@ class _TransferSenderScreenState extends State<TransferSenderScreen> with Blueto
148148
child: Center(
149149
child: (() {
150150
if (!hasGrantedBluetoothPermission) {
151-
return Column(
152-
mainAxisAlignment: MainAxisAlignment.center,
153-
crossAxisAlignment: CrossAxisAlignment.center,
154-
children: <Widget>[
155-
const Icon(Icons.bluetooth_audio_rounded, size: 60),
156-
const SizedBox(height: MEDIUM_SPACE),
157-
Text(l10n.grantBluetoothPermission),
158-
const SizedBox(height: MEDIUM_SPACE),
159-
PlatformElevatedButton(
160-
onPressed: checkBluetoothPermission,
161-
child: Text(l10n.grantPermission),
162-
),
163-
],
164-
);
151+
return BluetoothPermissionRequiredScreen(onRequest: checkBluetoothPermission);
165152
}
166153

167154
if (connectionEstablished) {

lib/screens/welcome_screen_widgets/TransferReceiverScreen.dart

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
1414
import '../../constants/app.dart';
1515
import '../../constants/values.dart';
1616
import '../../utils/import_export_handler.dart';
17+
import '../../widgets/BluetoothPermissionRequiredScreen.dart';
1718

1819
class TransferReceiverScreen extends StatefulWidget {
1920
final void Function(String rawData) onContentReceived;
@@ -117,21 +118,9 @@ class _TransferReceiverScreenState extends State<TransferReceiverScreen> with Bl
117118
child: Center(
118119
child: (() {
119120
if (!hasGrantedBluetoothPermission) {
120-
return Column(
121-
mainAxisAlignment: MainAxisAlignment.center,
122-
crossAxisAlignment: CrossAxisAlignment.center,
123-
children: <Widget>[
124-
const Icon(Icons.bluetooth_audio_rounded, size: 60),
125-
const SizedBox(height: MEDIUM_SPACE),
126-
Text(l10n.grantBluetoothPermission),
127-
const SizedBox(height: MEDIUM_SPACE),
128-
PlatformElevatedButton(
129-
onPressed: checkBluetoothPermission,
130-
child: Text(l10n.grantPermission),
131-
),
132-
],
133-
);
121+
return BluetoothPermissionRequiredScreen(onRequest: checkBluetoothPermission);
134122
}
123+
135124
if (progress != null) {
136125
return Column(
137126
mainAxisAlignment: MainAxisAlignment.center,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3+
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
4+
5+
import '../constants/spacing.dart';
6+
7+
class BluetoothPermissionRequiredScreen extends StatelessWidget {
8+
final VoidCallback onRequest;
9+
10+
const BluetoothPermissionRequiredScreen({
11+
required this.onRequest,
12+
Key? key,
13+
}) : super(key: key);
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
final l10n = AppLocalizations.of(context);
18+
19+
return Column(
20+
mainAxisAlignment: MainAxisAlignment.center,
21+
crossAxisAlignment: CrossAxisAlignment.center,
22+
children: <Widget>[
23+
const Icon(Icons.bluetooth_audio_rounded, size: 60),
24+
const SizedBox(height: MEDIUM_SPACE),
25+
Text(l10n.grantBluetoothPermission),
26+
const SizedBox(height: MEDIUM_SPACE),
27+
PlatformElevatedButton(
28+
onPressed: onRequest,
29+
child: Text(l10n.grantPermission),
30+
),
31+
],
32+
);
33+
}
34+
}

pubspec.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,14 @@ packages:
345345
url: "https://pub.dev"
346346
source: hosted
347347
version: "1.6.5"
348+
english_words:
349+
dependency: "direct main"
350+
description:
351+
name: english_words
352+
sha256: "6a7ef6473a97bd8571b6b641d006a6e58a7c67e65fb6f3d6d1151cb46b0e983c"
353+
url: "https://pub.dev"
354+
source: hosted
355+
version: "4.0.0"
348356
fake_async:
349357
dependency: transitive
350358
description:
@@ -661,14 +669,6 @@ packages:
661669
url: "https://pub.dev"
662670
source: hosted
663671
version: "2.1.2"
664-
gms_check:
665-
dependency: "direct main"
666-
description:
667-
name: gms_check
668-
sha256: "696780955f9432dd75f32dbd65994f45765ff6abe9aa34d6e2d2d6ced70671a7"
669-
url: "https://pub.dev"
670-
source: hosted
671-
version: "1.0.1"
672672
google_polyline_algorithm:
673673
dependency: transitive
674674
description:

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ dependencies:
8585
package_info_plus: ^4.0.1
8686
version: ^3.0.2
8787
nearby_connections: ^3.3.0
88+
english_words: ^4.0.0
8889

8990
# Uncomment this for publishing FLOSS variant
9091
# Taken from https://github.com/Zverik/every_door/blob/aaf8d2fdeac483041bcac2c7c79ef760b99dff2b/pubspec.yaml#L55

0 commit comments

Comments
 (0)