-
Notifications
You must be signed in to change notification settings - Fork 389
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
Recall pure socket #883
base: main
Are you sure you want to change the base?
Recall pure socket #883
Changes from 3 commits
2eff627
e5ea7a1
c0f87f1
a9ccb5b
13b929f
f8c612f
d137b8a
21e038c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -168,12 +168,12 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver { | |
ChangeNotifierProxyProvider3<MemoryProvider, MessageProvider, WebSocketProvider, CaptureProvider>( | ||
create: (context) => CaptureProvider(), | ||
update: (BuildContext context, memory, message, wsProvider, CaptureProvider? previous) => | ||
(previous?..updateProviderInstances(memory, message, wsProvider)) ?? CaptureProvider(), | ||
(previous?..updateProviderInstances(memory, message)) ?? CaptureProvider(), | ||
), | ||
ChangeNotifierProxyProvider2<CaptureProvider, WebSocketProvider, DeviceProvider>( | ||
create: (context) => DeviceProvider(), | ||
update: (BuildContext context, captureProvider, wsProvider, DeviceProvider? previous) => | ||
(previous?..setProviders(captureProvider, wsProvider)) ?? DeviceProvider(), | ||
(previous?..setProviders(captureProvider)) ?? DeviceProvider(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - (previous?..updateProviderInstances(memory, message, wsProvider)) ?? CaptureProvider(),
+ (previous?..updateProviderInstances(memory, message)) ?? CaptureProvider(),
- (previous?..setProviders(captureProvider, wsProvider)) ?? DeviceProvider(),
+ (previous?..setProviders(captureProvider)) ?? DeviceProvider(), |
||
), | ||
ChangeNotifierProxyProvider<DeviceProvider, OnboardingProvider>( | ||
create: (context) => OnboardingProvider(), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,6 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter/scheduler.dart'; | ||
import 'package:flutter_foreground_task/flutter_foreground_task.dart'; | ||
import 'package:flutter_provider_utilities/flutter_provider_utilities.dart'; | ||
import 'package:friend_private/backend/schema/bt_device.dart'; | ||
import 'package:friend_private/backend/schema/geolocation.dart'; | ||
import 'package:friend_private/pages/capture/widgets/widgets.dart'; | ||
import 'package:friend_private/providers/capture_provider.dart'; | ||
import 'package:friend_private/providers/connectivity_provider.dart'; | ||
import 'package:friend_private/providers/device_provider.dart'; | ||
import 'package:friend_private/providers/onboarding_provider.dart'; | ||
import 'package:friend_private/utils/audio/wav_bytes.dart'; | ||
import 'package:friend_private/utils/ble/communication.dart'; | ||
import 'package:friend_private/utils/enums.dart'; | ||
import 'package:friend_private/widgets/dialog.dart'; | ||
import 'package:provider/provider.dart'; | ||
|
||
import '../../providers/websocket_provider.dart'; | ||
|
||
@Deprecated("Capture page is deprecated, use @pages > memories > widgets > capture instead.") | ||
class CapturePage extends StatefulWidget { | ||
const CapturePage({ | ||
super.key, | ||
Comment on lines
1
to
6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The - @Deprecated("Capture page is deprecated, use @pages > memories > widgets > capture instead.")
- class CapturePage extends StatefulWidget {
- const CapturePage({
- super.key,
+ class CapturePage extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return const Text("This page has been deprecated. Please use @pages > memories > widgets > capture instead.");
+ } |
||
|
@@ -26,252 +10,9 @@ class CapturePage extends StatefulWidget { | |
State<CapturePage> createState() => CapturePageState(); | ||
} | ||
|
||
class CapturePageState extends State<CapturePage> with AutomaticKeepAliveClientMixin, WidgetsBindingObserver { | ||
@override | ||
bool get wantKeepAlive => true; | ||
|
||
/// ---- | ||
|
||
// List<TranscriptSegment> segments = List.filled(100, '') | ||
// .mapIndexed((i, e) => TranscriptSegment( | ||
// text: | ||
// '''[00:00:00 - 00:02:23] Speaker 0: The tech giants already know these techniques. | ||
// My goal is to unlock their secrets for the benefit of businesses who to design and help users develop healthy habits. | ||
// To that end, there's so much I wanted to put in this book that just didn't fit. Before you reading, please take a moment to download these | ||
// supplementary materials included free with the purchase of this audiobook. Please go to nirandfar.com forward slash hooked. | ||
// Near is spelled like my first name, speck, n I r. Andfar.com/hooked. There you will find the hooked model workbook, an ebook of case studies, | ||
// and a free email course about product psychology. Also, if you'd like to connect with me, you can reach me through my blog at nirafar.com. | ||
// You can schedule office hours to discuss your questions. Look forward to hearing from you as you build habits for good. | ||
// | ||
// Introduction. 79% of smartphone owners check their device within 15 minutes of waking up every morning. Perhaps most startling, | ||
// fully 1 third of Americans say they would rather give up sex than lose their cell phones. A 2011 university study suggested people check their | ||
// phones 34 times per day. However, industry insiders believe that number is closer to an astounding 150 daily sessions. We are hooked. | ||
// It's the poll to visit YouTube, Facebook, or Twitter for just a few minutes only to find yourself still capping and scrolling an hour later. | ||
// It's the urge you likely feel throughout your day but hardly notice. Cognitive psychologists define habits as, quote, automatic behaviors triggered | ||
// by situational cues. Things we do with little or no conscious thought. The products and services we use habitually alter our everyday behavior. | ||
// Just as their designers intended. Our actions have been engineered. How do companies producing little more than bits of code displayed on a screen | ||
// seemingly control users' minds? What makes some products so habit forming? Forming habit is imperative for the survival of many products. | ||
// | ||
// As infinite distractions compete for our attention, companies are learning to master novel tactics that stay relevant in users' minds. | ||
// Amassing millions of users is no longer good enough. Companies increasingly find that their economic value is a function of the strength of the habits they create. | ||
// | ||
// In order to win the loyalty of their users and create a product that's regularly used, companies must learn not only what compels users to click, | ||
// but also what makes them click. Although some companies are just waking up to this new reality, others are already cashing in. By mastering habit | ||
// forming product design, companies profiles in this book make their goods indispensable. First to mind wins. Companies that form strong user habits enjoy | ||
// several benefits to their bottom line. These companies attach their product to internal triggers. A result, users show up without any external prompting. | ||
// Instead of relying on expensive marketing, how did forming companies link their services to users' daily routines and emotions. | ||
// A habit is at work when users feel a tad bored and instantly open Twitter. Feel a hang of loneliness, and before rational thought occurs, | ||
// they're scrolling through their Facebook feeds.''', | ||
// speaker: 'SPEAKER_0${i % 2}', | ||
// isUser: false, | ||
// start: 0, | ||
// end: 10, | ||
// )) | ||
// .toList(); | ||
|
||
setHasTranscripts(bool hasTranscripts) { | ||
context.read<CaptureProvider>().setHasTranscripts(hasTranscripts); | ||
} | ||
|
||
void _onReceiveTaskData(dynamic data) { | ||
if (data is Map<String, dynamic>) { | ||
if (data.containsKey('latitude') && data.containsKey('longitude')) { | ||
context.read<CaptureProvider>().setGeolocation(Geolocation( | ||
latitude: data['latitude'], | ||
longitude: data['longitude'], | ||
accuracy: data['accuracy'], | ||
altitude: data['altitude'], | ||
time: DateTime.parse(data['time']), | ||
)); | ||
} else { | ||
if (mounted) { | ||
context.read<CaptureProvider>().setGeolocation(null); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@override | ||
void initState() { | ||
WavBytesUtil.clearTempWavFiles(); | ||
|
||
FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData); | ||
WidgetsBinding.instance.addObserver(this); | ||
SchedulerBinding.instance.addPostFrameCallback((_) async { | ||
// await context.read<CaptureProvider>().processCachedTranscript(); | ||
if (context.read<DeviceProvider>().connectedDevice != null) { | ||
context.read<OnboardingProvider>().stopFindDeviceTimer(); | ||
} | ||
// if (await LocationService().displayPermissionsDialog()) { | ||
// await showDialog( | ||
// context: context, | ||
// builder: (c) => getDialog( | ||
// context, | ||
// () => Navigator.of(context).pop(), | ||
// () async { | ||
// await requestLocationPermission(); | ||
// await LocationService().requestBackgroundPermission(); | ||
// if (mounted) Navigator.of(context).pop(); | ||
// }, | ||
// 'Enable Location? 🌍', | ||
// 'Allow location access to tag your memories. Set to "Always Allow" in Settings', | ||
// singleButton: false, | ||
// okButtonText: 'Continue', | ||
// ), | ||
// ); | ||
// } | ||
final connectivityProvider = Provider.of<ConnectivityProvider>(context, listen: false); | ||
if (!connectivityProvider.isConnected) { | ||
context.read<CaptureProvider>().cancelMemoryCreationTimer(); | ||
} | ||
}); | ||
|
||
super.initState(); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
WidgetsBinding.instance.removeObserver(this); | ||
// context.read<WebSocketProvider>().closeWebSocket(); | ||
super.dispose(); | ||
} | ||
|
||
// Future requestLocationPermission() async { | ||
// LocationService locationService = LocationService(); | ||
// bool serviceEnabled = await locationService.enableService(); | ||
// if (!serviceEnabled) { | ||
// debugPrint('Location service not enabled'); | ||
// if (mounted) { | ||
// ScaffoldMessenger.of(context).showSnackBar( | ||
// const SnackBar( | ||
// content: Text( | ||
// 'Location services are disabled. Enable them for a better experience.', | ||
// style: TextStyle(color: Colors.white, fontSize: 14), | ||
// ), | ||
// ), | ||
// ); | ||
// } | ||
// } else { | ||
// PermissionStatus permissionGranted = await locationService.requestPermission(); | ||
// SharedPreferencesUtil().locationEnabled = permissionGranted == PermissionStatus.granted; | ||
// MixpanelManager().setUserProperty('Location Enabled', SharedPreferencesUtil().locationEnabled); | ||
// if (permissionGranted == PermissionStatus.denied) { | ||
// debugPrint('Location permission not granted'); | ||
// } else if (permissionGranted == PermissionStatus.deniedForever) { | ||
// debugPrint('Location permission denied forever'); | ||
// if (mounted) { | ||
// ScaffoldMessenger.of(context).showSnackBar( | ||
// const SnackBar( | ||
// content: Text( | ||
// 'If you change your mind, you can enable location services in your device settings.', | ||
// style: TextStyle(color: Colors.white, fontSize: 14), | ||
// ), | ||
// ), | ||
// ); | ||
// } | ||
// } | ||
// } | ||
// } | ||
|
||
class CapturePageState extends State<CapturePage> { | ||
@override | ||
Widget build(BuildContext context) { | ||
super.build(context); | ||
return Consumer2<CaptureProvider, DeviceProvider>(builder: (context, provider, deviceProvider, child) { | ||
return MessageListener<CaptureProvider>( | ||
showInfo: (info) { | ||
// This probably will never be called because this has been handled even before we start the audio stream. But it's here just in case. | ||
if (info == 'FIM_CHANGE') { | ||
showDialog( | ||
context: context, | ||
barrierDismissible: false, | ||
builder: (c) => getDialog( | ||
context, | ||
() async { | ||
context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Firmware change detected'); | ||
var connectedDevice = deviceProvider.connectedDevice; | ||
var codec = await getAudioCodec(connectedDevice!.id); | ||
context.read<CaptureProvider>().resetState(restartBytesProcessing: true); | ||
context.read<CaptureProvider>().initiateWebsocket(codec); | ||
if (Navigator.canPop(context)) { | ||
Navigator.pop(context); | ||
} | ||
}, | ||
() => {}, | ||
'Firmware change detected!', | ||
'You are currently using a different firmware version than the one you were using before. Please restart the app to apply the changes.', | ||
singleButton: true, | ||
okButtonText: 'Restart', | ||
), | ||
); | ||
} | ||
}, | ||
showError: (error) { | ||
ScaffoldMessenger.of(context).showSnackBar( | ||
SnackBar( | ||
content: Text( | ||
error, | ||
style: const TextStyle(color: Colors.white, fontSize: 14), | ||
), | ||
), | ||
); | ||
}, | ||
child: Stack( | ||
children: [ | ||
ListView(children: [ | ||
SpeechProfileCardWidget(), | ||
...getConnectionStateWidgets( | ||
context, | ||
provider.hasTranscripts, | ||
deviceProvider.connectedDevice, | ||
context.read<WebSocketProvider>().wsConnectionState, | ||
), | ||
getTranscriptWidget( | ||
provider.memoryCreating, | ||
provider.segments, | ||
provider.photos, | ||
deviceProvider.connectedDevice, | ||
), | ||
...connectionStatusWidgets( | ||
context, | ||
provider.segments, | ||
context.read<WebSocketProvider>().wsConnectionState, | ||
), | ||
const SizedBox(height: 16) | ||
]), | ||
getPhoneMicRecordingButton(() => _recordingToggled(provider), provider.recordingState), | ||
], | ||
), | ||
); | ||
}); | ||
} | ||
|
||
_recordingToggled(CaptureProvider provider) async { | ||
var recordingState = provider.recordingState; | ||
if (recordingState == RecordingState.record) { | ||
provider.stopStreamRecording(); | ||
provider.updateRecordingState(RecordingState.stop); | ||
context.read<CaptureProvider>().cancelMemoryCreationTimer(); | ||
// await context.read<CaptureProvider>().tryCreateMemoryManually(); | ||
} else if (recordingState == RecordingState.initialising) { | ||
debugPrint('initialising, have to wait'); | ||
} else { | ||
showDialog( | ||
context: context, | ||
builder: (c) => getDialog( | ||
context, | ||
() => Navigator.pop(context), | ||
() async { | ||
provider.updateRecordingState(RecordingState.initialising); | ||
context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic'); | ||
await provider.initiateWebsocket(BleAudioCodec.pcm16, 16000); | ||
await provider.streamRecording(); | ||
Navigator.pop(context); | ||
}, | ||
'Limited Capabilities', | ||
'Recording with your phone microphone has a few limitations, including but not limited to: speaker profiles, background reliability.', | ||
okButtonText: 'Ok, I understand', | ||
), | ||
); | ||
} | ||
return const Text("Depreacted"); | ||
Comment on lines
+13
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - class CapturePageState extends State<CapturePage> {
- @override
- Widget build(BuildContext context) {
- return const Text("Depreacted");
- }
+ class CapturePageState extends State<CapturePage> {
+ // Add necessary state management and lifecycle methods here
+ @override
+ Widget build(BuildContext context) {
+ return const Text("This page has been deprecated. Please use @pages > memories > widgets > capture instead.");
+ } |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -544,7 +544,8 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver, Ticker | |
if (language != SharedPreferencesUtil().recordingsLanguage || | ||
hasSpeech != SharedPreferencesUtil().hasSpeakerProfile || | ||
transcriptModel != SharedPreferencesUtil().transcriptionModel) { | ||
context.read<DeviceProvider>().restartWebSocket(); | ||
// TODO: thinh, socket speech profile | ||
// context.read<DeviceProvider>().restartWebSocket(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The WebSocket restart logic has been commented out. If this is intentional and the functionality is being handled elsewhere, consider removing these lines entirely to avoid confusion. If the functionality is not handled elsewhere, this could lead to issues with the WebSocket connection not being properly restarted when necessary. - // TODO: thinh, socket speech profile
- // context.read<DeviceProvider>().restartWebSocket(); |
||
} | ||
}, | ||
), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,13 +34,15 @@ class LiteCaptureWidgetState extends State<LiteCaptureWidget> | |
void _onReceiveTaskData(dynamic data) { | ||
if (data is Map<String, dynamic>) { | ||
if (data.containsKey('latitude') && data.containsKey('longitude')) { | ||
context.read<CaptureProvider>().setGeolocation(Geolocation( | ||
latitude: data['latitude'], | ||
longitude: data['longitude'], | ||
accuracy: data['accuracy'], | ||
altitude: data['altitude'], | ||
time: DateTime.parse(data['time']), | ||
)); | ||
if (mounted) { | ||
context.read<CaptureProvider>().setGeolocation(Geolocation( | ||
latitude: data['latitude'], | ||
longitude: data['longitude'], | ||
accuracy: data['accuracy'], | ||
altitude: data['altitude'], | ||
time: DateTime.parse(data['time']), | ||
)); | ||
} | ||
Comment on lines
+37
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check for - context.read<CaptureProvider>().setGeolocation(Geolocation(
- latitude: data['latitude'],
- longitude: data['longitude'],
- accuracy: data['accuracy'],
- altitude: data['altitude'],
- time: DateTime.parse(data['time']),
- ));
+ if (mounted) {
+ context.read<CaptureProvider>().setGeolocation(Geolocation(
+ latitude: data['latitude'],
+ longitude: data['longitude'],
+ accuracy: data['accuracy'],
+ altitude: data['altitude'],
+ time: DateTime.parse(data['time']),
+ ));
+ } |
||
} else { | ||
if (mounted) { | ||
context.read<CaptureProvider>().setGeolocation(null); | ||
|
@@ -139,8 +141,7 @@ class LiteCaptureWidgetState extends State<LiteCaptureWidget> | |
context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Firmware change detected'); | ||
var connectedDevice = deviceProvider.connectedDevice; | ||
var codec = await _getAudioCodec(connectedDevice!.id); | ||
context.read<CaptureProvider>().resetState(restartBytesProcessing: true); | ||
context.read<CaptureProvider>().initiateWebsocket(codec); | ||
await context.read<CaptureProvider>().changeAudioRecordProfile(codec); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The refactoring of resetting state and initiating the websocket into a single method - context.read<CaptureProvider>().resetState(restartBytesProcessing: true);
- context.read<CaptureProvider>().initiateWebsocket(codec);
+ await context.read<CaptureProvider>().changeAudioRecordProfile(codec);
Comment on lines
140
to
+142
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new code seems to be missing the functionality of closing the WebSocket without reconnecting when a firmware change is detected. This was present in the old code but has been removed in the new one. If this functionality is still required, it should be reintroduced. + context.read<SocketServicePool>().closeSocketWithoutReconnect('Firmware change detected');
var connectedDevice = deviceProvider.connectedDevice;
var codec = await _getAudioCodec(connectedDevice!.id);
await context.read<CaptureProvider>().changeAudioRecordProfile(codec); Please ensure that |
||
if (Navigator.canPop(context)) { | ||
Navigator.pop(context); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,6 @@ import 'package:friend_private/pages/memory_capturing/page.dart'; | |
import 'package:friend_private/providers/capture_provider.dart'; | ||
import 'package:friend_private/providers/connectivity_provider.dart'; | ||
import 'package:friend_private/providers/device_provider.dart'; | ||
import 'package:friend_private/providers/websocket_provider.dart'; | ||
import 'package:friend_private/utils/analytics/mixpanel.dart'; | ||
import 'package:friend_private/utils/enums.dart'; | ||
import 'package:friend_private/utils/other/temp.dart'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The import statement for - import 'package:friend_private/providers/websocket_provider.dart'; |
||
|
@@ -80,7 +79,7 @@ class _MemoryCaptureWidgetState extends State<MemoryCaptureWidget> { | |
_toggleRecording(BuildContext context, CaptureProvider provider) async { | ||
var recordingState = provider.recordingState; | ||
if (recordingState == RecordingState.record) { | ||
provider.stopStreamRecording(); | ||
await provider.stopStreamRecording(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
context.read<CaptureProvider>().cancelMemoryCreationTimer(); | ||
await context.read<CaptureProvider>().createMemory(); | ||
MixpanelManager().phoneMicRecordingStopped(); | ||
|
@@ -95,8 +94,9 @@ class _MemoryCaptureWidgetState extends State<MemoryCaptureWidget> { | |
() async { | ||
Navigator.pop(context); | ||
provider.updateRecordingState(RecordingState.initialising); | ||
context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic'); | ||
await provider.initiateWebsocket(BleAudioCodec.pcm16, 16000); | ||
// TODO: thinh, socket check why we need to close socket provider here, disable temporary | ||
//context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic'); | ||
await provider.changeAudioRecordProfile(BleAudioCodec.pcm16, 16000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The call to close the WebSocket without reconnecting has been commented out and replaced with a call to - context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic');
- await provider.initiateWebsocket(BleAudioCodec.pcm16, 16000);
+ //context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic');
+ await provider.changeAudioRecordProfile(BleAudioCodec.pcm16, 16000); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - context.read<WebSocketProvider>().closeWebSocketWithoutReconnect('Recording with phone mic');
- await provider.initiateWebsocket(BleAudioCodec.pcm16, 16000);
+ await provider.changeAudioRecordProfile(BleAudioCodec.pcm16, 16000); |
||
await provider.streamRecording(); | ||
MixpanelManager().phoneMicRecordingStarted(); | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Entelligence.AI
The
wsProvider
argument has been removed from theupdateProviderInstances
method call. This could potentially cause issues if theCaptureProvider
class'supdateProviderInstances
method still expects three arguments. Please ensure that the method signature forupdateProviderInstances
in theCaptureProvider
class has been updated to match this change.