Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Settings Redesign #1586

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/lib/pages/capture/connect.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:friend_private/pages/settings/device_settings.dart';
import 'package:friend_private/pages/settings/device_settings/device_settings_page.dart';
import 'package:friend_private/pages/home/page.dart';
import 'package:friend_private/pages/onboarding/find_device/page.dart';
import 'package:friend_private/utils/other/temp.dart';
Expand Down
491 changes: 257 additions & 234 deletions app/lib/pages/facts/page.dart

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/lib/pages/home/device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:friend_private/widgets/device_widget.dart';
import 'package:gradient_borders/box_borders/gradient_box_border.dart';
import 'package:provider/provider.dart';

import '../settings/device_settings.dart';
import '../settings/device_settings/device_settings_page.dart';

class ConnectedDevice extends StatefulWidget {
const ConnectedDevice({super.key});
Expand Down
4 changes: 3 additions & 1 deletion app/lib/pages/onboarding/wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ class _OnboardingWrapperState extends State<OnboardingWrapper> with TickerProvid
AuthComponent(
onSignIn: () {
MixpanelManager().onboardingStepCompleted('Auth');
context.read<HomeProvider>().setupHasSpeakerProfile();
if (mounted) {
context.read<HomeProvider>().setupHasSpeakerProfile();
}
IntercomManager.instance.intercom.loginIdentifiedUser(
userId: SharedPreferencesUtil().uid,
);
Expand Down
556 changes: 265 additions & 291 deletions app/lib/pages/settings/developer.dart

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import 'package:friend_private/utils/other/temp.dart';
import 'package:friend_private/widgets/dialog.dart';
import 'package:gradient_borders/gradient_borders.dart';
import 'package:provider/provider.dart';
import 'package:friend_private/pages/settings/widgets.dart';

import 'widgets/device_info_card.dart';

class DeviceSettings extends StatefulWidget {
const DeviceSettings({super.key});
Expand All @@ -23,7 +26,6 @@ class DeviceSettings extends StatefulWidget {
}

class _DeviceSettingsState extends State<DeviceSettings> {
// TODO: thinh, use connection directly
Future _bleDisconnectDevice(BtDevice btDevice) async {
var connection = await ServiceManager.instance().device.ensureConnection(btDevice.id);
if (connection == null) {
Expand All @@ -49,14 +51,87 @@ class _DeviceSettingsState extends State<DeviceSettings> {
title: const Text('Device Settings'),
backgroundColor: Theme.of(context).colorScheme.primary,
),
body: Padding(
padding: const EdgeInsets.all(4.0),
child: ListView(
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 16),
Stack(
children: [
Column(
children: deviceSettingsWidgets(provider.pairedDevice, context),
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DeviceInfoCard(device: provider.pairedDevice),
const SizedBox(height: 24),
// Actions Section
Padding(
padding: const EdgeInsets.only(left: 4, bottom: 12),
child: Text(
'ACTIONS',
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 13,
fontWeight: FontWeight.w600,
letterSpacing: 0.5,
),
),
),
CustomListTile(
title: 'Update Version',
onTap: () => routeToPage(context, FirmwareUpdate(device: provider.pairedDevice)),
icon: Icons.system_update,
subtitle: 'Current: ${provider.pairedDevice?.firmwareRevision ?? '1.0.2'}',
showChevron: true,
),
const SizedBox(height: 8),
CustomListTile(
title: 'SD Card Sync',
onTap: () {
if (!provider.isDeviceV2Connected) {
showDialog(
context: context,
builder: (c) => getDialog(
context,
() => Navigator.of(context).pop(),
() => {},
'V2 undetected',
'We see that you either have a V1 device or your device is not connected. SD Card functionality is available only for V2 devices.',
singleButton: true,
),
);
} else {
routeToPage(context, const SyncPage());
}
},
icon: Icons.sd_card,
subtitle: 'Import audio files',
showChevron: true,
),
const SizedBox(height: 24),
// Support Section
Padding(
padding: const EdgeInsets.only(left: 4, bottom: 12),
child: Text(
'SUPPORT',
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 13,
fontWeight: FontWeight.w600,
letterSpacing: 0.5,
),
),
),
CustomListTile(
title: 'Issues charging the device?',
onTap: () async {
await IntercomManager().displayChargingArticle(provider.pairedDevice?.name ?? 'DevKit1');
},
icon: Icons.help_outline,
subtitle: 'Tap to see the guide',
showChevron: true,
),
],
),
if (!provider.isConnected)
ClipRRect(
Expand Down Expand Up @@ -96,15 +171,6 @@ class _DeviceSettingsState extends State<DeviceSettings> {
),
],
),
GestureDetector(
onTap: () async {
await IntercomManager().displayChargingArticle(provider.pairedDevice?.name ?? 'DevKit1');
},
child: const ListTile(
title: Text('Issues charging the device?'),
subtitle: Text('Tap to see the guide'),
),
),
],
),
),
Expand Down Expand Up @@ -140,8 +206,8 @@ class _DeviceSettingsState extends State<DeviceSettings> {
Navigator.of(context).pop();
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
'Your Omi is ${provider.connectedDevice == null ? "unpaired" : "disconnected"} 😔'),
content:
Text('Your Omi is ${provider.connectedDevice == null ? "unpaired" : "disconnected"} 😔'),
));
MixpanelManager().disconnectFriendClicked();
},
Expand All @@ -157,71 +223,3 @@ class _DeviceSettingsState extends State<DeviceSettings> {
});
}
}

