diff --git a/apps/AppWithWearable/lib/backend/api_requests/api/random_memory_img.dart b/apps/AppWithWearable/lib/backend/api_requests/api/random_memory_img.dart index 61f429862..6d16a114e 100644 --- a/apps/AppWithWearable/lib/backend/api_requests/api/random_memory_img.dart +++ b/apps/AppWithWearable/lib/backend/api_requests/api/random_memory_img.dart @@ -9,7 +9,7 @@ Future getImage() async { Uri.https(apiConstant, 'v1/randomimage', {'category': 'technology'}); final response = await http.get( url, - headers: {'X-Api-Key': 'hyycFNEH/Vm8bgpyjZ+eMQ==LUHnunq2o4QrWbr3'}, + headers: {'X-Api-Key': '+PVSQ6phxAnKHW4J4oz+7A==z4NR1q5X6DZ8RBDa'}, ); if (response.statusCode == 200) { diff --git a/apps/AppWithWearable/lib/features/capture/presentation/pages/capture_memory_page.dart b/apps/AppWithWearable/lib/features/capture/presentation/pages/capture_memory_page.dart index 1f10f7278..7c340acf1 100644 --- a/apps/AppWithWearable/lib/features/capture/presentation/pages/capture_memory_page.dart +++ b/apps/AppWithWearable/lib/features/capture/presentation/pages/capture_memory_page.dart @@ -68,6 +68,7 @@ class _CaptureMemoryPageState extends State { memoryBloc: _memoryBloc, ), const SizedBox(height: 8), + //*-- Capture --// CaptureCard( context: context, hasTranscripts: widget.hasTranscripts, diff --git a/apps/AppWithWearable/lib/features/chat/presentation/pages/chat_page.dart b/apps/AppWithWearable/lib/features/chat/presentation/pages/chat_page.dart index c7595e0e7..b78534916 100644 --- a/apps/AppWithWearable/lib/features/chat/presentation/pages/chat_page.dart +++ b/apps/AppWithWearable/lib/features/chat/presentation/pages/chat_page.dart @@ -83,7 +83,7 @@ class _ChatPageTestState extends State padding: const EdgeInsets.only( left: 20, right: 20, - bottom: 200, + bottom: 100, ), itemCount: state.messages?.length ?? 0, itemBuilder: (context, index) { @@ -122,7 +122,8 @@ class _ChatPageTestState extends State margin: EdgeInsets.only( left: 18, right: 18, - bottom: widget.textFieldFocusNode.hasFocus ? 40 : 120, + bottom: 18, + // bottom: widget.textFieldFocusNode.hasFocus ? 40 : 120, ), decoration: BoxDecoration( color: Colors.black, diff --git a/apps/AppWithWearable/lib/features/memory/presentation/pages/memory_detail_page.dart b/apps/AppWithWearable/lib/features/memory/presentation/pages/memory_detail_page.dart index 0ea62491d..149e408a3 100644 --- a/apps/AppWithWearable/lib/features/memory/presentation/pages/memory_detail_page.dart +++ b/apps/AppWithWearable/lib/features/memory/presentation/pages/memory_detail_page.dart @@ -2,12 +2,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:friend_private/backend/database/memory.dart'; import 'package:friend_private/features/memory/presentation/bloc/memory_bloc.dart'; +import 'package:friend_private/features/memory/presentation/widgets/action_tab.dart'; +import 'package:friend_private/features/memory/presentation/widgets/event_tab.dart'; import 'package:friend_private/features/memory/presentation/widgets/summary_tab.dart'; import 'package:friend_private/features/memory/presentation/widgets/transcript_tab.dart'; import 'package:friend_private/pages/home/backgrund_scafold.dart'; +import 'package:friend_private/pages/memory_detail/enable_title.dart'; import 'package:friend_private/pages/memory_detail/share.dart'; import 'package:friend_private/pages/memory_detail/widgets.dart'; import 'package:friend_private/utils/memories/reprocess.dart'; +import 'package:friend_private/utils/other/temp.dart'; class CustomMemoryDetailPage extends StatefulWidget { const CustomMemoryDetailPage({ @@ -37,7 +41,7 @@ class _CustomMemoryDetailPageState extends State { ); }, child: DefaultTabController( - length: 2, + length: 4, initialIndex: 1, child: CustomScaffold( backgroundColor: Colors.transparent, @@ -68,32 +72,117 @@ class _CustomMemoryDetailPageState extends State { elevation: 0, title: Text( "${widget.memoryBloc.state.memories[widget.memoryAtIndex].structured.target!.getEmoji()}"), - bottom: const TabBar( - tabs: [ - Tab(text: 'Transcript'), - Tab(text: 'Summary'), - ], - ), ), body: BlocBuilder( bloc: widget.memoryBloc, builder: (context, state) { - return TabBarView( + print('memory Details Page ${state.toString()}'); + final selectedMemory = state.memories[state.memoryIndex]; + + final structured = selectedMemory.structured.target!; + final time = selectedMemory.startedAt == null + ? dateTimeFormat('h:mm a', selectedMemory.createdAt) + : '${dateTimeFormat('h:mm a', selectedMemory.startedAt)} to ${dateTimeFormat('h:mm a', selectedMemory.finishedAt)}'; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - TranscriptTab( - pageController: pageController, - memoryAtIndex: state.memoryIndex, - memoryBloc: widget.memoryBloc, + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text( + '${dateTimeFormat('MMM d, yyyy', selectedMemory.createdAt)} ' + '${selectedMemory.startedAt == null ? 'at' : 'from'} $time', + style: const TextStyle(color: Colors.grey, fontSize: 16), + ), ), - // SummaryTab( - // memoryBloc: widget.memoryBloc, - // memoryAtIndex: state.memoryIndex, - // ), - SummaryTab( - pageController: pageController, - memoryAtIndex: state.memoryIndex, - memoryBloc: widget.memoryBloc, + const SizedBox(height: 16), + selectedMemory.discarded + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Text( + 'Discarded Memory', + style: Theme.of(context).textTheme.titleLarge, + ), + ) + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: EditableTitle( + initialText: structured.title, + onTextChanged: (String newTitle) { + structured.title = newTitle; + widget.memoryBloc + .add(UpdatedMemory(structured: structured)); + }, + discarded: selectedMemory.discarded, + style: Theme.of(context).textTheme.titleLarge!, + ), + ), + const SizedBox(height: 16), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: const Color.fromARGB(255, 29, 29, 29), + ), + margin: + const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + // color: const Color.fromARGB(75, 242, 242, 242), + + child: SizedBox( + height: 40, + child: TabBar( + dividerColor: Colors.transparent, + padding: const EdgeInsets.symmetric( + vertical: 4, horizontal: 4), + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Colors.white, + unselectedLabelColor: Colors.grey, + indicator: BoxDecoration( + borderRadius: BorderRadius.circular( + 6, + ), + color: const Color.fromARGB(125, 158, 158, 158), + ), + indicatorWeight: 0, + labelPadding: EdgeInsets.zero, + tabs: const [ + Tab(text: 'Transcript'), + Tab(text: 'Summary'), + Tab(text: 'Action'), + Tab(text: 'Events'), + ], + ), + ), ), + Expanded( + child: TabBarView( + children: [ + TranscriptTab( + pageController: pageController, + memoryAtIndex: state.memoryIndex, + memoryBloc: widget.memoryBloc, + ), + // SummaryTab( + // memoryBloc: widget.memoryBloc, + // memoryAtIndex: state.memoryIndex, + // ), + SummaryTab( + pageController: pageController, + memoryAtIndex: state.memoryIndex, + memoryBloc: widget.memoryBloc, + ), + ActionTab( + pageController: pageController, + memoryAtIndex: state.memoryIndex, + memoryBloc: widget.memoryBloc, + ), + EventTab( + pageController: pageController, + memoryAtIndex: state.memoryIndex, + memoryBloc: widget.memoryBloc, + ) + ], + ), + ) ], ); }, diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/action_tab.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/action_tab.dart new file mode 100644 index 000000000..a9c07d3ac --- /dev/null +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/action_tab.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:friend_private/backend/database/memory_provider.dart'; +import 'package:friend_private/backend/mixpanel.dart'; +import 'package:friend_private/features/memory/presentation/bloc/memory_bloc.dart'; +import 'package:friend_private/utils/other/temp.dart'; + +class ActionTab extends StatefulWidget { + const ActionTab( + {super.key, + required this.memoryAtIndex, + required this.memoryBloc, + required this.pageController}); + final int memoryAtIndex; + final MemoryBloc memoryBloc; + final PageController pageController; + + @override + State createState() => _ActionTabState(); +} + +class _ActionTabState extends State { + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final selectedMemory = state.memories[state.memoryIndex]; + final structured = state.memories[state.memoryIndex].structured.target!; + + if (state.status == MemoryStatus.success) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16,vertical: 12), + child: Column( + children: [ + structured.actionItems.isNotEmpty + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Action Items', + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontSize: 26), + ), + IconButton( + onPressed: () { + Clipboard.setData(ClipboardData( + text: + '- ${structured.actionItems.map((e) => e.description).join('\n- ')}')); + ScaffoldMessenger.of(context) + .showSnackBar(const SnackBar( + content: Text('Action items copied to clipboard'), + duration: Duration(seconds: 2), + )); + MixpanelManager().copiedMemoryDetails( + selectedMemory, + source: 'Action Items'); + }, + icon: const Icon(Icons.copy_rounded, + color: Colors.white, size: 20), + ) + ], + ) + : const SizedBox( + height: 400, + child: Center( + child: Text("Oops! This Memory Don't have Action")), + ), + ...structured.actionItems.map( + (item) { + return Padding( + padding: const EdgeInsets.only(top: 10), + child: ListTile( + onTap: () { + setState(() { + item.completed = !item.completed; + MemoryProvider().updateActionItem(item); + }); + }, + contentPadding: EdgeInsets.zero, + leading: Icon( + color: item.completed ? Colors.green : Colors.grey, + item.completed ? Icons.task_alt : Icons.circle_outlined, + size: 20, + ), + title: Text( + item.description, + style: TextStyle( + color: Colors.grey.shade300, + fontSize: 16, + height: 1.3, + ), + ), + ), + ); + }, + ), + ], + ), + ), + ); + } + return const SizedBox.shrink(); + }, + ); + } +} diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/event_tab.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/event_tab.dart new file mode 100644 index 000000000..e09cc759f --- /dev/null +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/event_tab.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:friend_private/backend/database/memory_provider.dart'; +import 'package:friend_private/backend/preferences.dart'; +import 'package:friend_private/features/memory/presentation/bloc/memory_bloc.dart'; +import 'package:friend_private/pages/settings/calendar.dart'; +import 'package:friend_private/utils/features/calendar.dart'; +import 'package:friend_private/utils/other/temp.dart'; + +class EventTab extends StatefulWidget { + const EventTab( + {super.key, + required this.memoryAtIndex, + required this.memoryBloc, + required this.pageController}); + final int memoryAtIndex; + final MemoryBloc memoryBloc; + final PageController pageController; + + @override + State createState() => _EventTabState(); +} + +class _EventTabState extends State { + // late PageController _pageController; + @override + void initState() { + super.initState(); + + // _pageController = PageController(initialPage: widget.memoryAtIndex); + // widget.pageController.addListener(_onPageChanged); + } + + // void _onPageChanged() { + // final currentPage = widget.pageController.page?.round(); + // if (currentPage != null) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: currentPage)); + // } + // } + + // @override + // void dispose() { + // widget.pageController.removeListener(_onPageChanged); + // super.dispose(); + // } + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final structured = state.memories[state.memoryIndex].structured.target!; + // return PageView.builder( + // scrollDirection: Axis.vertical, + // // controller: _pageController, + // itemCount: state.memories.length, + // onPageChanged: (index) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: index)); + // }, + // itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: SingleChildScrollView( + child: Column( + children: [ + structured.events.isNotEmpty + ? Row( + children: [ + Icon(Icons.event, color: Colors.grey.shade300), + const SizedBox(width: 8), + Text( + 'Events', + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(fontSize: 26), + ) + ], + ) + : const SizedBox( + height: 400, + child: Center( + child: Text("Oops! This Memory Don't have Events")), + ), + ...structured.events.map( + (event) { + return ListTile( + contentPadding: EdgeInsets.zero, + title: Text( + event.title, + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600), + ), + subtitle: Padding( + padding: const EdgeInsets.only(top: 4.0), + child: Text( + '' + '${dateTimeFormat('MMM d, yyyy', event.startsAt)} at ${dateTimeFormat('h:mm a', event.startsAt)} ~ ${event.duration} minutes.', + style: + const TextStyle(color: Colors.grey, fontSize: 15), + ), + ), + trailing: IconButton( + onPressed: event.created + ? null + : () { + var calEnabled = + SharedPreferencesUtil().calendarEnabled; + var calSelected = SharedPreferencesUtil() + .calendarId + .isNotEmpty; + if (!calEnabled || !calSelected) { + routeToPage(context, const CalendarPage()); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(!calEnabled + ? 'Enable calendar integration to add events' + : 'Select a calendar to add events to'), + ), + ); + return; + } + MemoryProvider().setEventCreated(event); + setState(() => event.created = true); + CalendarUtil().createEvent( + event.title, + event.startsAt, + event.duration, + description: event.description, + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Event added to calendar'), + ), + ); + }, + icon: Icon(event.created ? Icons.check : Icons.add, + color: Colors.white), + ), + ); + }, + ), + ], + ), + ), + ); + }, + ); + // }, + // ); + } +} diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_card.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_card.dart index 2ce99a37f..37f58de2c 100644 --- a/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_card.dart +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_card.dart @@ -30,9 +30,9 @@ class MemoryCardWidget extends StatelessWidget { ); } return SizedBox( - height: height*0.4, + height: (height-10)*0.38, child: ListView.separated( - padding: const EdgeInsets.only(left: 12,right: 12,bottom: 50), + padding: const EdgeInsets.only(left: 12,right: 12,bottom:0), shrinkWrap: true, itemCount: state.memories.length, @@ -41,6 +41,8 @@ class MemoryCardWidget extends StatelessWidget { Memory memory = state.memories[index]; //*-- Delete Memory Card --*// return Dismissible( + direction: DismissDirection.endToStart, + background: Container(color: Colors.red.withOpacity(0.5),), key: Key(memory.id.toString()), confirmDismiss: (direction) async { return await showDialog( diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_search.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_search.dart index 4787ed713..f926a6ae5 100644 --- a/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_search.dart +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/memory_search.dart @@ -23,7 +23,7 @@ class MemorySearchWidget extends StatelessWidget { color: Colors.black, borderRadius: const BorderRadius.all(Radius.circular(16)), border: Border.all( - color: Colors.grey, + color: Color.fromARGB(53, 158, 158, 158), ), shape: BoxShape.rectangle, ), @@ -39,7 +39,7 @@ class MemorySearchWidget extends StatelessWidget { // focusNode: widget.textFieldFocusNode, decoration: InputDecoration( hintText: 'Search for memories...', - hintStyle: const TextStyle(fontSize: 14.0, color: Colors.grey), + hintStyle: const TextStyle(fontSize: 14.0, color: Color.fromARGB(255, 124, 124, 124)), enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, suffixIcon: _searchController.text.isEmpty diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/summary_tab.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/summary_tab.dart index 95ee54351..26c958b1e 100644 --- a/apps/AppWithWearable/lib/features/memory/presentation/widgets/summary_tab.dart +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/summary_tab.dart @@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:friend_private/backend/database/memory_provider.dart'; import 'package:friend_private/backend/mixpanel.dart'; import 'package:friend_private/backend/preferences.dart'; +import 'package:friend_private/backend/schema/plugin.dart'; import 'package:friend_private/features/memory/presentation/bloc/memory_bloc.dart'; import 'package:friend_private/pages/memory_detail/enable_title.dart'; import 'package:friend_private/pages/settings/calendar.dart'; @@ -27,115 +28,117 @@ class SummaryTab extends StatefulWidget { } class _SummaryTabState extends State { - late PageController _pageController; - late ScrollController _scrollController; - ScrollPhysics _scrollPhysics = const AlwaysScrollableScrollPhysics(); - // List pluginsList = SharedPreferencesUtil().pluginsList; - // List pluginResponseExpanded = []; + // late PageController _pageController; + // final ScrollController _scrollController = ScrollController(); + List pluginsList = SharedPreferencesUtil().pluginsList; + List pluginResponseExpanded = []; + @override void initState() { super.initState(); - _pageController = PageController(initialPage: widget.memoryAtIndex); - _scrollController = ScrollController(); - widget.pageController.addListener(_onPageChanged); - _scrollController.addListener(_onScroll); + // _pageController = PageController(initialPage: widget.memoryAtIndex); + + // widget.pageController.addListener(_onPageChanged); + // _scrollController.addListener(() { + // _onScroll(); + // }); // pluginResponseExpanded = List.filled( // widget.memoryBloc.state.memories[widget.memoryAtIndex].pluginsResponse // .length, // false); } - void _onPageChanged() { - final currentPage = widget.pageController.page?.round(); - if (currentPage != null) { - widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: currentPage)); - } - // setState(() { - // pluginsList[currentPage??0]; - // pluginResponseExpanded = List.filled( - // widget.memoryBloc.state.memories[currentPage!].pluginsResponse.length, - // false); - // }); - } + // void _onPageChanged() { + // final currentPage = widget.pageController.page?.round(); + // if (currentPage != null) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: currentPage)); + // setState(() { + // pluginResponseExpanded = List.filled( + // widget.memoryBloc.state.memories[currentPage].pluginsResponse.length, + // false, + // ); + // }); + // } + // } - @override - void dispose() { - widget.pageController.removeListener(_onPageChanged); - _scrollController.dispose(); - super.dispose(); - } + // void _onScroll() { + // if (_scrollController.position.pixels > + // (_scrollController.position.maxScrollExtent + 50)) { + // _pageController.nextPage( + // duration: const Duration(milliseconds: 500), + // curve: Curves.easeInOut, + // ); + // } - void _onScroll() { - if (_scrollController.position.atEdge) { - if (_scrollController.position.pixels == 0) { - // Reached the top - setState(() { - _scrollPhysics = const NeverScrollableScrollPhysics(); - }); - } else { - // Reached the bottom - setState(() { - _scrollPhysics = const NeverScrollableScrollPhysics(); - }); - } - } else { - setState(() { - _scrollPhysics = const AlwaysScrollableScrollPhysics(); - }); - } - } + // if (_scrollController.position.pixels < + // (_scrollController.position.minScrollExtent - 50)) { + // _pageController.previousPage( + // duration: const Duration(milliseconds: 500), + // curve: Curves.easeInOut, + // ); + // } + // } + + // @override + // void dispose() { + // widget.pageController.removeListener(_onPageChanged); + // _scrollController.dispose(); + // super.dispose(); + // } @override Widget build(BuildContext context) { return BlocBuilder( bloc: widget.memoryBloc, builder: (context, state) { - // _currentPage = state.memoryIndex; final selectedMemory = state.memories[state.memoryIndex]; + final structured = selectedMemory.structured.target!; final time = selectedMemory.startedAt == null ? dateTimeFormat('h:mm a', selectedMemory.createdAt) : '${dateTimeFormat('h:mm a', selectedMemory.startedAt)} to ${dateTimeFormat('h:mm a', selectedMemory.finishedAt)}'; - print('index ${state.memoryIndex}'); - return PageView.builder( - scrollDirection: Axis.vertical, - controller: _pageController, - itemCount: state.memories.length, - onPageChanged: (index) { - widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: index)); - }, - itemBuilder: (BuildContext context, int index) { + print( + 'index ${state.memoryIndex}, time:$time,title:${structured.title},overview:${structured.overview}'); + + // return PageView.builder( + // scrollDirection: Axis.vertical, + // // controller: _pageController, + // itemCount: state.memories.length, + // onPageChanged: (index) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: index)); + // }, + // itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: SingleChildScrollView( - physics: _scrollPhysics, - controller: _scrollController, + // physics: const BouncingScrollPhysics(), + // controller: _scrollController, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ //*--- TITLE ---*// - const SizedBox(height: 12), - selectedMemory.discarded - ? Text( - 'Discarded Memory', - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(fontSize: 32), - ) - : EditableTitle( - initialText: structured.title, - onTextChanged: (String newTitle) { - structured.title = newTitle; - widget.memoryBloc - .add(UpdatedMemory(structured: structured)); - }, - discarded: selectedMemory.discarded, - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(fontSize: 32), - ), + // const SizedBox(height: 12), + // selectedMemory.discarded + // ? Text( + // 'Discarded Memory', + // style: Theme.of(context) + // .textTheme + // .titleLarge! + // .copyWith(fontSize: 32), + // ) + // : EditableTitle( + // initialText: structured.title, + // onTextChanged: (String newTitle) { + // structured.title = newTitle; + // widget.memoryBloc + // .add(UpdatedMemory(structured: structured)); + // }, + // discarded: selectedMemory.discarded, + // style: Theme.of(context) + // .textTheme + // .titleLarge! + // .copyWith(fontSize: 32), + // ), // Text( // structured.title, // style: Theme.of(context) @@ -145,12 +148,12 @@ class _SummaryTabState extends State { // ), const SizedBox(height: 16), //*--- TIME ---*// - Text( - '${dateTimeFormat('MMM d, yyyy', selectedMemory.createdAt)} ' - '${selectedMemory.startedAt == null ? 'at' : 'from'} $time', - style: const TextStyle(color: Colors.grey, fontSize: 16), - ), - const SizedBox(height: 16), + // Text( + // '${dateTimeFormat('MMM d, yyyy', selectedMemory.createdAt)} ' + // '${selectedMemory.startedAt == null ? 'at' : 'from'} $time', + // style: const TextStyle(color: Colors.grey, fontSize: 16), + // ), + // const SizedBox(height: 16), //*--- IMAGE ---*// Stack( children: [ @@ -216,152 +219,152 @@ class _SummaryTabState extends State { ? const SizedBox.shrink() : const SizedBox(height: 40), //*--- ACTION ITEMS ---*// - structured.actionItems.isNotEmpty - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Action Items', - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(fontSize: 26), - ), - IconButton( - onPressed: () { - Clipboard.setData(ClipboardData( - text: - '- ${structured.actionItems.map((e) => e.description).join('\n- ')}')); - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text( - 'Action items copied to clipboard'), - duration: Duration(seconds: 2), - )); - MixpanelManager().copiedMemoryDetails( - selectedMemory, - source: 'Action Items'); - }, - icon: const Icon(Icons.copy_rounded, - color: Colors.white, size: 20), - ) - ], - ) - : const SizedBox.shrink(), - ...structured.actionItems.map( - (item) { - return Padding( - padding: const EdgeInsets.only(top: 10), - child: ListTile( - onTap: () { - setState(() { - item.completed = !item.completed; - MemoryProvider().updateActionItem(item); - }); - }, - contentPadding: EdgeInsets.zero, - leading: Icon( - color: - item.completed ? Colors.green : Colors.grey, - item.completed - ? Icons.task_alt - : Icons.circle_outlined, - size: 20, - ), - title: Text( - item.description, - style: TextStyle( - color: Colors.grey.shade300, - fontSize: 16, - height: 1.3, - ), - ), - ), - ); - }, - ), + // structured.actionItems.isNotEmpty + // ? Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // 'Action Items', + // style: Theme.of(context) + // .textTheme + // .titleLarge! + // .copyWith(fontSize: 26), + // ), + // IconButton( + // onPressed: () { + // Clipboard.setData(ClipboardData( + // text: + // '- ${structured.actionItems.map((e) => e.description).join('\n- ')}')); + // ScaffoldMessenger.of(context) + // .showSnackBar(const SnackBar( + // content: Text( + // 'Action items copied to clipboard'), + // duration: Duration(seconds: 2), + // )); + // MixpanelManager().copiedMemoryDetails( + // selectedMemory, + // source: 'Action Items'); + // }, + // icon: const Icon(Icons.copy_rounded, + // color: Colors.white, size: 20), + // ) + // ], + // ) + // : const SizedBox.shrink(), + // ...structured.actionItems.map( + // (item) { + // return Padding( + // padding: const EdgeInsets.only(top: 10), + // child: ListTile( + // onTap: () { + // setState(() { + // item.completed = !item.completed; + // MemoryProvider().updateActionItem(item); + // }); + // }, + // contentPadding: EdgeInsets.zero, + // leading: Icon( + // color: + // item.completed ? Colors.green : Colors.grey, + // item.completed + // ? Icons.task_alt + // : Icons.circle_outlined, + // size: 20, + // ), + // title: Text( + // item.description, + // style: TextStyle( + // color: Colors.grey.shade300, + // fontSize: 16, + // height: 1.3, + // ), + // ), + // ), + // ); + // }, + // ), //*--- EVENTS ---*// - structured.events.isNotEmpty - ? Row( - children: [ - Icon(Icons.event, color: Colors.grey.shade300), - const SizedBox(width: 8), - Text( - 'Events', - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(fontSize: 26), - ) - ], - ) - : const SizedBox.shrink(), - ...structured.events.map( - (event) { - return ListTile( - contentPadding: EdgeInsets.zero, - title: Text( - event.title, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w600), - ), - subtitle: Padding( - padding: const EdgeInsets.only(top: 4.0), - child: Text( - '' - '${dateTimeFormat('MMM d, yyyy', event.startsAt)} at ${dateTimeFormat('h:mm a', event.startsAt)} ~ ${event.duration} minutes.', - style: const TextStyle( - color: Colors.grey, fontSize: 15), - ), - ), - trailing: IconButton( - onPressed: event.created - ? null - : () { - var calEnabled = - SharedPreferencesUtil().calendarEnabled; - var calSelected = SharedPreferencesUtil() - .calendarId - .isNotEmpty; - if (!calEnabled || !calSelected) { - routeToPage( - context, const CalendarPage()); - ScaffoldMessenger.of(context) - .showSnackBar( - SnackBar( - content: Text(!calEnabled - ? 'Enable calendar integration to add events' - : 'Select a calendar to add events to'), - ), - ); - return; - } - MemoryProvider().setEventCreated(event); - setState(() => event.created = true); - CalendarUtil().createEvent( - event.title, - event.startsAt, - event.duration, - description: event.description, - ); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: - Text('Event added to calendar'), - ), - ); - }, - icon: Icon(event.created ? Icons.check : Icons.add, - color: Colors.white), - ), - ); - }, - ), - const SizedBox( - height: 25, - ), + // structured.events.isNotEmpty + // ? Row( + // children: [ + // Icon(Icons.event, color: Colors.grey.shade300), + // const SizedBox(width: 8), + // Text( + // 'Events', + // style: Theme.of(context) + // .textTheme + // .titleLarge! + // .copyWith(fontSize: 26), + // ) + // ], + // ) + // : const SizedBox.shrink(), + // ...structured.events.map( + // (event) { + // return ListTile( + // contentPadding: EdgeInsets.zero, + // title: Text( + // event.title, + // style: const TextStyle( + // color: Colors.white, + // fontSize: 16, + // fontWeight: FontWeight.w600), + // ), + // subtitle: Padding( + // padding: const EdgeInsets.only(top: 4.0), + // child: Text( + // '' + // '${dateTimeFormat('MMM d, yyyy', event.startsAt)} at ${dateTimeFormat('h:mm a', event.startsAt)} ~ ${event.duration} minutes.', + // style: const TextStyle( + // color: Colors.grey, fontSize: 15), + // ), + // ), + // trailing: IconButton( + // onPressed: event.created + // ? null + // : () { + // var calEnabled = + // SharedPreferencesUtil().calendarEnabled; + // var calSelected = SharedPreferencesUtil() + // .calendarId + // .isNotEmpty; + // if (!calEnabled || !calSelected) { + // routeToPage( + // context, const CalendarPage()); + // ScaffoldMessenger.of(context) + // .showSnackBar( + // SnackBar( + // content: Text(!calEnabled + // ? 'Enable calendar integration to add events' + // : 'Select a calendar to add events to'), + // ), + // ); + // return; + // } + // MemoryProvider().setEventCreated(event); + // setState(() => event.created = true); + // CalendarUtil().createEvent( + // event.title, + // event.startsAt, + // event.duration, + // description: event.description, + // ); + // ScaffoldMessenger.of(context).showSnackBar( + // const SnackBar( + // content: + // Text('Event added to calendar'), + // ), + // ); + // }, + // icon: Icon(event.created ? Icons.check : Icons.add, + // color: Colors.white), + // ), + // ); + // }, + // ), + // const SizedBox( + // height: 25, + // ), // ...getPluginsWidgets( // context, // state.memories[index], @@ -381,7 +384,7 @@ class _SummaryTabState extends State { // ); }, ); - }, - ); + // }, + // ); } } diff --git a/apps/AppWithWearable/lib/features/memory/presentation/widgets/transcript_tab.dart b/apps/AppWithWearable/lib/features/memory/presentation/widgets/transcript_tab.dart index da948f3cc..7a365ea5b 100644 --- a/apps/AppWithWearable/lib/features/memory/presentation/widgets/transcript_tab.dart +++ b/apps/AppWithWearable/lib/features/memory/presentation/widgets/transcript_tab.dart @@ -20,47 +20,50 @@ class TranscriptTab extends StatefulWidget { } class _TranscriptTabState extends State { - late PageController _pageController; + // late PageController _pageController; @override void initState() { super.initState(); - _pageController = PageController(initialPage: widget.memoryAtIndex); - widget.pageController.addListener(_onPageChanged); + // _pageController = PageController(initialPage: widget.memoryAtIndex); + // widget.pageController.addListener(_onPageChanged); } - void _onPageChanged() { - final currentPage = widget.pageController.page?.round(); - if (currentPage != null) { - widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: currentPage)); - } - } + // void _onPageChanged() { + // final currentPage = widget.pageController.page?.round(); + // if (currentPage != null) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: currentPage)); + // } + // } - @override - void dispose() { - widget.pageController.removeListener(_onPageChanged); - super.dispose(); - } + // @override + // void dispose() { + // widget.pageController.removeListener(_onPageChanged); + // super.dispose(); + // } @override Widget build(BuildContext context) { return BlocBuilder( bloc: widget.memoryBloc, builder: (context, state) { - return PageView.builder( - scrollDirection: Axis.vertical, - controller: _pageController, - itemCount: state.memories.length, - onPageChanged: (index) { - widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: index)); - }, - itemBuilder: (BuildContext context, int index) { - return TranscriptWidget( - segments: state.memories[index].transcriptSegments, + // return PageView.builder( + // scrollDirection: Axis.vertical, + // controller: _pageController, + // itemCount: state.memories.length, + // onPageChanged: (index) { + // widget.memoryBloc.add(MemoryIndexChanged(memoryIndex: index)); + // }, + // itemBuilder: (BuildContext context, int index) { + return SingleChildScrollView( + child: TranscriptWidget( + segments: state.memories[widget.memoryAtIndex].transcriptSegments, + // segments: state.memories[index].transcriptSegments, + ), ); }, ); - }, - ); + // }, + // ); } } diff --git a/apps/AppWithWearable/lib/main.dart b/apps/AppWithWearable/lib/main.dart index 4d3f3015d..f5d04298c 100644 --- a/apps/AppWithWearable/lib/main.dart +++ b/apps/AppWithWearable/lib/main.dart @@ -24,6 +24,7 @@ import 'package:friend_private/features/memory/presentation/bloc/memory_bloc.dar import 'package:friend_private/firebase_options_dev.dart' as dev; import 'package:friend_private/firebase_options_prod.dart' as prod; import 'package:friend_private/flavors.dart'; +import 'package:friend_private/pages/home/home_page_wrapper.dart'; import 'package:friend_private/pages/home/page.dart'; import 'package:friend_private/utils/features/calendar.dart'; import 'package:friend_private/utils/other/notifications.dart'; @@ -222,7 +223,7 @@ class _MyAppState extends State { ), // SharedPreferencesUtil().onboardingCompleted && widget.isAuth // ? - const HomePageWrapper() + const HomePageWrapperTest() // : const OnboardingWrapper(), ], ), diff --git a/apps/AppWithWearable/lib/pages/capture/connect.dart b/apps/AppWithWearable/lib/pages/capture/connect.dart index 93cb2883c..abca95b9a 100644 --- a/apps/AppWithWearable/lib/pages/capture/connect.dart +++ b/apps/AppWithWearable/lib/pages/capture/connect.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:friend_private/pages/capture/widgets/ripple_animation.dart'; import 'package:friend_private/pages/home/backgrund_scafold.dart'; -import 'package:friend_private/pages/home/page.dart'; +import 'package:friend_private/pages/home/home_page_wrapper.dart'; import 'package:friend_private/pages/onboarding/find_device/page.dart'; class ConnectDevicePage extends StatefulWidget { @@ -46,7 +46,7 @@ class _ConnectDevicePageState extends State { goNext: () { debugPrint('onConnected'); Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (c) => const HomePageWrapper()), + MaterialPageRoute(builder: (c) => const HomePageWrapperTest()), ); }, includeSkip: false, diff --git a/apps/AppWithWearable/lib/pages/capture/page.dart b/apps/AppWithWearable/lib/pages/capture/page.dart index 66fbc5073..ab9b4bea8 100644 --- a/apps/AppWithWearable/lib/pages/capture/page.dart +++ b/apps/AppWithWearable/lib/pages/capture/page.dart @@ -146,7 +146,7 @@ class CapturePageState extends State if (_scrollController.hasClients) { _scrollController.animateTo( _scrollController.position.maxScrollExtent, - duration: const Duration(milliseconds:100), + duration: const Duration(milliseconds: 100), curve: Curves.easeOut, ); } @@ -412,6 +412,7 @@ class CapturePageState extends State memoryCreating: memoryCreating, photos: photos, scrollController: _scrollController, + ), // ...getConnectionStateWidgets( // context, @@ -426,7 +427,7 @@ class CapturePageState extends State const SizedBox(height: 16) ], ), - getPhoneMicRecordingButton(_recordingToggled, recordingState) + // getPhoneMicRecordingButton(_recordingToggled, recordingState) ], ); } diff --git a/apps/AppWithWearable/lib/pages/capture/widgets/sin_wave.dart b/apps/AppWithWearable/lib/pages/capture/widgets/sin_wave.dart index 39d6d5bb4..67940f4af 100644 --- a/apps/AppWithWearable/lib/pages/capture/widgets/sin_wave.dart +++ b/apps/AppWithWearable/lib/pages/capture/widgets/sin_wave.dart @@ -59,7 +59,10 @@ class _SineWaveWidgetState extends State builder: (context, child) { return isWifiDisconnected ? const SizedBox.shrink() - : Lottie.asset('assets/lottie_animations/wave_animation.json'); + : Lottie.asset('assets/lottie_animations/wave_animation.json', controller: _sineAnimController, + onLoaded: (composition) { + _sineAnimController.duration = composition.duration * 0.5; + },); }, ); }, diff --git a/apps/AppWithWearable/lib/pages/capture/widgets/widgets.dart b/apps/AppWithWearable/lib/pages/capture/widgets/widgets.dart index 789e5a01d..a222992f1 100644 --- a/apps/AppWithWearable/lib/pages/capture/widgets/widgets.dart +++ b/apps/AppWithWearable/lib/pages/capture/widgets/widgets.dart @@ -46,6 +46,7 @@ class CaptureCard extends StatelessWidget { final bool memoryCreating; final List> photos; final ScrollController? scrollController; + @override Widget build(BuildContext context) { return GestureDetector( @@ -147,6 +148,7 @@ class GetConnectionStateWidgets extends StatelessWidget { final InternetStatus? internetStatus; final double sizeMultiplier; + // final RecordingState micRecordState; @override Widget build(BuildContext context) { bool isWifiDisconnected = internetStatus == InternetStatus.disconnected; @@ -173,7 +175,11 @@ class GetConnectionStateWidgets extends StatelessWidget { builder: (context) { if (isDeviceDisconnected) { if (SharedPreferencesUtil().deviceId.isEmpty) { - return _getNoFriendConnectedYet(context); + return const Icon( + Icons.power_off_outlined, + size: 40, + color: Colors.grey, + ); } else { return Image.asset('assets/images/device.png'); } @@ -264,7 +270,12 @@ class GetConnectionStateWidgets extends StatelessWidget { } Widget _getNoFriendConnectedYet(BuildContext context) { - return const Text('No friend connected yet'); + return const Center( + child: Icon( + Icons.power_off_outlined, + size: 50, + color: Colors.grey, + )); } } @@ -557,6 +568,8 @@ connectionStatusWidgets( getPhoneMicRecordingButton( VoidCallback recordingToggled, RecordingState state) { + print('abcd $recordingToggled'); + print('abcd $state'); if (SharedPreferencesUtil().deviceId.isNotEmpty) { return const SizedBox.shrink(); } diff --git a/apps/AppWithWearable/lib/pages/home/device.dart b/apps/AppWithWearable/lib/pages/home/device.dart index 01d6c1bc6..b418898d2 100644 --- a/apps/AppWithWearable/lib/pages/home/device.dart +++ b/apps/AppWithWearable/lib/pages/home/device.dart @@ -5,7 +5,6 @@ import 'package:friend_private/backend/schema/bt_device.dart'; import 'package:friend_private/pages/home/backgrund_scafold.dart'; import 'package:friend_private/utils/ble/connect.dart'; import 'package:friend_private/widgets/device_widget.dart'; -import 'package:gradient_borders/box_borders/gradient_box_border.dart'; // Update with the actual path to your CustomScaffold file class ConnectedDevice extends StatefulWidget { @@ -31,7 +30,7 @@ class _DeviceInfo { static Future<_DeviceInfo> getDeviceInfo(BTDeviceStruct? device) async { var modelNumber = 'AVM'; var firmwareRevision = '1.0.2'; - var hardwareRevision = 'Seeed Xiao BLE Sense'; + var hardwareRevision = 'Seed Xiao BLE Sense'; var manufacturerName = 'Craftech 360'; if (device == null) { @@ -183,15 +182,17 @@ class _ConnectedDeviceState extends State { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), decoration: BoxDecoration( - border: const GradientBoxBorder( - gradient: LinearGradient(colors: [ - Color.fromARGB(127, 208, 208, 208), - Color.fromARGB(127, 188, 99, 121), - Color.fromARGB(127, 86, 101, 182), - Color.fromARGB(127, 126, 190, 236) - ]), - width: 2, - ), + color: const Color.fromARGB(83, 158, 158, 158), + border: Border.all(color: Colors.grey), + // border: const GradientBoxBorder( + // gradient: LinearGradient(colors: [ + // Color.fromARGB(127, 208, 208, 208), + // Color.fromARGB(127, 188, 99, 121), + // Color.fromARGB(127, 86, 101, 182), + // Color.fromARGB(127, 126, 190, 236) + // ]), + // width: 2, + // ), borderRadius: BorderRadius.circular(12), ), child: TextButton( diff --git a/apps/AppWithWearable/lib/pages/home/home_page_wrapper.dart b/apps/AppWithWearable/lib/pages/home/home_page_wrapper.dart new file mode 100644 index 000000000..a2c08ac9f --- /dev/null +++ b/apps/AppWithWearable/lib/pages/home/home_page_wrapper.dart @@ -0,0 +1,520 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:flutter_foreground_task/flutter_foreground_task.dart'; +import 'package:friend_private/backend/api_requests/api/server.dart'; +import 'package:friend_private/backend/api_requests/cloud_storage.dart'; +import 'package:friend_private/backend/database/memory.dart'; +import 'package:friend_private/backend/database/memory_provider.dart'; +import 'package:friend_private/backend/database/message.dart'; +import 'package:friend_private/backend/database/message_provider.dart'; +import 'package:friend_private/backend/mixpanel.dart'; +import 'package:friend_private/backend/preferences.dart'; +import 'package:friend_private/backend/schema/bt_device.dart'; +import 'package:friend_private/backend/schema/plugin.dart'; +import 'package:friend_private/features/chat/presentation/pages/chat_page.dart'; +import 'package:friend_private/pages/capture/connect.dart'; +import 'package:friend_private/pages/capture/page.dart'; +import 'package:friend_private/pages/home/backgrund_scafold.dart'; +import 'package:friend_private/pages/home/device.dart'; +import 'package:friend_private/pages/settings/page.dart'; +import 'package:friend_private/scripts.dart'; +import 'package:friend_private/utils/audio/foreground.dart'; +import 'package:friend_private/utils/ble/communication.dart'; +import 'package:friend_private/utils/ble/connected.dart'; +import 'package:friend_private/utils/ble/scan.dart'; +import 'package:friend_private/utils/other/notifications.dart'; +import 'package:friend_private/utils/other/temp.dart'; +import 'package:friend_private/widgets/scanning_ui.dart'; +import 'package:friend_private/widgets/upgrade_alert.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:upgrader/upgrader.dart'; + +class HomePageWrapperTest extends StatefulWidget { + final dynamic btDevice; + + const HomePageWrapperTest({super.key, this.btDevice}); + + @override + State createState() => _HomePageWrapperState(); +} + +class _HomePageWrapperState extends State + with WidgetsBindingObserver { + ForegroundUtil foregroundUtil = ForegroundUtil(); + List screens = [Container(), const SizedBox(), const SizedBox()]; + List memories = []; + List messages = []; + + FocusNode chatTextFieldFocusNode = FocusNode(canRequestFocus: true); + FocusNode memoriesTextFieldFocusNode = FocusNode(canRequestFocus: true); + + GlobalKey capturePageKey = GlobalKey(); + StreamSubscription? _connectionStateListener; + StreamSubscription>? _bleBatteryLevelListener; + + int batteryLevel = -1; + BTDeviceStruct? _device; + + List plugins = []; + final _upgrader = MyUpgrader(debugLogging: false, debugDisplayOnce: false); + + int _selectedIndex = 0; + + _initiateMemories() async { + memories = MemoryProvider() + .getMemoriesOrdered(includeDiscarded: true) + .reversed + .toList(); + setState(() {}); + } + + _migrationScripts() async { + scriptMemoryVectorsExecuted(); + // await migrateMemoriesToObjectBox(); + _initiateMemories(); + } + + _refreshMessages() async { + messages = MessageProvider().getMessages(); + setState(() {}); + } + + Future _initiatePlugins() async { + plugins = SharedPreferencesUtil().pluginsList; + plugins = await retrievePlugins(); + _edgeCasePluginNotAvailable(); + setState(() {}); + } + + _edgeCasePluginNotAvailable() { + var selectedChatPlugin = SharedPreferencesUtil().selectedChatPluginId; + var plugin = plugins.firstWhereOrNull((p) => selectedChatPlugin == p.id); + if (selectedChatPlugin != 'no_selected' && + (plugin == null || !plugin.worksWithChat())) { + SharedPreferencesUtil().selectedChatPluginId = 'no_selected'; + } + } + + _setupHasSpeakerProfile() async { + SharedPreferencesUtil().hasSpeakerProfile = + await userHasSpeakerProfile(SharedPreferencesUtil().uid); + debugPrint( + '_setupHasSpeakerProfile: ${SharedPreferencesUtil().hasSpeakerProfile}'); + MixpanelManager().setUserProperty( + 'Speaker Profile', SharedPreferencesUtil().hasSpeakerProfile); + setState(() {}); + } + + _onConnected(BTDeviceStruct? connectedDevice, + {bool initiateConnectionListener = true}) { + debugPrint('_onConnected: $connectedDevice'); + if (connectedDevice == null) return; + clearNotification(1); + _device = connectedDevice; + if (initiateConnectionListener) _initiateConnectionListener(); + _initiateBleBatteryListener(); + capturePageKey.currentState + ?.resetState(restartBytesProcessing: true, btDevice: connectedDevice); + MixpanelManager().deviceConnected(); + SharedPreferencesUtil().deviceId = _device!.id; + SharedPreferencesUtil().deviceName = _device!.name; + _startForeground(); + setState(() {}); + } + + _initiateConnectionListener() async { + if (_connectionStateListener != null) return; + _connectionStateListener = getConnectionStateListener( + deviceId: _device!.id, + onDisconnected: () { + debugPrint('onDisconnected'); + capturePageKey.currentState + ?.resetState(restartBytesProcessing: false); + setState(() => _device = null); + InstabugLog.logInfo('AVM Device Disconnected'); + if (SharedPreferencesUtil().reconnectNotificationIsChecked) { + createNotification( + title: 'AVM Device Disconnected', + body: 'Please reconnect to continue using your AVM.', + ); + } + MixpanelManager().deviceDisconnected(); + foregroundUtil.stopForegroundTask(); + }, + onConnected: ((d) => + _onConnected(d, initiateConnectionListener: false))); + } + + _initiateBleBatteryListener() async { + _bleBatteryLevelListener?.cancel(); + _bleBatteryLevelListener = await getBleBatteryLevelListener( + _device!.id, + onBatteryLevelChange: (int value) { + setState(() { + batteryLevel = value; + }); + }, + ); + } + + _startForeground() async { + if (!Platform.isAndroid) return; + await foregroundUtil.initForegroundTask(); + var result = await foregroundUtil.startForegroundTask(); + debugPrint('_startForeground: $result'); + } + + @override + void initState() { + super.initState(); + + SharedPreferencesUtil().pageToShowFromNotification = 1; + SharedPreferencesUtil().onboardingCompleted = true; + + WidgetsBinding.instance.addObserver(this); + WidgetsBinding.instance.addPostFrameCallback((_) async { + requestNotificationPermissions(); + foregroundUtil.requestPermissionForAndroid(); + }); + + _refreshMessages(); + _initiateMemories(); + _initiatePlugins(); + _setupHasSpeakerProfile(); + _migrationScripts(); + authenticateGCP(); + + if (SharedPreferencesUtil().deviceId.isNotEmpty) { + scanAndConnectDevice().then(_onConnected); + } + + createNotification( + title: 'Don\'t forget to wear AVM today', + body: 'Wear your AVM and capture your memories today.', + notificationId: 4, + isMorningNotification: true, + ); + + createNotification( + title: 'Here is your action plan for tomorrow', + body: 'Check out your daily summary to see what you should do tomorrow.', + notificationId: 5, + isDailySummaryNotification: true, + payload: {'path': '/chat'}, + ); + } + + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + + @override + Widget build(BuildContext context) { + // The different screens for the bottom navigation + List screens = [ + CapturePage( + key: capturePageKey, + device: _device, + refreshMemories: _initiateMemories, + refreshMessages: _refreshMessages, + ), + ChatPageTest( + textFieldFocusNode: chatTextFieldFocusNode, + ), + const SettingsPage(), + ]; + + return WithForegroundTask( + child: MyUpgradeAlert( + upgrader: _upgrader, + dialogStyle: Platform.isIOS + ? UpgradeDialogStyle.cupertino + : UpgradeDialogStyle.material, + child: CustomScaffold( + backgroundColor: Theme.of(context).colorScheme.primary, + body: GestureDetector( + onTap: () { + FocusScope.of(context).unfocus(); + chatTextFieldFocusNode.unfocus(); + memoriesTextFieldFocusNode.unfocus(); + }, + child: Stack( + children: [ + Center( + // Display the selected screen based on the selectedIndex + child: screens[_selectedIndex], + ), + ], + ), + ), + appBar: AppBar( + automaticallyImplyLeading: false, + backgroundColor: Theme.of(context).colorScheme.surface, + leading: TextButton( + onPressed: () async { + // if (SharedPreferencesUtil().deviceId.isEmpty) { + // routeToPage(context, const ConnectDevicePage()); + // MixpanelManager().connectFriendClicked(); + // } else { + // await routeToPage(context, + // const ConnectedDevice(device: null, batteryLevel: 0)); + // } + // setState(() {}); + }, + // style: TextButton.styleFrom( + // padding: EdgeInsets.zero, + // backgroundColor: Colors.transparent, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10), + // side: const BorderSide(color: Colors.white, width: 1), + // ), + // ), + child: Image.asset( + 'assets/images/herologo.png', + width: 60, + height: 40, + ), + ), + //*-- Chat Plugin --*// + // title: _selectedIndex == 1 + // ? DropdownButton( + // menuMaxHeight: 350, + // value: SharedPreferencesUtil().selectedChatPluginId, + // onChanged: (s) async { + // if ((s == 'no_selected' && + // SharedPreferencesUtil().pluginsEnabled.isEmpty) || + // s == 'enable') { + // await routeToPage( + // context, const PluginsPage(filterChatOnly: true)); + // setState(() {}); + // return; + // } + // print( + // 'Selected: $s prefs: ${SharedPreferencesUtil().selectedChatPluginId}'); + // if (s == null || + // s == SharedPreferencesUtil().selectedChatPluginId) { + // return; + // } + + // SharedPreferencesUtil().selectedChatPluginId = s; + // plugins.firstWhereOrNull((p) => p.id == s); + // // chatPageKey.currentState + // // ?.sendInitialPluginMessage(plugin); + // setState(() {}); + // }, + // icon: Container(), + // alignment: Alignment.center, + // dropdownColor: Colors.black, + // style: const TextStyle(color: Colors.white, fontSize: 16), + // underline: Container(height: 0, color: Colors.transparent), + // isExpanded: false, + // itemHeight: 48, + // padding: EdgeInsets.zero, + // items: _getPluginsDropdownItems(context), + // ) + // : const SizedBox.shrink(), + actions: [ + //* AVM Battery indecator + _device != null && batteryLevel != -1 + ? GestureDetector( + onTap: _device == null + ? null + : () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (c) => ConnectedDevice( + device: _device!, + batteryLevel: batteryLevel, + ), + ), + ); + MixpanelManager().batteryIndicatorClicked(); + }, + child: Container( + margin: const EdgeInsets.only( + right: 10, top: 15, bottom: 15), + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 0), + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: const Color.fromARGB(106, 158, 158, 158), + width: 1, + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.bolt, + color: batteryLevel > 75 + ? const Color.fromARGB(255, 0, 255, 8) + : batteryLevel > 20 + ? Colors.yellow.shade700 + : Colors.red, + size: 12, + ), + // Container( + // width: 10, + // height: 10, + // decoration: BoxDecoration( + // color: batteryLevel > 75 + // ? const Color.fromARGB(255, 0, 255, 8) + // : batteryLevel > 20 + // ? Colors.yellow.shade700 + // : Colors.red, + // shape: BoxShape.circle, + // ), + // ), + // const SizedBox(width: 8.0), + Text( + '${batteryLevel.toString()}%', + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w300, + ), + ), + ], + ), + ), + ) + : Padding( + padding: const EdgeInsets.only(right: 10), + child: GestureDetector( + onTap: () async { + if (SharedPreferencesUtil().deviceId.isEmpty) { + routeToPage(context, const ConnectDevicePage()); + MixpanelManager().connectFriendClicked(); + } else { + await routeToPage( + context, + const ConnectedDevice( + device: null, batteryLevel: 0)); + } + setState(() {}); + }, + child: const ScanningUI()), + ) + ], + centerTitle: true, + elevation: 0, + ), + // Add the BottomNavigationBar here + bottomNavigationBar: BottomNavigationBar( + items: const [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Home', + ), + BottomNavigationBarItem( + icon: Icon(Icons.chat), + label: 'Chat', + ), + BottomNavigationBarItem( + icon: Icon(Icons.settings), + label: 'Settings', + ), + ], + currentIndex: _selectedIndex, + selectedItemColor: Colors.white, + unselectedItemColor: Colors.grey, + onTap: _onItemTapped, + backgroundColor: Colors.black, + ), + ), + ), + ); + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + _connectionStateListener?.cancel(); + _bleBatteryLevelListener?.cancel(); + super.dispose(); + } + + _getPluginsDropdownItems(BuildContext context) { + var items = [ + DropdownMenuItem( + value: 'no_selected', + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Icon(size: 20, Icons.chat, color: Colors.white), + const SizedBox(width: 10), + Text( + SharedPreferencesUtil().pluginsEnabled.isEmpty + ? 'Enable Plugins ' + : 'Select a plugin', + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontSize: 16), + ) + ], + ), + ) + ] + + plugins + .where((p) => + SharedPreferencesUtil().pluginsEnabled.contains(p.id) && + p.worksWithChat()) + .map>((Plugin plugin) { + return DropdownMenuItem( + value: plugin.id, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + CircleAvatar( + backgroundColor: Colors.white, + maxRadius: 12, + backgroundImage: NetworkImage(plugin.getImageUrl()), + ), + const SizedBox(width: 8), + Text( + plugin.name.length > 18 + ? '${plugin.name.substring(0, 18)}...' + : plugin.name + ' ' * (18 - plugin.name.length), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontSize: 16), + ) + ], + ), + ); + }).toList(); + if (SharedPreferencesUtil().pluginsEnabled.isNotEmpty) { + items.add(const DropdownMenuItem( + value: 'enable', + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + backgroundColor: Colors.transparent, + maxRadius: 12, + child: Icon(Icons.star, color: Colors.purpleAccent), + ), + SizedBox(width: 8), + Text('Enable Plugins ', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontSize: 16)) + ], + ), + )); + } + return items; + } +} diff --git a/apps/AppWithWearable/lib/pages/home/page.dart b/apps/AppWithWearable/lib/pages/home/page.dart index 4c82bf201..0cb35bf3b 100644 --- a/apps/AppWithWearable/lib/pages/home/page.dart +++ b/apps/AppWithWearable/lib/pages/home/page.dart @@ -1,3 +1,644 @@ +// // import 'dart:async'; +// // import 'dart:io'; + +// // import 'package:collection/collection.dart'; +// // import 'package:flutter/material.dart'; +// // import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +// // import 'package:flutter_foreground_task/flutter_foreground_task.dart'; +// // import 'package:friend_private/backend/api_requests/api/server.dart'; +// // import 'package:friend_private/backend/api_requests/cloud_storage.dart'; +// // import 'package:friend_private/backend/database/memory.dart'; +// // import 'package:friend_private/backend/database/memory_provider.dart'; +// // import 'package:friend_private/backend/database/message.dart'; +// // import 'package:friend_private/backend/database/message_provider.dart'; +// // import 'package:friend_private/backend/growthbook.dart'; +// // import 'package:friend_private/backend/mixpanel.dart'; +// // import 'package:friend_private/backend/preferences.dart'; +// // import 'package:friend_private/backend/schema/bt_device.dart'; +// // import 'package:friend_private/backend/schema/plugin.dart'; +// // import 'package:friend_private/main.dart'; +// // import 'package:friend_private/pages/capture/connect.dart'; +// // import 'package:friend_private/pages/capture/page.dart'; +// // import 'package:friend_private/pages/chat/page.dart'; +// // import 'package:friend_private/pages/home/device.dart'; +// // import 'package:friend_private/pages/memories/page.dart'; +// // import 'package:friend_private/pages/plugins/page.dart'; +// // import 'package:friend_private/pages/settings/page.dart'; +// // import 'package:friend_private/scripts.dart'; +// // import 'package:friend_private/utils/audio/foreground.dart'; +// // import 'package:friend_private/utils/ble/communication.dart'; +// // import 'package:friend_private/utils/ble/connected.dart'; +// // import 'package:friend_private/utils/ble/scan.dart'; +// // import 'package:friend_private/utils/features/backups.dart'; +// // import 'package:friend_private/utils/other/notifications.dart'; +// // import 'package:friend_private/utils/other/temp.dart'; +// // import 'package:friend_private/widgets/upgrade_alert.dart'; +// // import 'package:gradient_borders/gradient_borders.dart'; +// // import 'package:instabug_flutter/instabug_flutter.dart'; +// // import 'package:upgrader/upgrader.dart'; + +// // class HomePageWrapper extends StatefulWidget { +// // final dynamic btDevice; + +// // const HomePageWrapper({super.key, this.btDevice}); + +// // @override +// // State createState() => _HomePageWrapperState(); +// // } + +// // class _HomePageWrapperState extends State +// // with WidgetsBindingObserver, TickerProviderStateMixin { +// // ForegroundUtil foregroundUtil = ForegroundUtil(); +// // TabController? _controller; +// // List screens = [Container(), const SizedBox(), const SizedBox()]; + +// // List memories = []; +// // List messages = []; + +// // FocusNode chatTextFieldFocusNode = FocusNode(canRequestFocus: true); +// // FocusNode memoriesTextFieldFocusNode = FocusNode(canRequestFocus: true); + +// // GlobalKey capturePageKey = GlobalKey(); +// // GlobalKey chatPageKey = GlobalKey(); +// // StreamSubscription? _connectionStateListener; +// // StreamSubscription>? _bleBatteryLevelListener; + +// // int batteryLevel = -1; +// // BTDeviceStruct? _device; + +// // List plugins = []; +// // final _upgrader = MyUpgrader(debugLogging: false, debugDisplayOnce: false); + +// // _initiateMemories() async { +// // memories = MemoryProvider() +// // .getMemoriesOrdered(includeDiscarded: true) +// // .reversed +// // .toList(); +// // setState(() {}); +// // } + +// // _refreshMessages() async { +// // messages = MessageProvider().getMessages(); +// // setState(() {}); +// // } + +// // _setupHasSpeakerProfile() async { +// // SharedPreferencesUtil().hasSpeakerProfile = +// // await userHasSpeakerProfile(SharedPreferencesUtil().uid); +// // print( +// // '_setupHasSpeakerProfile: ${SharedPreferencesUtil().hasSpeakerProfile}'); +// // MixpanelManager().setUserProperty( +// // 'Speaker Profile', SharedPreferencesUtil().hasSpeakerProfile); +// // setState(() {}); +// // } + +// // _edgeCasePluginNotAvailable() { +// // var selectedChatPlugin = SharedPreferencesUtil().selectedChatPluginId; +// // var plugin = plugins.firstWhereOrNull((p) => selectedChatPlugin == p.id); +// // if (selectedChatPlugin != 'no_selected' && +// // (plugin == null || !plugin.worksWithChat())) { +// // SharedPreferencesUtil().selectedChatPluginId = 'no_selected'; +// // } +// // } + +// // Future _initiatePlugins() async { +// // plugins = SharedPreferencesUtil().pluginsList; +// // plugins = await retrievePlugins(); +// // _edgeCasePluginNotAvailable(); +// // setState(() {}); +// // } + +// // @override +// // void didChangeAppLifecycleState(AppLifecycleState state) { +// // super.didChangeAppLifecycleState(state); +// // String event = ''; +// // if (state == AppLifecycleState.paused) { +// // event = 'App is paused'; +// // } else if (state == AppLifecycleState.resumed) { +// // event = 'App is resumed'; +// // } else if (state == AppLifecycleState.hidden) { +// // event = 'App is hidden'; +// // } else if (state == AppLifecycleState.detached) { +// // event = 'App is detached'; +// // } +// // debugPrint(event); +// // InstabugLog.logInfo(event); +// // } + +// // _migrationScripts() async { +// // scriptMemoryVectorsExecuted(); +// // // await migrateMemoriesToObjectBox(); +// // _initiateMemories(); +// // } + +// // ///Screens with respect to subpage +// // final Map screensWithRespectToPath = { +// // '/settings': const SettingsPage(), +// // }; + +// // @override +// // void initState() { +// // _controller = TabController( +// // length: 3, +// // vsync: this, +// // initialIndex: SharedPreferencesUtil().pageToShowFromNotification, +// // ); +// // SharedPreferencesUtil().pageToShowFromNotification = 1; +// // SharedPreferencesUtil().onboardingCompleted = true; +// // print('Selected: ${SharedPreferencesUtil().selectedChatPluginId}'); + +// // WidgetsBinding.instance.addObserver(this); +// // WidgetsBinding.instance.addPostFrameCallback((_) async { +// // requestNotificationPermissions(); +// // foregroundUtil.requestPermissionForAndroid(); +// // }); +// // _refreshMessages(); +// // executeBackupWithUid(); +// // _initiateMemories(); +// // _initiatePlugins(); +// // _setupHasSpeakerProfile(); +// // _migrationScripts(); +// // authenticateGCP(); +// // if (SharedPreferencesUtil().deviceId.isNotEmpty) { +// // scanAndConnectDevice().then(_onConnected); +// // } + +// // createNotification( +// // title: 'Don\'t forget to wear Friend today', +// // body: 'Wear your friend and capture your memories today.', +// // notificationId: 4, +// // isMorningNotification: true, +// // ); +// // createNotification( +// // title: 'Here is your action plan for tomorrow', +// // body: 'Check out your daily summary to see what you should do tomorrow.', +// // notificationId: 5, +// // isDailySummaryNotification: true, +// // payload: {'path': '/chat'}, +// // ); +// // if (SharedPreferencesUtil().subPageToShowFromNotification != '') { +// // final subPageRoute = +// // SharedPreferencesUtil().subPageToShowFromNotification; +// // WidgetsBinding.instance.addPostFrameCallback((_) async { +// // MyApp.navigatorKey.currentState?.push( +// // MaterialPageRoute( +// // builder: (context) => +// // screensWithRespectToPath[subPageRoute] as Widget, +// // ), +// // ); +// // }); +// // SharedPreferencesUtil().subPageToShowFromNotification = ''; +// // } +// // super.initState(); +// // } + +// // _initiateConnectionListener() async { +// // if (_connectionStateListener != null) return; +// // // TODO: when disconnected manually need to remove this connection state listener +// // _connectionStateListener = getConnectionStateListener( +// // deviceId: _device!.id, +// // onDisconnected: () { +// // debugPrint('onDisconnected'); +// // capturePageKey.currentState +// // ?.resetState(restartBytesProcessing: false); +// // setState(() => _device = null); +// // InstabugLog.logInfo('Friend Device Disconnected'); +// // if (SharedPreferencesUtil().reconnectNotificationIsChecked) { +// // createNotification( +// // title: 'Friend Device Disconnected', +// // body: 'Please reconnect to continue using your Friend.', +// // ); +// // } +// // MixpanelManager().deviceDisconnected(); +// // foregroundUtil.stopForegroundTask(); +// // }, +// // onConnected: ((d) => +// // _onConnected(d, initiateConnectionListener: false))); +// // } + +// // _startForeground() async { +// // if (!Platform.isAndroid) return; +// // await foregroundUtil.initForegroundTask(); +// // var result = await foregroundUtil.startForegroundTask(); +// // debugPrint('_startForeground: $result'); +// // } + +// // _onConnected(BTDeviceStruct? connectedDevice, +// // {bool initiateConnectionListener = true}) { +// // debugPrint('_onConnected: $connectedDevice'); +// // if (connectedDevice == null) return; +// // clearNotification(1); +// // _device = connectedDevice; +// // if (initiateConnectionListener) _initiateConnectionListener(); +// // _initiateBleBatteryListener(); +// // capturePageKey.currentState +// // ?.resetState(restartBytesProcessing: true, btDevice: connectedDevice); +// // MixpanelManager().deviceConnected(); +// // SharedPreferencesUtil().deviceId = _device!.id; +// // SharedPreferencesUtil().deviceName = _device!.name; +// // _startForeground(); +// // setState(() {}); +// // } + +// // _initiateBleBatteryListener() async { +// // _bleBatteryLevelListener?.cancel(); +// // _bleBatteryLevelListener = await getBleBatteryLevelListener( +// // _device!.id, +// // onBatteryLevelChange: (int value) { +// // setState(() { +// // batteryLevel = value; +// // }); +// // }, +// // ); +// // } + +// // _tabChange(int index) { +// // MixpanelManager() +// // .bottomNavigationTabClicked(['Memories', 'Device', 'Chat'][index]); +// // FocusScope.of(context).unfocus(); +// // setState(() { +// // _controller!.index = index; +// // }); +// // } + +// // @override +// // Widget build(BuildContext context) { +// // return WithForegroundTask( +// // child: MyUpgradeAlert( +// // upgrader: _upgrader, +// // dialogStyle: Platform.isIOS +// // ? UpgradeDialogStyle.cupertino +// // : UpgradeDialogStyle.material, +// // child: Scaffold( +// // backgroundColor: Theme.of(context).colorScheme.primary, +// // body: GestureDetector( +// // onTap: () { +// // FocusScope.of(context).unfocus(); +// // chatTextFieldFocusNode.unfocus(); +// // memoriesTextFieldFocusNode.unfocus(); +// // }, +// // child: Stack( +// // children: [ +// // Center( +// // child: TabBarView( +// // controller: _controller, +// // physics: const NeverScrollableScrollPhysics(), +// // children: [ +// // MemoriesPage( +// // memories: memories, +// // refreshMemories: _initiateMemories, +// // textFieldFocusNode: memoriesTextFieldFocusNode, +// // ), +// // CapturePage( +// // key: capturePageKey, +// // device: _device, +// // refreshMemories: _initiateMemories, +// // refreshMessages: _refreshMessages, +// // ), +// // ChatPage( +// // key: chatPageKey, +// // textFieldFocusNode: chatTextFieldFocusNode, +// // messages: messages, +// // refreshMessages: _refreshMessages, +// // ), +// // ], +// // ), +// // ), +// // if (chatTextFieldFocusNode.hasFocus || +// // memoriesTextFieldFocusNode.hasFocus) +// // const SizedBox.shrink() +// // else +// // Align( +// // alignment: Alignment.bottomCenter, +// // child: Container( +// // margin: const EdgeInsets.fromLTRB(16, 16, 16, 40), +// // decoration: const BoxDecoration( +// // color: Colors.black, +// // borderRadius: BorderRadius.all(Radius.circular(16)), +// // border: GradientBoxBorder( +// // gradient: LinearGradient(colors: [ +// // Color.fromARGB(127, 208, 208, 208), +// // Color.fromARGB(127, 188, 99, 121), +// // Color.fromARGB(127, 86, 101, 182), +// // Color.fromARGB(127, 126, 190, 236) +// // ]), +// // width: 2, +// // ), +// // shape: BoxShape.rectangle, +// // ), +// // child: Row( +// // mainAxisAlignment: MainAxisAlignment.spaceBetween, +// // children: [ +// // Expanded( +// // child: MaterialButton( +// // onPressed: () => _tabChange(0), +// // child: Padding( +// // padding: +// // const EdgeInsets.only(top: 20, bottom: 20), +// // child: Text('Memories', +// // maxLines: 1, +// // overflow: TextOverflow.ellipsis, +// // style: TextStyle( +// // color: _controller!.index == 0 +// // ? Colors.white +// // : Colors.grey, +// // fontSize: 16)), +// // ), +// // ), +// // ), +// // Expanded( +// // child: MaterialButton( +// // onPressed: () => _tabChange(1), +// // child: Padding( +// // padding: const EdgeInsets.only( +// // top: 20, +// // bottom: 20, +// // ), +// // child: Text('Capture', +// // maxLines: 1, +// // overflow: TextOverflow.ellipsis, +// // style: TextStyle( +// // color: _controller!.index == 1 +// // ? Colors.white +// // : Colors.grey, +// // fontSize: 16)), +// // ), +// // ), +// // ), +// // Expanded( +// // child: MaterialButton( +// // onPressed: () => _tabChange(2), +// // child: Padding( +// // padding: +// // const EdgeInsets.only(top: 20, bottom: 20), +// // child: Text('Chat', +// // maxLines: 1, +// // overflow: TextOverflow.ellipsis, +// // style: TextStyle( +// // color: _controller!.index == 2 +// // ? Colors.white +// // : Colors.grey, +// // fontSize: 16)), +// // ), +// // ), +// // ), +// // ], +// // ), +// // ), +// // ) +// // ], +// // ), +// // ), +// // appBar: AppBar( +// // automaticallyImplyLeading: false, +// // backgroundColor: Theme.of(context).colorScheme.surface, +// // title: Row( +// // mainAxisAlignment: MainAxisAlignment.spaceBetween, +// // crossAxisAlignment: CrossAxisAlignment.center, +// // children: [ +// // _device != null && batteryLevel != -1 +// // ? GestureDetector( +// // onTap: _device == null +// // ? null +// // : () { +// // Navigator.of(context).push(MaterialPageRoute( +// // builder: (c) => ConnectedDevice( +// // device: _device!, +// // batteryLevel: batteryLevel, +// // ))); +// // MixpanelManager().batteryIndicatorClicked(); +// // }, +// // child: Container( +// // padding: const EdgeInsets.symmetric( +// // horizontal: 14, vertical: 10), +// // decoration: BoxDecoration( +// // color: Colors.transparent, +// // borderRadius: BorderRadius.circular(10), +// // border: Border.all( +// // color: Colors.grey, +// // width: 1, +// // ), +// // ), +// // child: Row( +// // mainAxisSize: MainAxisSize.min, +// // children: [ +// // Container( +// // width: 10, +// // height: 10, +// // decoration: BoxDecoration( +// // color: batteryLevel > 75 +// // ? const Color.fromARGB(255, 0, 255, 8) +// // : batteryLevel > 20 +// // ? Colors.yellow.shade700 +// // : Colors.red, +// // shape: BoxShape.circle, +// // ), +// // ), +// // const SizedBox(width: 8.0), +// // Text( +// // '${batteryLevel.toString()}%', +// // style: const TextStyle( +// // color: Colors.white, +// // fontSize: 12, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // ], +// // )), +// // ) +// // : TextButton( +// // onPressed: () async { +// // if (SharedPreferencesUtil().deviceId.isEmpty) { +// // routeToPage(context, const ConnectDevicePage()); +// // MixpanelManager().connectFriendClicked(); +// // } else { +// // await routeToPage( +// // context, +// // const ConnectedDevice( +// // device: null, batteryLevel: 0)); +// // } +// // setState(() {}); +// // }, +// // style: TextButton.styleFrom( +// // padding: EdgeInsets.zero, +// // backgroundColor: Colors.transparent, +// // shape: RoundedRectangleBorder( +// // borderRadius: BorderRadius.circular(10), +// // side: const BorderSide(color: Colors.white, width: 1), +// // ), +// // ), +// // child: Image.asset('assets/images/logo_transparent.png', +// // width: 25, height: 25), +// // ), +// // _controller!.index == 2 +// // ? Padding( +// // padding: const EdgeInsets.only(left: 0), +// // child: Container( +// // // decoration: BoxDecoration( +// // // border: Border.all(color: Colors.grey), +// // // borderRadius: BorderRadius.circular(30), +// // // ), +// // padding: const EdgeInsets.symmetric(horizontal: 16), +// // child: DropdownButton( +// // menuMaxHeight: 350, +// // value: SharedPreferencesUtil().selectedChatPluginId, +// // onChanged: (s) async { +// // if ((s == 'no_selected' && +// // SharedPreferencesUtil() +// // .pluginsEnabled +// // .isEmpty) || +// // s == 'enable') { +// // await routeToPage(context, +// // const PluginsPage(filterChatOnly: true)); +// // setState(() {}); +// // return; +// // } +// // print( +// // 'Selected: $s prefs: ${SharedPreferencesUtil().selectedChatPluginId}'); +// // if (s == null || +// // s == +// // SharedPreferencesUtil() +// // .selectedChatPluginId) return; + +// // SharedPreferencesUtil().selectedChatPluginId = s; +// // var plugin = +// // plugins.firstWhereOrNull((p) => p.id == s); +// // chatPageKey.currentState +// // ?.sendInitialPluginMessage(plugin); +// // setState(() {}); +// // }, +// // icon: Container(), +// // alignment: Alignment.center, +// // dropdownColor: Colors.black, +// // style: const TextStyle( +// // color: Colors.white, fontSize: 16), +// // underline: +// // Container(height: 0, color: Colors.transparent), +// // isExpanded: false, +// // itemHeight: 48, +// // padding: EdgeInsets.zero, +// // items: _getPluginsDropdownItems(context), +// // ), +// // ), +// // ) +// // : const SizedBox(width: 16), +// // IconButton( +// // icon: const Icon( +// // Icons.settings, +// // color: Colors.white, +// // size: 30, +// // ), +// // onPressed: () async { +// // MixpanelManager().settingsOpened(); +// // String language = SharedPreferencesUtil().recordingsLanguage; +// // bool hasSpeech = SharedPreferencesUtil().hasSpeakerProfile; +// // await routeToPage(context, const SettingsPage()); +// // // TODO: this fails like 10 times, connects reconnects, until it finally works. +// // if (GrowthbookUtil().hasStreamingTranscriptFeatureOn() && +// // (language != SharedPreferencesUtil().recordingsLanguage || +// // hasSpeech != +// // SharedPreferencesUtil().hasSpeakerProfile)) { +// // capturePageKey.currentState?.restartWebSocket(); +// // } +// // setState(() {}); +// // }, +// // ) +// // ], +// // ), +// // elevation: 0, +// // centerTitle: true, +// // ), +// // ), +// // )); +// // } + +// // _getPluginsDropdownItems(BuildContext context) { +// // var items = [ +// // DropdownMenuItem( +// // value: 'no_selected', +// // child: Row( +// // crossAxisAlignment: CrossAxisAlignment.center, +// // children: [ +// // const Icon(size: 20, Icons.chat, color: Colors.white), +// // const SizedBox(width: 10), +// // Text( +// // SharedPreferencesUtil().pluginsEnabled.isEmpty +// // ? 'Enable Plugins ' +// // : 'Select a plugin', +// // style: const TextStyle( +// // color: Colors.white, +// // fontWeight: FontWeight.w500, +// // fontSize: 16), +// // ) +// // ], +// // ), +// // ) +// // ] + +// // plugins +// // .where((p) => +// // SharedPreferencesUtil().pluginsEnabled.contains(p.id) && +// // p.worksWithChat()) +// // .map>((Plugin plugin) { +// // return DropdownMenuItem( +// // value: plugin.id, +// // child: Row( +// // crossAxisAlignment: CrossAxisAlignment.end, +// // mainAxisAlignment: MainAxisAlignment.start, +// // children: [ +// // CircleAvatar( +// // backgroundColor: Colors.white, +// // maxRadius: 12, +// // backgroundImage: NetworkImage(plugin.getImageUrl()), +// // ), +// // const SizedBox(width: 8), +// // Text( +// // plugin.name.length > 18 +// // ? '${plugin.name.substring(0, 18)}...' +// // : plugin.name + ' ' * (18 - plugin.name.length), +// // style: const TextStyle( +// // color: Colors.white, +// // fontWeight: FontWeight.w500, +// // fontSize: 16), +// // ) +// // ], +// // ), +// // ); +// // }).toList(); +// // if (SharedPreferencesUtil().pluginsEnabled.isNotEmpty) { +// // items.add(const DropdownMenuItem( +// // value: 'enable', +// // child: Row( +// // crossAxisAlignment: CrossAxisAlignment.center, +// // children: [ +// // CircleAvatar( +// // backgroundColor: Colors.transparent, +// // maxRadius: 12, +// // child: Icon(Icons.star, color: Colors.purpleAccent), +// // ), +// // SizedBox(width: 8), +// // Text('Enable Plugins ', +// // style: TextStyle( +// // color: Colors.white, +// // fontWeight: FontWeight.w500, +// // fontSize: 16)) +// // ], +// // ), +// // )); +// // } +// // return items; +// // } + +// // @override +// // void dispose() { +// // WidgetsBinding.instance.removeObserver(this); +// // _connectionStateListener?.cancel(); +// // _bleBatteryLevelListener?.cancel(); + +// // _controller?.dispose(); +// // super.dispose(); +// // } +// // } + // import 'dart:async'; // import 'dart:io'; @@ -11,17 +652,19 @@ // import 'package:friend_private/backend/database/memory_provider.dart'; // import 'package:friend_private/backend/database/message.dart'; // import 'package:friend_private/backend/database/message_provider.dart'; -// import 'package:friend_private/backend/growthbook.dart'; // import 'package:friend_private/backend/mixpanel.dart'; // import 'package:friend_private/backend/preferences.dart'; // import 'package:friend_private/backend/schema/bt_device.dart'; // import 'package:friend_private/backend/schema/plugin.dart'; +// import 'package:friend_private/features/chat/presentation/pages/chat_page.dart'; // import 'package:friend_private/main.dart'; // import 'package:friend_private/pages/capture/connect.dart'; // import 'package:friend_private/pages/capture/page.dart'; // import 'package:friend_private/pages/chat/page.dart'; +// // import 'package:friend_private/pages/chat/page.dart'; +// // import 'package:friend_private/pages/chat/page.dart'; +// import 'package:friend_private/pages/home/backgrund_scafold.dart'; // import 'package:friend_private/pages/home/device.dart'; -// import 'package:friend_private/pages/memories/page.dart'; // import 'package:friend_private/pages/plugins/page.dart'; // import 'package:friend_private/pages/settings/page.dart'; // import 'package:friend_private/scripts.dart'; @@ -32,8 +675,8 @@ // import 'package:friend_private/utils/features/backups.dart'; // import 'package:friend_private/utils/other/notifications.dart'; // import 'package:friend_private/utils/other/temp.dart'; +// import 'package:friend_private/widgets/scanning_ui.dart'; // import 'package:friend_private/widgets/upgrade_alert.dart'; -// import 'package:gradient_borders/gradient_borders.dart'; // import 'package:instabug_flutter/instabug_flutter.dart'; // import 'package:upgrader/upgrader.dart'; @@ -59,7 +702,7 @@ // FocusNode memoriesTextFieldFocusNode = FocusNode(canRequestFocus: true); // GlobalKey capturePageKey = GlobalKey(); -// GlobalKey chatPageKey = GlobalKey(); +// // GlobalKey chatPageKey = GlobalKey(); // StreamSubscription? _connectionStateListener; // StreamSubscription>? _bleBatteryLevelListener; @@ -85,7 +728,7 @@ // _setupHasSpeakerProfile() async { // SharedPreferencesUtil().hasSpeakerProfile = // await userHasSpeakerProfile(SharedPreferencesUtil().uid); -// print( +// debugPrint( // '_setupHasSpeakerProfile: ${SharedPreferencesUtil().hasSpeakerProfile}'); // MixpanelManager().setUserProperty( // 'Speaker Profile', SharedPreferencesUtil().hasSpeakerProfile); @@ -143,6 +786,7 @@ // vsync: this, // initialIndex: SharedPreferencesUtil().pageToShowFromNotification, // ); + // SharedPreferencesUtil().pageToShowFromNotification = 1; // SharedPreferencesUtil().onboardingCompleted = true; // print('Selected: ${SharedPreferencesUtil().selectedChatPluginId}'); @@ -164,8 +808,8 @@ // } // createNotification( -// title: 'Don\'t forget to wear Friend today', -// body: 'Wear your friend and capture your memories today.', +// title: 'Don\'t forget to wear AVM today', +// body: 'Wear your AVM and capture your memories today.', // notificationId: 4, // isMorningNotification: true, // ); @@ -202,11 +846,11 @@ // capturePageKey.currentState // ?.resetState(restartBytesProcessing: false); // setState(() => _device = null); -// InstabugLog.logInfo('Friend Device Disconnected'); +// InstabugLog.logInfo('AVM Device Disconnected'); // if (SharedPreferencesUtil().reconnectNotificationIsChecked) { // createNotification( -// title: 'Friend Device Disconnected', -// body: 'Please reconnect to continue using your Friend.', +// title: 'AVM Device Disconnected', +// body: 'Please reconnect to continue using your AVM.', // ); // } // MixpanelManager().deviceDisconnected(); @@ -254,7 +898,7 @@ // _tabChange(int index) { // MixpanelManager() -// .bottomNavigationTabClicked(['Memories', 'Device', 'Chat'][index]); +// .bottomNavigationTabClicked(['Device', 'Chat', 'Setting'][index]); // FocusScope.of(context).unfocus(); // setState(() { // _controller!.index = index; @@ -269,7 +913,7 @@ // dialogStyle: Platform.isIOS // ? UpgradeDialogStyle.cupertino // : UpgradeDialogStyle.material, -// child: Scaffold( +// child: CustomScaffold( // backgroundColor: Theme.of(context).colorScheme.primary, // body: GestureDetector( // onTap: () { @@ -282,25 +926,31 @@ // Center( // child: TabBarView( // controller: _controller, -// physics: const NeverScrollableScrollPhysics(), +// // physics: const NeverScrollableScrollPhysics(), // children: [ -// MemoriesPage( -// memories: memories, -// refreshMemories: _initiateMemories, -// textFieldFocusNode: memoriesTextFieldFocusNode, -// ), +// // const MyWidget(), +// // TestPage( +// // refreshMemories: _initiateMemories, +// // textFieldFocusNode: memoriesTextFieldFocusNode, +// // memories: memories, +// // ), + // CapturePage( // key: capturePageKey, // device: _device, // refreshMemories: _initiateMemories, // refreshMessages: _refreshMessages, // ), -// ChatPage( -// key: chatPageKey, +// // ChatPage( +// // key: chatPageKey, +// // textFieldFocusNode: chatTextFieldFocusNode, +// // messages: messages, +// // refreshMessages: _refreshMessages, +// // ), +// ChatPageTest( // textFieldFocusNode: chatTextFieldFocusNode, -// messages: messages, -// refreshMessages: _refreshMessages, // ), +// const SettingsPage(), // ], // ), // ), @@ -312,18 +962,19 @@ // alignment: Alignment.bottomCenter, // child: Container( // margin: const EdgeInsets.fromLTRB(16, 16, 16, 40), -// decoration: const BoxDecoration( +// decoration: BoxDecoration( // color: Colors.black, -// borderRadius: BorderRadius.all(Radius.circular(16)), -// border: GradientBoxBorder( -// gradient: LinearGradient(colors: [ -// Color.fromARGB(127, 208, 208, 208), -// Color.fromARGB(127, 188, 99, 121), -// Color.fromARGB(127, 86, 101, 182), -// Color.fromARGB(127, 126, 190, 236) -// ]), -// width: 2, -// ), +// borderRadius: const BorderRadius.all(Radius.circular(16)), +// border: Border.all(color: Colors.grey), +// // border: GradientBoxBorder( +// // gradient: LinearGradient(colors: [ +// // Color.fromARGB(127, 208, 208, 208), +// // Color.fromARGB(127, 188, 99, 121), +// // Color.fromARGB(127, 86, 101, 182), +// // Color.fromARGB(127, 126, 190, 236) +// // ]), +// // width: 2, +// // ), // shape: BoxShape.rectangle, // ), // child: Row( @@ -333,16 +984,21 @@ // child: MaterialButton( // onPressed: () => _tabChange(0), // child: Padding( -// padding: -// const EdgeInsets.only(top: 20, bottom: 20), -// child: Text('Memories', -// maxLines: 1, -// overflow: TextOverflow.ellipsis, -// style: TextStyle( -// color: _controller!.index == 0 -// ? Colors.white -// : Colors.grey, -// fontSize: 16)), +// padding: const EdgeInsets.only( +// top: 20, +// bottom: 20, +// ), +// child: Text( +// 'Capture', +// maxLines: 1, +// overflow: TextOverflow.ellipsis, +// style: TextStyle( +// color: _controller!.index == 0 +// ? Colors.white +// : Colors.grey, +// fontSize: 16, +// ), +// ), // ), // ), // ), @@ -350,11 +1006,9 @@ // child: MaterialButton( // onPressed: () => _tabChange(1), // child: Padding( -// padding: const EdgeInsets.only( -// top: 20, -// bottom: 20, -// ), -// child: Text('Capture', +// padding: +// const EdgeInsets.only(top: 20, bottom: 20), +// child: Text('Chat', // maxLines: 1, // overflow: TextOverflow.ellipsis, // style: TextStyle( @@ -371,14 +1025,16 @@ // child: Padding( // padding: // const EdgeInsets.only(top: 20, bottom: 20), -// child: Text('Chat', -// maxLines: 1, -// overflow: TextOverflow.ellipsis, -// style: TextStyle( -// color: _controller!.index == 2 -// ? Colors.white -// : Colors.grey, -// fontSize: 16)), +// child: Text( +// 'Setting', +// maxLines: 1, +// overflow: TextOverflow.ellipsis, +// style: TextStyle( +// color: _controller!.index == 2 +// ? Colors.white +// : Colors.grey, +// fontSize: 16), +// ), // ), // ), // ), @@ -396,81 +1052,84 @@ // mainAxisAlignment: MainAxisAlignment.spaceBetween, // crossAxisAlignment: CrossAxisAlignment.center, // children: [ -// _device != null && batteryLevel != -1 -// ? GestureDetector( -// onTap: _device == null -// ? null -// : () { -// Navigator.of(context).push(MaterialPageRoute( -// builder: (c) => ConnectedDevice( -// device: _device!, -// batteryLevel: batteryLevel, -// ))); -// MixpanelManager().batteryIndicatorClicked(); -// }, -// child: Container( -// padding: const EdgeInsets.symmetric( -// horizontal: 14, vertical: 10), -// decoration: BoxDecoration( -// color: Colors.transparent, -// borderRadius: BorderRadius.circular(10), -// border: Border.all( -// color: Colors.grey, -// width: 1, -// ), -// ), -// child: Row( -// mainAxisSize: MainAxisSize.min, -// children: [ -// Container( -// width: 10, -// height: 10, -// decoration: BoxDecoration( -// color: batteryLevel > 75 -// ? const Color.fromARGB(255, 0, 255, 8) -// : batteryLevel > 20 -// ? Colors.yellow.shade700 -// : Colors.red, -// shape: BoxShape.circle, -// ), -// ), -// const SizedBox(width: 8.0), -// Text( -// '${batteryLevel.toString()}%', -// style: const TextStyle( -// color: Colors.white, -// fontSize: 12, -// fontWeight: FontWeight.bold, -// ), -// ), -// ], -// )), -// ) -// : TextButton( -// onPressed: () async { -// if (SharedPreferencesUtil().deviceId.isEmpty) { -// routeToPage(context, const ConnectDevicePage()); -// MixpanelManager().connectFriendClicked(); -// } else { -// await routeToPage( -// context, -// const ConnectedDevice( -// device: null, batteryLevel: 0)); -// } -// setState(() {}); -// }, -// style: TextButton.styleFrom( -// padding: EdgeInsets.zero, -// backgroundColor: Colors.transparent, -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10), -// side: const BorderSide(color: Colors.white, width: 1), -// ), -// ), -// child: Image.asset('assets/images/logo_transparent.png', -// width: 25, height: 25), -// ), -// _controller!.index == 2 +// //* AVM page navigating +// // _device != null && batteryLevel != -1 +// // ? GestureDetector( +// // onTap: _device == null +// // ? null +// // : () { +// // Navigator.of(context).push(MaterialPageRoute( +// // builder: (c) => ConnectedDevice( +// // device: _device!, +// // batteryLevel: batteryLevel, +// // ))); +// // MixpanelManager().batteryIndicatorClicked(); +// // }, +// // child: Container( +// // padding: const EdgeInsets.symmetric( +// // horizontal: 14, vertical: 10), +// // decoration: BoxDecoration( +// // color: Colors.transparent, +// // borderRadius: BorderRadius.circular(10), +// // border: Border.all( +// // color: Colors.grey, +// // width: 1, +// // ), +// // ), +// // child: Row( +// // mainAxisSize: MainAxisSize.min, +// // children: [ +// // Container( +// // width: 10, +// // height: 10, +// // decoration: BoxDecoration( +// // color: batteryLevel > 75 +// // ? const Color.fromARGB(255, 0, 255, 8) +// // : batteryLevel > 20 +// // ? Colors.yellow.shade700 +// // : Colors.red, +// // shape: BoxShape.circle, +// // ), +// // ), +// // const SizedBox(width: 8.0), +// // Text( +// // '${batteryLevel.toString()}%', +// // style: const TextStyle( +// // color: Colors.white, +// // fontSize: 12, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // ], +// // )), +// // ) +// // : +// TextButton( +// onPressed: () async { +// if (SharedPreferencesUtil().deviceId.isEmpty) { +// routeToPage(context, const ConnectDevicePage()); +// MixpanelManager().connectFriendClicked(); +// } else { +// await routeToPage(context, +// const ConnectedDevice(device: null, batteryLevel: 0)); +// } +// setState(() {}); +// }, +// // style: TextButton.styleFrom( +// // padding: EdgeInsets.zero, +// // backgroundColor: Colors.transparent, +// // shape: RoundedRectangleBorder( +// // borderRadius: BorderRadius.circular(10), +// // side: const BorderSide(color: Colors.white, width: 1), +// // ), +// // ), +// child: Image.asset( +// 'assets/images/herologo.png', +// width: 60, +// height: 30, +// ), +// ), +// _controller!.index == 1 // ? Padding( // padding: const EdgeInsets.only(left: 0), // child: Container( @@ -503,8 +1162,8 @@ // SharedPreferencesUtil().selectedChatPluginId = s; // var plugin = // plugins.firstWhereOrNull((p) => p.id == s); -// chatPageKey.currentState -// ?.sendInitialPluginMessage(plugin); +// // chatPageKey.currentState +// // ?.sendInitialPluginMessage(plugin); // setState(() {}); // }, // icon: Container(), @@ -522,27 +1181,90 @@ // ), // ) // : const SizedBox(width: 16), -// IconButton( -// icon: const Icon( -// Icons.settings, -// color: Colors.white, -// size: 30, -// ), -// onPressed: () async { -// MixpanelManager().settingsOpened(); -// String language = SharedPreferencesUtil().recordingsLanguage; -// bool hasSpeech = SharedPreferencesUtil().hasSpeakerProfile; -// await routeToPage(context, const SettingsPage()); -// // TODO: this fails like 10 times, connects reconnects, until it finally works. -// if (GrowthbookUtil().hasStreamingTranscriptFeatureOn() && -// (language != SharedPreferencesUtil().recordingsLanguage || -// hasSpeech != -// SharedPreferencesUtil().hasSpeakerProfile)) { -// capturePageKey.currentState?.restartWebSocket(); -// } -// setState(() {}); -// }, -// ) +// //* AVM Battery indecator +// _device != null && batteryLevel != -1 +// ? GestureDetector( +// onTap: _device == null +// ? null +// : () { +// Navigator.of(context).push(MaterialPageRoute( +// builder: (c) => ConnectedDevice( +// device: _device!, +// batteryLevel: batteryLevel, +// ))); +// MixpanelManager().batteryIndicatorClicked(); +// }, +// child: Container( + +// padding: const EdgeInsets.symmetric( +// horizontal: 8, vertical: 8), +// decoration: BoxDecoration( +// color: Colors.transparent, +// borderRadius: BorderRadius.circular(10), +// border: Border.all( +// color: Colors.grey, +// width: 1, +// ), +// ), +// child: Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// Icon( +// Icons.electric_bolt, +// color: batteryLevel > 75 +// ? const Color.fromARGB(255, 0, 255, 8) +// : batteryLevel > 20 +// ? Colors.yellow.shade700 +// : Colors.red, +// size: 12, +// ), +// // Container( +// // width: 10, +// // height: 10, +// // decoration: BoxDecoration( +// // color: batteryLevel > 75 +// // ? const Color.fromARGB(255, 0, 255, 8) +// // : batteryLevel > 20 +// // ? Colors.yellow.shade700 +// // : Colors.red, +// // shape: BoxShape.circle, +// // ), +// // ), +// // const SizedBox(width: 8.0), +// Text( +// '${batteryLevel.toString()}%', +// style: const TextStyle( +// color: Colors.white, +// fontSize: 12, +// // fontWeight: FontWeight.bold, +// ), +// ), +// ], +// ), +// ), +// ) +// : const ScanningUI() +// // IconButton( +// // icon: const Icon( +// // Icons.settings, +// // color: Colors.white, +// // size: 30, +// // ), +// // onPressed: () async { +// // MixpanelManager().settingsOpened(); +// // String language = SharedPreferencesUtil().recordingsLanguage; +// // bool hasSpeech = SharedPreferencesUtil().hasSpeakerProfile; +// // await routeToPage(context, const SettingsPage()); +// // // TODO: this fails like 10 times, connects reconnects, until it finally works. +// // if (GrowthbookUtil().hasStreamingTranscriptFeatureOn() && +// // (language != SharedPreferencesUtil().recordingsLanguage || +// // hasSpeech != +// // SharedPreferencesUtil().hasSpeakerProfile)) { +// // capturePageKey.currentState?.restartWebSocket(); +// // } +// // setState(() {}); +// // }, +// // ) // ], // ), // elevation: 0, @@ -638,724 +1360,3 @@ // super.dispose(); // } // } - -import 'dart:async'; -import 'dart:io'; - -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_blue_plus/flutter_blue_plus.dart'; -import 'package:flutter_foreground_task/flutter_foreground_task.dart'; -import 'package:friend_private/backend/api_requests/api/server.dart'; -import 'package:friend_private/backend/api_requests/cloud_storage.dart'; -import 'package:friend_private/backend/database/memory.dart'; -import 'package:friend_private/backend/database/memory_provider.dart'; -import 'package:friend_private/backend/database/message.dart'; -import 'package:friend_private/backend/database/message_provider.dart'; -import 'package:friend_private/backend/mixpanel.dart'; -import 'package:friend_private/backend/preferences.dart'; -import 'package:friend_private/backend/schema/bt_device.dart'; -import 'package:friend_private/backend/schema/plugin.dart'; -import 'package:friend_private/features/chat/presentation/pages/chat_page.dart'; -import 'package:friend_private/main.dart'; -import 'package:friend_private/pages/capture/connect.dart'; -import 'package:friend_private/pages/capture/page.dart'; -import 'package:friend_private/pages/chat/page.dart'; -// import 'package:friend_private/pages/chat/page.dart'; -// import 'package:friend_private/pages/chat/page.dart'; -import 'package:friend_private/pages/home/backgrund_scafold.dart'; -import 'package:friend_private/pages/home/device.dart'; -import 'package:friend_private/pages/plugins/page.dart'; -import 'package:friend_private/pages/settings/page.dart'; -import 'package:friend_private/scripts.dart'; -import 'package:friend_private/utils/audio/foreground.dart'; -import 'package:friend_private/utils/ble/communication.dart'; -import 'package:friend_private/utils/ble/connected.dart'; -import 'package:friend_private/utils/ble/scan.dart'; -import 'package:friend_private/utils/features/backups.dart'; -import 'package:friend_private/utils/other/notifications.dart'; -import 'package:friend_private/utils/other/temp.dart'; -import 'package:friend_private/widgets/scanning_ui.dart'; -import 'package:friend_private/widgets/upgrade_alert.dart'; -import 'package:instabug_flutter/instabug_flutter.dart'; -import 'package:upgrader/upgrader.dart'; - -class HomePageWrapper extends StatefulWidget { - final dynamic btDevice; - - const HomePageWrapper({super.key, this.btDevice}); - - @override - State createState() => _HomePageWrapperState(); -} - -class _HomePageWrapperState extends State - with WidgetsBindingObserver, TickerProviderStateMixin { - ForegroundUtil foregroundUtil = ForegroundUtil(); - TabController? _controller; - List screens = [Container(), const SizedBox(), const SizedBox()]; - - List memories = []; - List messages = []; - - FocusNode chatTextFieldFocusNode = FocusNode(canRequestFocus: true); - FocusNode memoriesTextFieldFocusNode = FocusNode(canRequestFocus: true); - - GlobalKey capturePageKey = GlobalKey(); - // GlobalKey chatPageKey = GlobalKey(); - StreamSubscription? _connectionStateListener; - StreamSubscription>? _bleBatteryLevelListener; - - int batteryLevel = -1; - BTDeviceStruct? _device; - - List plugins = []; - final _upgrader = MyUpgrader(debugLogging: false, debugDisplayOnce: false); - - _initiateMemories() async { - memories = MemoryProvider() - .getMemoriesOrdered(includeDiscarded: true) - .reversed - .toList(); - setState(() {}); - } - - _refreshMessages() async { - messages = MessageProvider().getMessages(); - setState(() {}); - } - - _setupHasSpeakerProfile() async { - SharedPreferencesUtil().hasSpeakerProfile = - await userHasSpeakerProfile(SharedPreferencesUtil().uid); - debugPrint( - '_setupHasSpeakerProfile: ${SharedPreferencesUtil().hasSpeakerProfile}'); - MixpanelManager().setUserProperty( - 'Speaker Profile', SharedPreferencesUtil().hasSpeakerProfile); - setState(() {}); - } - - _edgeCasePluginNotAvailable() { - var selectedChatPlugin = SharedPreferencesUtil().selectedChatPluginId; - var plugin = plugins.firstWhereOrNull((p) => selectedChatPlugin == p.id); - if (selectedChatPlugin != 'no_selected' && - (plugin == null || !plugin.worksWithChat())) { - SharedPreferencesUtil().selectedChatPluginId = 'no_selected'; - } - } - - Future _initiatePlugins() async { - plugins = SharedPreferencesUtil().pluginsList; - plugins = await retrievePlugins(); - _edgeCasePluginNotAvailable(); - setState(() {}); - } - - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - super.didChangeAppLifecycleState(state); - String event = ''; - if (state == AppLifecycleState.paused) { - event = 'App is paused'; - } else if (state == AppLifecycleState.resumed) { - event = 'App is resumed'; - } else if (state == AppLifecycleState.hidden) { - event = 'App is hidden'; - } else if (state == AppLifecycleState.detached) { - event = 'App is detached'; - } - debugPrint(event); - InstabugLog.logInfo(event); - } - - _migrationScripts() async { - scriptMemoryVectorsExecuted(); - // await migrateMemoriesToObjectBox(); - _initiateMemories(); - } - - ///Screens with respect to subpage - final Map screensWithRespectToPath = { - '/settings': const SettingsPage(), - }; - - @override - void initState() { - _controller = TabController( - length: 3, - vsync: this, - initialIndex: SharedPreferencesUtil().pageToShowFromNotification, - ); - - SharedPreferencesUtil().pageToShowFromNotification = 1; - SharedPreferencesUtil().onboardingCompleted = true; - print('Selected: ${SharedPreferencesUtil().selectedChatPluginId}'); - - WidgetsBinding.instance.addObserver(this); - WidgetsBinding.instance.addPostFrameCallback((_) async { - requestNotificationPermissions(); - foregroundUtil.requestPermissionForAndroid(); - }); - _refreshMessages(); - executeBackupWithUid(); - _initiateMemories(); - _initiatePlugins(); - _setupHasSpeakerProfile(); - _migrationScripts(); - authenticateGCP(); - if (SharedPreferencesUtil().deviceId.isNotEmpty) { - scanAndConnectDevice().then(_onConnected); - } - - createNotification( - title: 'Don\'t forget to wear AVM today', - body: 'Wear your AVM and capture your memories today.', - notificationId: 4, - isMorningNotification: true, - ); - createNotification( - title: 'Here is your action plan for tomorrow', - body: 'Check out your daily summary to see what you should do tomorrow.', - notificationId: 5, - isDailySummaryNotification: true, - payload: {'path': '/chat'}, - ); - if (SharedPreferencesUtil().subPageToShowFromNotification != '') { - final subPageRoute = - SharedPreferencesUtil().subPageToShowFromNotification; - WidgetsBinding.instance.addPostFrameCallback((_) async { - MyApp.navigatorKey.currentState?.push( - MaterialPageRoute( - builder: (context) => - screensWithRespectToPath[subPageRoute] as Widget, - ), - ); - }); - SharedPreferencesUtil().subPageToShowFromNotification = ''; - } - super.initState(); - } - - _initiateConnectionListener() async { - if (_connectionStateListener != null) return; - // TODO: when disconnected manually need to remove this connection state listener - _connectionStateListener = getConnectionStateListener( - deviceId: _device!.id, - onDisconnected: () { - debugPrint('onDisconnected'); - capturePageKey.currentState - ?.resetState(restartBytesProcessing: false); - setState(() => _device = null); - InstabugLog.logInfo('AVM Device Disconnected'); - if (SharedPreferencesUtil().reconnectNotificationIsChecked) { - createNotification( - title: 'AVM Device Disconnected', - body: 'Please reconnect to continue using your AVM.', - ); - } - MixpanelManager().deviceDisconnected(); - foregroundUtil.stopForegroundTask(); - }, - onConnected: ((d) => - _onConnected(d, initiateConnectionListener: false))); - } - - _startForeground() async { - if (!Platform.isAndroid) return; - await foregroundUtil.initForegroundTask(); - var result = await foregroundUtil.startForegroundTask(); - debugPrint('_startForeground: $result'); - } - - _onConnected(BTDeviceStruct? connectedDevice, - {bool initiateConnectionListener = true}) { - debugPrint('_onConnected: $connectedDevice'); - if (connectedDevice == null) return; - clearNotification(1); - _device = connectedDevice; - if (initiateConnectionListener) _initiateConnectionListener(); - _initiateBleBatteryListener(); - capturePageKey.currentState - ?.resetState(restartBytesProcessing: true, btDevice: connectedDevice); - MixpanelManager().deviceConnected(); - SharedPreferencesUtil().deviceId = _device!.id; - SharedPreferencesUtil().deviceName = _device!.name; - _startForeground(); - setState(() {}); - } - - _initiateBleBatteryListener() async { - _bleBatteryLevelListener?.cancel(); - _bleBatteryLevelListener = await getBleBatteryLevelListener( - _device!.id, - onBatteryLevelChange: (int value) { - setState(() { - batteryLevel = value; - }); - }, - ); - } - - _tabChange(int index) { - MixpanelManager() - .bottomNavigationTabClicked(['Device', 'Chat', 'Setting'][index]); - FocusScope.of(context).unfocus(); - setState(() { - _controller!.index = index; - }); - } - - @override - Widget build(BuildContext context) { - return WithForegroundTask( - child: MyUpgradeAlert( - upgrader: _upgrader, - dialogStyle: Platform.isIOS - ? UpgradeDialogStyle.cupertino - : UpgradeDialogStyle.material, - child: CustomScaffold( - backgroundColor: Theme.of(context).colorScheme.primary, - body: GestureDetector( - onTap: () { - FocusScope.of(context).unfocus(); - chatTextFieldFocusNode.unfocus(); - memoriesTextFieldFocusNode.unfocus(); - }, - child: Stack( - children: [ - Center( - child: TabBarView( - controller: _controller, - // physics: const NeverScrollableScrollPhysics(), - children: [ - // const MyWidget(), - // TestPage( - // refreshMemories: _initiateMemories, - // textFieldFocusNode: memoriesTextFieldFocusNode, - // memories: memories, - // ), - - CapturePage( - key: capturePageKey, - device: _device, - refreshMemories: _initiateMemories, - refreshMessages: _refreshMessages, - ), - // ChatPage( - // key: chatPageKey, - // textFieldFocusNode: chatTextFieldFocusNode, - // messages: messages, - // refreshMessages: _refreshMessages, - // ), - ChatPageTest( - textFieldFocusNode: chatTextFieldFocusNode, - ), - const SettingsPage(), - ], - ), - ), - if (chatTextFieldFocusNode.hasFocus || - memoriesTextFieldFocusNode.hasFocus) - const SizedBox.shrink() - else - Align( - alignment: Alignment.bottomCenter, - child: Container( - margin: const EdgeInsets.fromLTRB(16, 16, 16, 40), - decoration: BoxDecoration( - color: Colors.black, - borderRadius: const BorderRadius.all(Radius.circular(16)), - border: Border.all(color: Colors.grey), - // border: GradientBoxBorder( - // gradient: LinearGradient(colors: [ - // Color.fromARGB(127, 208, 208, 208), - // Color.fromARGB(127, 188, 99, 121), - // Color.fromARGB(127, 86, 101, 182), - // Color.fromARGB(127, 126, 190, 236) - // ]), - // width: 2, - // ), - shape: BoxShape.rectangle, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: MaterialButton( - onPressed: () => _tabChange(0), - child: Padding( - padding: const EdgeInsets.only( - top: 20, - bottom: 20, - ), - child: Text( - 'Capture', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: _controller!.index == 0 - ? Colors.white - : Colors.grey, - fontSize: 16, - ), - ), - ), - ), - ), - Expanded( - child: MaterialButton( - onPressed: () => _tabChange(1), - child: Padding( - padding: - const EdgeInsets.only(top: 20, bottom: 20), - child: Text('Chat', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: _controller!.index == 1 - ? Colors.white - : Colors.grey, - fontSize: 16)), - ), - ), - ), - Expanded( - child: MaterialButton( - onPressed: () => _tabChange(2), - child: Padding( - padding: - const EdgeInsets.only(top: 20, bottom: 20), - child: Text( - 'Setting', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: _controller!.index == 2 - ? Colors.white - : Colors.grey, - fontSize: 16), - ), - ), - ), - ), - ], - ), - ), - ) - ], - ), - ), - appBar: AppBar( - automaticallyImplyLeading: false, - backgroundColor: Theme.of(context).colorScheme.surface, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - //* AVM page navigating - // _device != null && batteryLevel != -1 - // ? GestureDetector( - // onTap: _device == null - // ? null - // : () { - // Navigator.of(context).push(MaterialPageRoute( - // builder: (c) => ConnectedDevice( - // device: _device!, - // batteryLevel: batteryLevel, - // ))); - // MixpanelManager().batteryIndicatorClicked(); - // }, - // child: Container( - // padding: const EdgeInsets.symmetric( - // horizontal: 14, vertical: 10), - // decoration: BoxDecoration( - // color: Colors.transparent, - // borderRadius: BorderRadius.circular(10), - // border: Border.all( - // color: Colors.grey, - // width: 1, - // ), - // ), - // child: Row( - // mainAxisSize: MainAxisSize.min, - // children: [ - // Container( - // width: 10, - // height: 10, - // decoration: BoxDecoration( - // color: batteryLevel > 75 - // ? const Color.fromARGB(255, 0, 255, 8) - // : batteryLevel > 20 - // ? Colors.yellow.shade700 - // : Colors.red, - // shape: BoxShape.circle, - // ), - // ), - // const SizedBox(width: 8.0), - // Text( - // '${batteryLevel.toString()}%', - // style: const TextStyle( - // color: Colors.white, - // fontSize: 12, - // fontWeight: FontWeight.bold, - // ), - // ), - // ], - // )), - // ) - // : - TextButton( - onPressed: () async { - if (SharedPreferencesUtil().deviceId.isEmpty) { - routeToPage(context, const ConnectDevicePage()); - MixpanelManager().connectFriendClicked(); - } else { - await routeToPage(context, - const ConnectedDevice(device: null, batteryLevel: 0)); - } - setState(() {}); - }, - // style: TextButton.styleFrom( - // padding: EdgeInsets.zero, - // backgroundColor: Colors.transparent, - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(10), - // side: const BorderSide(color: Colors.white, width: 1), - // ), - // ), - child: Image.asset( - 'assets/images/herologo.png', - width: 60, - height: 30, - ), - ), - _controller!.index == 1 - ? Padding( - padding: const EdgeInsets.only(left: 0), - child: Container( - // decoration: BoxDecoration( - // border: Border.all(color: Colors.grey), - // borderRadius: BorderRadius.circular(30), - // ), - padding: const EdgeInsets.symmetric(horizontal: 16), - child: DropdownButton( - menuMaxHeight: 350, - value: SharedPreferencesUtil().selectedChatPluginId, - onChanged: (s) async { - if ((s == 'no_selected' && - SharedPreferencesUtil() - .pluginsEnabled - .isEmpty) || - s == 'enable') { - await routeToPage(context, - const PluginsPage(filterChatOnly: true)); - setState(() {}); - return; - } - print( - 'Selected: $s prefs: ${SharedPreferencesUtil().selectedChatPluginId}'); - if (s == null || - s == - SharedPreferencesUtil() - .selectedChatPluginId) return; - - SharedPreferencesUtil().selectedChatPluginId = s; - var plugin = - plugins.firstWhereOrNull((p) => p.id == s); - // chatPageKey.currentState - // ?.sendInitialPluginMessage(plugin); - setState(() {}); - }, - icon: Container(), - alignment: Alignment.center, - dropdownColor: Colors.black, - style: const TextStyle( - color: Colors.white, fontSize: 16), - underline: - Container(height: 0, color: Colors.transparent), - isExpanded: false, - itemHeight: 48, - padding: EdgeInsets.zero, - items: _getPluginsDropdownItems(context), - ), - ), - ) - : const SizedBox(width: 16), - //* AVM Battery indecator - _device != null && batteryLevel != -1 - ? GestureDetector( - onTap: _device == null - ? null - : () { - Navigator.of(context).push(MaterialPageRoute( - builder: (c) => ConnectedDevice( - device: _device!, - batteryLevel: batteryLevel, - ))); - MixpanelManager().batteryIndicatorClicked(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 8), - decoration: BoxDecoration( - color: Colors.transparent, - borderRadius: BorderRadius.circular(10), - border: Border.all( - color: Colors.grey, - width: 1, - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - Icons.electric_bolt, - color: batteryLevel > 75 - ? const Color.fromARGB(255, 0, 255, 8) - : batteryLevel > 20 - ? Colors.yellow.shade700 - : Colors.red, - size: 12, - ), - // Container( - // width: 10, - // height: 10, - // decoration: BoxDecoration( - // color: batteryLevel > 75 - // ? const Color.fromARGB(255, 0, 255, 8) - // : batteryLevel > 20 - // ? Colors.yellow.shade700 - // : Colors.red, - // shape: BoxShape.circle, - // ), - // ), - // const SizedBox(width: 8.0), - Text( - '${batteryLevel.toString()}%', - style: const TextStyle( - color: Colors.white, - fontSize: 12, - // fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - ) - : const ScanningUI() - // IconButton( - // icon: const Icon( - // Icons.settings, - // color: Colors.white, - // size: 30, - // ), - // onPressed: () async { - // MixpanelManager().settingsOpened(); - // String language = SharedPreferencesUtil().recordingsLanguage; - // bool hasSpeech = SharedPreferencesUtil().hasSpeakerProfile; - // await routeToPage(context, const SettingsPage()); - // // TODO: this fails like 10 times, connects reconnects, until it finally works. - // if (GrowthbookUtil().hasStreamingTranscriptFeatureOn() && - // (language != SharedPreferencesUtil().recordingsLanguage || - // hasSpeech != - // SharedPreferencesUtil().hasSpeakerProfile)) { - // capturePageKey.currentState?.restartWebSocket(); - // } - // setState(() {}); - // }, - // ) - ], - ), - elevation: 0, - centerTitle: true, - ), - ), - )); - } - - _getPluginsDropdownItems(BuildContext context) { - var items = [ - DropdownMenuItem( - value: 'no_selected', - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Icon(size: 20, Icons.chat, color: Colors.white), - const SizedBox(width: 10), - Text( - SharedPreferencesUtil().pluginsEnabled.isEmpty - ? 'Enable Plugins ' - : 'Select a plugin', - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.w500, - fontSize: 16), - ) - ], - ), - ) - ] + - plugins - .where((p) => - SharedPreferencesUtil().pluginsEnabled.contains(p.id) && - p.worksWithChat()) - .map>((Plugin plugin) { - return DropdownMenuItem( - value: plugin.id, - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - CircleAvatar( - backgroundColor: Colors.white, - maxRadius: 12, - backgroundImage: NetworkImage(plugin.getImageUrl()), - ), - const SizedBox(width: 8), - Text( - plugin.name.length > 18 - ? '${plugin.name.substring(0, 18)}...' - : plugin.name + ' ' * (18 - plugin.name.length), - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.w500, - fontSize: 16), - ) - ], - ), - ); - }).toList(); - if (SharedPreferencesUtil().pluginsEnabled.isNotEmpty) { - items.add(const DropdownMenuItem( - value: 'enable', - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - CircleAvatar( - backgroundColor: Colors.transparent, - maxRadius: 12, - child: Icon(Icons.star, color: Colors.purpleAccent), - ), - SizedBox(width: 8), - Text('Enable Plugins ', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.w500, - fontSize: 16)) - ], - ), - )); - } - return items; - } - - @override - void dispose() { - WidgetsBinding.instance.removeObserver(this); - _connectionStateListener?.cancel(); - _bleBatteryLevelListener?.cancel(); - - _controller?.dispose(); - super.dispose(); - } -} diff --git a/apps/AppWithWearable/lib/pages/onboarding/wrapper.dart b/apps/AppWithWearable/lib/pages/onboarding/wrapper.dart index 0902f4a8d..bd903c94e 100644 --- a/apps/AppWithWearable/lib/pages/onboarding/wrapper.dart +++ b/apps/AppWithWearable/lib/pages/onboarding/wrapper.dart @@ -5,6 +5,7 @@ import 'package:friend_private/backend/auth.dart'; import 'package:friend_private/backend/mixpanel.dart'; import 'package:friend_private/backend/preferences.dart'; import 'package:friend_private/pages/home/backgrund_scafold.dart'; +import 'package:friend_private/pages/home/home_page_wrapper.dart'; import 'package:friend_private/pages/home/page.dart'; import 'package:friend_private/pages/onboarding/auth.dart'; import 'package:friend_private/pages/onboarding/complete/complete.dart'; @@ -99,7 +100,7 @@ class _OnboardingWrapperState extends State MixpanelManager().onboardingStepICompleted('Auth'); if (SharedPreferencesUtil().onboardingCompleted) { // previous users - routeToPage(context, const HomePageWrapper(), + routeToPage(context, const HomePageWrapperTest(), replace: true); } else { _goNext(); @@ -132,7 +133,7 @@ class _OnboardingWrapperState extends State ), CompletePage( goNext: () { - routeToPage(context, const HomePageWrapper(), + routeToPage(context, const HomePageWrapperTest(), replace: true); MixpanelManager().onboardingStepICompleted('Finalize'); MixpanelManager().onboardingCompleted(); diff --git a/apps/AppWithWearable/lib/pages/settings/page.dart b/apps/AppWithWearable/lib/pages/settings/page.dart index e53da55c7..dd4716d11 100644 --- a/apps/AppWithWearable/lib/pages/settings/page.dart +++ b/apps/AppWithWearable/lib/pages/settings/page.dart @@ -199,10 +199,10 @@ class _SettingsPageState extends State { textAlign: TextAlign.start, ), ), - getItemAddOn('Plugins', () { - MixpanelManager().pluginsOpened(); - routeToPage(context, const PluginsPage()); - }, icon: Icons.integration_instructions), + // getItemAddOn('Plugins', () { + // MixpanelManager().pluginsOpened(); + // routeToPage(context, const PluginsPage()); + // }, icon: Icons.integration_instructions), SharedPreferencesUtil().useTranscriptServer ? getItemAddOn('Speech Profile', () { routeToPage(context, const SpeakerIdPage()); diff --git a/apps/AppWithWearable/lib/pages/speaker_id/page.dart b/apps/AppWithWearable/lib/pages/speaker_id/page.dart index 64f735bae..cdc24bd9c 100644 --- a/apps/AppWithWearable/lib/pages/speaker_id/page.dart +++ b/apps/AppWithWearable/lib/pages/speaker_id/page.dart @@ -8,6 +8,7 @@ import 'package:friend_private/backend/mixpanel.dart'; import 'package:friend_private/backend/preferences.dart'; import 'package:friend_private/backend/schema/bt_device.dart'; import 'package:friend_private/backend/schema/sample.dart'; +import 'package:friend_private/pages/home/home_page_wrapper.dart'; import 'package:friend_private/pages/home/page.dart'; import 'package:friend_private/pages/speaker_id/tabs/completed.dart'; import 'package:friend_private/pages/speaker_id/tabs/instructions.dart'; @@ -102,7 +103,7 @@ class _SpeakerIdPageState extends State : TextButton( onPressed: () { Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (c) => const HomePageWrapper())); + builder: (c) => const HomePageWrapperTest())); }, child: const Text( 'Skip', @@ -187,7 +188,7 @@ class _SpeakerIdPageState extends State if (_currentIdx == _controller!.length - 1) { if (widget.onbording) { Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (c) => const HomePageWrapper())); + MaterialPageRoute(builder: (c) => const HomePageWrapperTest())); } else { Navigator.pop(context); } diff --git a/apps/AppWithWearable/lib/utils/other/notifications.dart b/apps/AppWithWearable/lib/utils/other/notifications.dart index 7e39f0edd..61a12dc8b 100644 --- a/apps/AppWithWearable/lib/utils/other/notifications.dart +++ b/apps/AppWithWearable/lib/utils/other/notifications.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:friend_private/backend/notify_on_kill.dart'; import 'package:friend_private/backend/preferences.dart'; import 'package:friend_private/main.dart'; +import 'package:friend_private/pages/home/home_page_wrapper.dart'; import 'package:friend_private/pages/home/page.dart'; // TODO: could install the latest version due to podfile issues, so installed 0.8.3 @@ -166,6 +167,6 @@ class NotificationUtil { SharedPreferencesUtil().subPageToShowFromNotification = payload?['navigateTo'] ?? ''; } SharedPreferencesUtil().pageToShowFromNotification = screensWithRespectToPath[payload?['path']] ?? 1; - MyApp.navigatorKey.currentState?.pushReplacement(MaterialPageRoute(builder: (context) => const HomePageWrapper())); + MyApp.navigatorKey.currentState?.pushReplacement(MaterialPageRoute(builder: (context) => const HomePageWrapperTest())); } } diff --git a/apps/AppWithWearable/lib/widgets/scanning_ui.dart b/apps/AppWithWearable/lib/widgets/scanning_ui.dart index a4f407f60..05c88cacd 100644 --- a/apps/AppWithWearable/lib/widgets/scanning_ui.dart +++ b/apps/AppWithWearable/lib/widgets/scanning_ui.dart @@ -27,9 +27,9 @@ class _ScanningUIState extends State { // Color(0xFF5A00FF), // Color(0xFF3400D8), ], - minRadius: 10, - ripplesCount: 2, - duration: Duration(milliseconds: 3000), + minRadius: 5, + ripplesCount: 3, + duration: Duration(milliseconds:3000), repeat: true, child: Icon( Icons.bluetooth_searching, diff --git a/apps/AppWithWearable/lib/widgets/transcript.dart b/apps/AppWithWearable/lib/widgets/transcript.dart index e8627bf1c..242e8dce2 100644 --- a/apps/AppWithWearable/lib/widgets/transcript.dart +++ b/apps/AppWithWearable/lib/widgets/transcript.dart @@ -33,7 +33,7 @@ class _TranscriptWidgetState extends State { physics: const NeverScrollableScrollPhysics(), separatorBuilder: (_, __) => const SizedBox(height: 16.0), itemBuilder: (context, idx) { - if (idx == 0) return SizedBox(height: widget.topMargin ? 32 : 0); + if (idx == 0) return SizedBox(height: widget.topMargin ? 8 : 0); if (idx == widget.segments.length + 1) return const SizedBox(height: 64); final data = widget.segments[idx - 1];