neoagent 2.3.1-beta.56 → 2.3.1-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/flutter_app/lib/features/onboarding/onboarding_chrome.dart +569 -0
- package/flutter_app/lib/features/onboarding/onboarding_messaging_step.dart +155 -216
- package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +206 -234
- package/flutter_app/lib/features/onboarding/onboarding_shell.dart +3 -5
- package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +192 -105
- package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +87 -145
- package/flutter_app/lib/main_app_shell.dart +439 -19
- package/flutter_app/lib/main_controller.dart +12 -6
- package/flutter_app/lib/main_devices.dart +204 -109
- package/flutter_app/lib/main_navigation.dart +2 -7
- package/flutter_app/lib/main_recordings.dart +382 -332
- package/flutter_app/lib/main_settings.dart +16 -0
- package/flutter_app/lib/main_shared.dart +41 -29
- package/flutter_app/lib/main_theme.dart +28 -30
- package/flutter_app/lib/src/theme/palette.dart +14 -14
- package/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +77110 -76183
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import 'package:flutter/material.dart';
|
|
2
2
|
import 'package:flutter_animate/flutter_animate.dart';
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import '../../main.dart';
|
|
5
|
+
import 'onboarding_chrome.dart';
|
|
5
6
|
|
|
6
7
|
class OnboardingMessagingStep extends StatefulWidget {
|
|
7
8
|
const OnboardingMessagingStep({
|
|
@@ -14,7 +15,8 @@ class OnboardingMessagingStep extends StatefulWidget {
|
|
|
14
15
|
final NeoAgentController controller;
|
|
15
16
|
|
|
16
17
|
@override
|
|
17
|
-
State<OnboardingMessagingStep> createState() =>
|
|
18
|
+
State<OnboardingMessagingStep> createState() =>
|
|
19
|
+
_OnboardingMessagingStepState();
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
class _OnboardingMessagingStepState extends State<OnboardingMessagingStep> {
|
|
@@ -22,240 +24,177 @@ class _OnboardingMessagingStepState extends State<OnboardingMessagingStep> {
|
|
|
22
24
|
|
|
23
25
|
@override
|
|
24
26
|
Widget build(BuildContext context) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
final platforms = messagingPlatforms.length > 5
|
|
28
|
+
? messagingPlatforms.take(5).toList()
|
|
29
|
+
: messagingPlatforms;
|
|
30
|
+
|
|
31
|
+
return OnboardingScaffold(
|
|
32
|
+
step: 2,
|
|
33
|
+
totalSteps: 4,
|
|
34
|
+
eyebrow: 'COMMUNICATION',
|
|
35
|
+
title: 'Connect the channels\nyou actually use.',
|
|
36
|
+
description:
|
|
37
|
+
'Choose one messaging surface to start. NeoOS can prepare context, monitor the right signals, and keep the interaction layer close to your real workflow.',
|
|
38
|
+
sidePanel: OnboardingPanel(
|
|
28
39
|
child: Column(
|
|
29
40
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
30
41
|
children: <Widget>[
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
style: GoogleFonts.spaceGrotesk(
|
|
35
|
-
fontSize: 48,
|
|
36
|
-
fontWeight: FontWeight.w800,
|
|
37
|
-
height: 1.1,
|
|
38
|
-
letterSpacing: -1.5,
|
|
42
|
+
const Text(
|
|
43
|
+
'Setup principle',
|
|
44
|
+
style: TextStyle(
|
|
39
45
|
color: Colors.white,
|
|
46
|
+
fontSize: 20,
|
|
47
|
+
fontWeight: FontWeight.w800,
|
|
40
48
|
),
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
.slideX(begin: -0.1, end: 0, curve: Curves.easeOutCubic),
|
|
44
|
-
|
|
45
|
-
const SizedBox(height: 16),
|
|
49
|
+
),
|
|
50
|
+
const SizedBox(height: 10),
|
|
46
51
|
Text(
|
|
47
|
-
'
|
|
52
|
+
'Start with one high-value integration first. The product feels smarter when the first connection is relevant, not exhaustive.',
|
|
48
53
|
style: TextStyle(
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
color: Colors.white.withValues(alpha: 0.72),
|
|
55
|
+
fontSize: 15,
|
|
51
56
|
height: 1.5,
|
|
52
57
|
),
|
|
53
|
-
).animate()
|
|
54
|
-
.fadeIn(duration: 600.ms, delay: 200.ms)
|
|
55
|
-
.slideX(begin: -0.1, end: 0, curve: Curves.easeOutCubic),
|
|
56
|
-
|
|
57
|
-
const SizedBox(height: 60),
|
|
58
|
-
|
|
59
|
-
Expanded(
|
|
60
|
-
child: ListView.separated(
|
|
61
|
-
itemCount: messagingPlatforms.length > 5 ? 6 : messagingPlatforms.length,
|
|
62
|
-
separatorBuilder: (context, index) => const SizedBox(height: 16),
|
|
63
|
-
itemBuilder: (context, index) {
|
|
64
|
-
final platformCount = messagingPlatforms.length > 5 ? 5 : messagingPlatforms.length;
|
|
65
|
-
if (index == platformCount) {
|
|
66
|
-
return Padding(
|
|
67
|
-
padding: const EdgeInsets.only(top: 16, bottom: 32),
|
|
68
|
-
child: Center(
|
|
69
|
-
child: Text(
|
|
70
|
-
'More providers available in Settings',
|
|
71
|
-
style: TextStyle(
|
|
72
|
-
color: Colors.white.withValues(alpha: 0.5),
|
|
73
|
-
fontSize: 14,
|
|
74
|
-
fontWeight: FontWeight.w500,
|
|
75
|
-
),
|
|
76
|
-
),
|
|
77
|
-
),
|
|
78
|
-
).animate().fadeIn(delay: 1000.ms);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
final platform = messagingPlatforms[index];
|
|
82
|
-
final isSelected = _selectedPlatform?.id == platform.id;
|
|
83
|
-
|
|
84
|
-
return _PlatformCard(
|
|
85
|
-
platform: platform,
|
|
86
|
-
isSelected: isSelected,
|
|
87
|
-
onTap: () {
|
|
88
|
-
setState(() {
|
|
89
|
-
_selectedPlatform = platform;
|
|
90
|
-
});
|
|
91
|
-
},
|
|
92
|
-
).animate()
|
|
93
|
-
.fadeIn(duration: 500.ms, delay: (400 + index * 100).ms)
|
|
94
|
-
.slideY(begin: 0.2, end: 0, curve: Curves.easeOutCubic);
|
|
95
|
-
},
|
|
96
|
-
),
|
|
97
58
|
),
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
59
|
+
const SizedBox(height: 18),
|
|
60
|
+
const Wrap(
|
|
61
|
+
spacing: 12,
|
|
62
|
+
runSpacing: 12,
|
|
102
63
|
children: <Widget>[
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
style: TextButton.styleFrom(
|
|
106
|
-
foregroundColor: Colors.white54,
|
|
107
|
-
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
|
108
|
-
),
|
|
109
|
-
child: const Text('Skip for now', style: TextStyle(fontSize: 16)),
|
|
110
|
-
).animate().fadeIn(delay: 800.ms),
|
|
111
|
-
|
|
112
|
-
Row(
|
|
113
|
-
mainAxisSize: MainAxisSize.min,
|
|
114
|
-
children: [
|
|
115
|
-
if (_selectedPlatform != null)
|
|
116
|
-
FilledButton.icon(
|
|
117
|
-
onPressed: () async {
|
|
118
|
-
try {
|
|
119
|
-
await openMessagingConfig(context, widget.controller, _selectedPlatform!);
|
|
120
|
-
} catch (e) {
|
|
121
|
-
if (context.mounted) {
|
|
122
|
-
ScaffoldMessenger.of(context).showSnackBar(
|
|
123
|
-
SnackBar(
|
|
124
|
-
content: Text('Failed to connect: $e'),
|
|
125
|
-
backgroundColor: Colors.redAccent,
|
|
126
|
-
),
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
style: FilledButton.styleFrom(
|
|
132
|
-
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20),
|
|
133
|
-
shape: RoundedRectangleBorder(
|
|
134
|
-
borderRadius: BorderRadius.circular(20),
|
|
135
|
-
),
|
|
136
|
-
),
|
|
137
|
-
icon: const Icon(Icons.settings_rounded),
|
|
138
|
-
label: const Text(
|
|
139
|
-
'Configure',
|
|
140
|
-
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
|
|
141
|
-
),
|
|
142
|
-
).animate().fadeIn(delay: 800.ms),
|
|
143
|
-
|
|
144
|
-
if (_selectedPlatform != null)
|
|
145
|
-
const SizedBox(width: 8),
|
|
146
|
-
|
|
147
|
-
FilledButton.icon(
|
|
148
|
-
onPressed: widget.onNext,
|
|
149
|
-
style: FilledButton.styleFrom(
|
|
150
|
-
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
|
|
151
|
-
shape: RoundedRectangleBorder(
|
|
152
|
-
borderRadius: BorderRadius.circular(20),
|
|
153
|
-
),
|
|
154
|
-
backgroundColor: _selectedPlatform != null
|
|
155
|
-
? Colors.white.withValues(alpha: 0.1)
|
|
156
|
-
: Theme.of(context).colorScheme.primary,
|
|
157
|
-
foregroundColor: Colors.white,
|
|
158
|
-
),
|
|
159
|
-
icon: const Icon(Icons.arrow_forward_rounded),
|
|
160
|
-
label: Text(
|
|
161
|
-
_selectedPlatform != null ? 'Next' : 'Continue',
|
|
162
|
-
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
|
|
163
|
-
),
|
|
164
|
-
).animate().fadeIn(delay: 800.ms),
|
|
165
|
-
],
|
|
166
|
-
),
|
|
64
|
+
OnboardingMetricPill(label: 'Signal', value: 'Relevant only'),
|
|
65
|
+
OnboardingMetricPill(label: 'Access', value: 'Configurable'),
|
|
167
66
|
],
|
|
168
67
|
),
|
|
169
68
|
],
|
|
170
69
|
),
|
|
171
|
-
),
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
required this.platform,
|
|
179
|
-
required this.isSelected,
|
|
180
|
-
required this.onTap,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
final MessagingPlatformDescriptor platform;
|
|
184
|
-
final bool isSelected;
|
|
185
|
-
final VoidCallback onTap;
|
|
186
|
-
|
|
187
|
-
@override
|
|
188
|
-
Widget build(BuildContext context) {
|
|
189
|
-
final color = platform.accent;
|
|
190
|
-
|
|
191
|
-
return InkWell(
|
|
192
|
-
onTap: onTap,
|
|
193
|
-
borderRadius: BorderRadius.circular(24),
|
|
194
|
-
child: AnimatedContainer(
|
|
195
|
-
duration: const Duration(milliseconds: 300),
|
|
196
|
-
curve: Curves.easeOutCubic,
|
|
197
|
-
padding: const EdgeInsets.all(24),
|
|
198
|
-
decoration: BoxDecoration(
|
|
199
|
-
color: isSelected
|
|
200
|
-
? color.withValues(alpha: 0.15)
|
|
201
|
-
: Colors.white.withValues(alpha: 0.05),
|
|
202
|
-
borderRadius: BorderRadius.circular(24),
|
|
203
|
-
border: Border.all(
|
|
204
|
-
color: isSelected ? color : Colors.white.withValues(alpha: 0.1),
|
|
205
|
-
width: isSelected ? 2 : 1,
|
|
70
|
+
).animate().fadeIn(duration: 600.ms, delay: 200.ms),
|
|
71
|
+
footer: Row(
|
|
72
|
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
73
|
+
children: <Widget>[
|
|
74
|
+
OnboardingGhostButton(
|
|
75
|
+
label: 'Skip for now',
|
|
76
|
+
onPressed: widget.onNext,
|
|
206
77
|
),
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
78
|
+
Wrap(
|
|
79
|
+
spacing: 12,
|
|
80
|
+
runSpacing: 12,
|
|
81
|
+
children: <Widget>[
|
|
82
|
+
if (_selectedPlatform != null)
|
|
83
|
+
OnboardingGhostButton(
|
|
84
|
+
label: 'Configure',
|
|
85
|
+
icon: Icons.settings_rounded,
|
|
86
|
+
onPressed: () async {
|
|
87
|
+
try {
|
|
88
|
+
await openMessagingConfig(
|
|
89
|
+
context,
|
|
90
|
+
widget.controller,
|
|
91
|
+
_selectedPlatform!,
|
|
92
|
+
);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
if (context.mounted) {
|
|
95
|
+
ScaffoldMessenger.of(context).showSnackBar(
|
|
96
|
+
SnackBar(content: Text('Failed to connect: $e')),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
),
|
|
102
|
+
OnboardingPrimaryButton(
|
|
103
|
+
label: _selectedPlatform == null ? 'Continue' : 'Next',
|
|
104
|
+
icon: Icons.arrow_forward_rounded,
|
|
105
|
+
onPressed: widget.onNext,
|
|
222
106
|
),
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
107
|
+
],
|
|
108
|
+
),
|
|
109
|
+
],
|
|
110
|
+
),
|
|
111
|
+
child: ListView.separated(
|
|
112
|
+
itemCount: platforms.length + 1,
|
|
113
|
+
separatorBuilder: (_, __) => const SizedBox(height: 14),
|
|
114
|
+
itemBuilder: (context, index) {
|
|
115
|
+
if (index == platforms.length) {
|
|
116
|
+
return Padding(
|
|
117
|
+
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
|
118
|
+
child: Text(
|
|
119
|
+
'More providers stay available later in Settings.',
|
|
120
|
+
style: TextStyle(
|
|
121
|
+
color: Colors.white.withValues(alpha: 0.52),
|
|
122
|
+
fontSize: 14,
|
|
123
|
+
fontWeight: FontWeight.w600,
|
|
124
|
+
),
|
|
227
125
|
),
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
final platform = platforms[index];
|
|
130
|
+
final selected = _selectedPlatform?.id == platform.id;
|
|
131
|
+
return OnboardingOptionCard(
|
|
132
|
+
selected: selected,
|
|
133
|
+
accent: platform.accent,
|
|
134
|
+
onTap: () => setState(() => _selectedPlatform = platform),
|
|
135
|
+
child: Row(
|
|
136
|
+
children: <Widget>[
|
|
137
|
+
Container(
|
|
138
|
+
width: 58,
|
|
139
|
+
height: 58,
|
|
140
|
+
decoration: BoxDecoration(
|
|
141
|
+
color: platform.accent.withValues(alpha: 0.18),
|
|
142
|
+
borderRadius: BorderRadius.circular(18),
|
|
143
|
+
),
|
|
144
|
+
child: Icon(
|
|
145
|
+
platform.icon,
|
|
146
|
+
color: platform.accent,
|
|
147
|
+
size: 30,
|
|
148
|
+
),
|
|
241
149
|
),
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
150
|
+
const SizedBox(width: 18),
|
|
151
|
+
Expanded(
|
|
152
|
+
child: Column(
|
|
153
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
154
|
+
children: <Widget>[
|
|
155
|
+
Text(
|
|
156
|
+
platform.label,
|
|
157
|
+
style: const TextStyle(
|
|
158
|
+
color: Colors.white,
|
|
159
|
+
fontSize: 20,
|
|
160
|
+
fontWeight: FontWeight.w800,
|
|
161
|
+
),
|
|
162
|
+
),
|
|
163
|
+
const SizedBox(height: 5),
|
|
164
|
+
Text(
|
|
165
|
+
platform.subtitle,
|
|
166
|
+
style: TextStyle(
|
|
167
|
+
color: Colors.white.withValues(alpha: 0.68),
|
|
168
|
+
fontSize: 14,
|
|
169
|
+
height: 1.45,
|
|
170
|
+
),
|
|
171
|
+
),
|
|
172
|
+
],
|
|
173
|
+
),
|
|
249
174
|
),
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
175
|
+
AnimatedSwitcher(
|
|
176
|
+
duration: const Duration(milliseconds: 220),
|
|
177
|
+
child: selected
|
|
178
|
+
? Icon(
|
|
179
|
+
Icons.check_circle_rounded,
|
|
180
|
+
key: ValueKey<String>(platform.id),
|
|
181
|
+
color: platform.accent,
|
|
182
|
+
size: 28,
|
|
183
|
+
)
|
|
184
|
+
: Icon(
|
|
185
|
+
Icons.add_circle_outline_rounded,
|
|
186
|
+
key: ValueKey<String>('idle-${platform.id}'),
|
|
187
|
+
color: Colors.white.withValues(alpha: 0.26),
|
|
188
|
+
size: 28,
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
],
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
.animate()
|
|
195
|
+
.fadeIn(duration: 420.ms, delay: (180 + (index * 80)).ms)
|
|
196
|
+
.slideY(begin: 0.16, end: 0);
|
|
197
|
+
},
|
|
259
198
|
),
|
|
260
199
|
);
|
|
261
200
|
}
|