List<Widget> deviceSettingsWidgets(BtDevice? device, BuildContext context) {
var provider = Provider.of<DeviceProvider>(context, listen: true);

return [
ListTile(
title: const Text('Device Name'),
subtitle: Text(device?.name ?? 'Omi DevKit'),
),
ListTile(
title: const Text('Device ID'),
subtitle: Text(device?.id ?? '12AB34CD:56EF78GH'),
),
GestureDetector(
onTap: () {
routeToPage(context, FirmwareUpdate(device: device));
},
child: ListTile(
title: const Text('Update Latest Version'),
subtitle: Text('Current: ${device?.firmwareRevision ?? '1.0.2'}'),
trailing: const Icon(
Icons.arrow_forward_ios,
size: 16,
),
),
),
GestureDetector(
onTap: () {
if (!provider.isDeviceV2Connected) {
showDialog(
context: context,
builder: (c) => getDialog(
context,
() => Navigator.of(context).pop(),
() => {},
'V2 undetected',
'We see that you either have a V1 device or your device is not connected. SD Card functionality is available only for V2 devices.',
singleButton: true,
),
);
} else {
var page = const SyncPage();
routeToPage(context, page);
}
},
child: const ListTile(
title: Text('SD Card Sync'),
subtitle: Text('Import audio files from SD Card'),
trailing: Icon(
Icons.arrow_forward_ios,
size: 16,
),
),
),
ListTile(
title: const Text('Hardware Revision'),
subtitle: Text(device?.hardwareRevision ?? 'XIAO'),
),
ListTile(
title: const Text('Model Number'),
subtitle: Text(device?.modelNumber ?? 'Omi DevKit'),
),
ListTile(
title: const Text('Manufacturer Name'),
subtitle: Text(device?.manufacturerName ?? 'Based Hardware'),
),
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:friend_private/backend/schema/bt_device/bt_device.dart';

class DeviceInfoCard extends StatelessWidget {
final BtDevice? device;
const DeviceInfoCard({super.key, this.device});

@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 18, 18, 18),
borderRadius: BorderRadius.circular(12.0),
border: Border.all(
color: Colors.white.withOpacity(0.15),
width: 1,
),
),
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 28, 28, 28),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
Icons.devices,
color: Colors.white,
size: 22,
),
),
const SizedBox(width: 16),
Text(
device?.name ?? 'Omi DevKit',
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
],
),
const SizedBox(height: 16),
DeviceInfoRow(label: 'Device ID', value: device?.id ?? '12AB34CD:56EF78GH'),
const SizedBox(height: 8),
DeviceInfoRow(label: 'Hardware', value: device?.hardwareRevision ?? 'XIAO'),
const SizedBox(height: 8),
DeviceInfoRow(label: 'Model', value: device?.modelNumber ?? 'Friend'),
const SizedBox(height: 8),
DeviceInfoRow(label: 'Manufacturer', value: device?.manufacturerName ?? 'Based Hardware'),
],
),
);
}
}

class DeviceInfoRow extends StatelessWidget {
final String label;
final String value;
const DeviceInfoRow({super.key, required this.label, required this.value});

@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.sizeOf(context).width * 0.24,
child: Text(
label,
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 14,
),
),
),
Expanded(
child: Text(
value,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
),
),
],
);
}
}
Loading