Skip to content

Commit facc6cc

Browse files
authored
2309-action-items-make-them-as-a-separate-tab (#2310)
implementation or tab for action items. Screenshot attached. fix #2309 ![image](https://github.com/user-attachments/assets/6251c501-5360-4788-b164-224a9084a9dd)
2 parents 27704d0 + 8b5a212 commit facc6cc

File tree

2 files changed

+109
-8
lines changed

2 files changed

+109
-8
lines changed

app/lib/pages/conversation_detail/page.dart

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:omi/pages/conversation_detail/widgets.dart';
1010
import 'package:omi/pages/settings/people.dart';
1111
import 'package:omi/providers/connectivity_provider.dart';
1212
import 'package:omi/providers/conversation_provider.dart';
13-
import 'package:omi/utils/alerts/app_snackbar.dart';
1413
import 'package:omi/utils/analytics/mixpanel.dart';
1514
import 'package:omi/utils/other/temp.dart';
1615
import 'package:omi/widgets/conversation_bottom_bar.dart';
@@ -49,10 +48,23 @@ class _ConversationDetailPageState extends State<ConversationDetailPage> with Ti
4948
void initState() {
5049
super.initState();
5150

52-
_controller = TabController(length: 2, vsync: this, initialIndex: 1); // Start with summary tab
51+
_controller = TabController(length: 3, vsync: this, initialIndex: 1); // Start with summary tab
5352
_controller!.addListener(() {
5453
setState(() {
55-
selectedTab = _controller!.index == 0 ? ConversationTab.transcript : ConversationTab.summary;
54+
switch (_controller!.index) {
55+
case 0:
56+
selectedTab = ConversationTab.transcript;
57+
break;
58+
case 1:
59+
selectedTab = ConversationTab.summary;
60+
break;
61+
case 2:
62+
selectedTab = ConversationTab.actionItems;
63+
break;
64+
default:
65+
debugPrint('Invalid tab index: ${_controller!.index}');
66+
selectedTab = ConversationTab.summary;
67+
}
5668
});
5769
});
5870

@@ -188,6 +200,7 @@ class _ConversationDetailPageState extends State<ConversationDetailPage> with Ti
188200
},
189201
),
190202
const SummaryTab(),
203+
const ActionItemsTab(),
191204
],
192205
);
193206
}),
@@ -210,7 +223,21 @@ class _ConversationDetailPageState extends State<ConversationDetailPage> with Ti
210223
hasSegments:
211224
conversation.transcriptSegments.isNotEmpty || conversation.externalIntegration != null,
212225
onTabSelected: (tab) {
213-
int index = tab == ConversationTab.transcript ? 0 : 1;
226+
int index;
227+
switch (tab) {
228+
case ConversationTab.transcript:
229+
index = 0;
230+
break;
231+
case ConversationTab.summary:
232+
index = 1;
233+
break;
234+
case ConversationTab.actionItems:
235+
index = 2;
236+
break;
237+
default:
238+
debugPrint('Invalid tab selected: $tab');
239+
index = 1; // Default to summary tab
240+
}
214241
_controller!.animateTo(index);
215242
},
216243
onStopPressed: () {
@@ -556,3 +583,62 @@ class EditSegmentWidget extends StatelessWidget {
556583
});
557584
}
558585
}
586+
587+
class ActionItemsTab extends StatelessWidget {
588+
const ActionItemsTab({super.key});
589+
590+
@override
591+
Widget build(BuildContext context) {
592+
return GestureDetector(
593+
onTap: () => FocusScope.of(context).unfocus(),
594+
child: Consumer<ConversationDetailProvider>(
595+
builder: (context, provider, child) {
596+
final hasActionItems = provider.conversation.structured.actionItems.where((item) => !item.deleted).isNotEmpty;
597+
598+
return ListView(
599+
shrinkWrap: true,
600+
children: [
601+
const SizedBox(height: 24),
602+
if (hasActionItems) const ActionItemsListWidget() else _buildEmptyState(context),
603+
const SizedBox(height: 150)
604+
],
605+
);
606+
},
607+
),
608+
);
609+
}
610+
611+
Widget _buildEmptyState(BuildContext context) {
612+
return Center(
613+
child: Padding(
614+
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 40.0),
615+
child: Column(
616+
mainAxisAlignment: MainAxisAlignment.center,
617+
children: [
618+
const Icon(
619+
Icons.check_circle_outline,
620+
size: 72,
621+
color: Colors.grey,
622+
),
623+
const SizedBox(height: 24),
624+
Text(
625+
'No Action Items',
626+
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
627+
color: Colors.white,
628+
),
629+
),
630+
const SizedBox(height: 12),
631+
Text(
632+
'This memory doesn\'t have any action items yet. They\'ll appear here when your conversations include tasks or to-dos.',
633+
textAlign: TextAlign.center,
634+
style: TextStyle(
635+
color: Colors.grey.shade400,
636+
fontSize: 16,
637+
),
638+
),
639+
],
640+
),
641+
),
642+
);
643+
}
644+
}

app/lib/widgets/conversation_bottom_bar.dart

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ enum ConversationBottomBarMode {
1313
detail // For viewing completed conversations
1414
}
1515

16-
enum ConversationTab { transcript, summary }
16+
enum ConversationTab { transcript, summary, actionItems }
1717

1818
class ConversationBottomBar extends StatelessWidget {
1919
final ConversationBottomBarMode mode;
@@ -49,7 +49,7 @@ class ConversationBottomBar extends StatelessWidget {
4949
borderRadius: BorderRadius.circular(28),
5050
child: Container(
5151
height: 56,
52-
width: mode == ConversationBottomBarMode.recording ? 180 : 290,
52+
width: mode == ConversationBottomBarMode.recording ? 180 : 360,
5353
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
5454
decoration: BoxDecoration(
5555
color: Colors.grey.shade900,
@@ -69,8 +69,15 @@ class ConversationBottomBar extends StatelessWidget {
6969
// Transcript tab
7070
_buildTranscriptTab(),
7171

72-
// Stop button or Summary tab
73-
if (mode == ConversationBottomBarMode.recording) _buildStopButton() else _buildSummaryTab(context),
72+
// Stop button or Summary/Action Items tabs
73+
...switch (mode) {
74+
ConversationBottomBarMode.recording => [_buildStopButton()],
75+
ConversationBottomBarMode.detail => [
76+
_buildSummaryTab(context),
77+
_buildActionItemsTab(),
78+
],
79+
_ => [_buildSummaryTab(context)],
80+
},
7481
],
7582
),
7683
),
@@ -164,4 +171,12 @@ class ConversationBottomBar extends StatelessWidget {
164171
},
165172
);
166173
}
174+
175+
Widget _buildActionItemsTab() {
176+
return TabButton(
177+
icon: Icons.check_circle_outline,
178+
isSelected: selectedTab == ConversationTab.actionItems,
179+
onTap: () => onTabSelected(ConversationTab.actionItems),
180+
);
181+
}
167182
}

0 commit comments

Comments
 (0)