neoagent 2.3.1-beta.57 → 2.3.1-beta.59
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 +125 -230
- package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +183 -248
- package/flutter_app/lib/features/onboarding/onboarding_shell.dart +3 -5
- package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +140 -107
- package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +32 -150
- 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_settings.dart +16 -77
- package/flutter_app/lib/main_shared.dart +1 -0
- 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 +75022 -74341
|
@@ -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,133 @@ class _OnboardingMessagingStepState extends State<OnboardingMessagingStep> {
|
|
|
22
24
|
|
|
23
25
|
@override
|
|
24
26
|
Widget build(BuildContext context) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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 a\nmessaging platform.',
|
|
36
|
+
description: 'Choose one to get started now. You can add more later.',
|
|
37
|
+
footer: Row(
|
|
38
|
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
39
|
+
children: <Widget>[
|
|
40
|
+
OnboardingGhostButton(
|
|
41
|
+
label: 'Skip for now',
|
|
42
|
+
onPressed: widget.onNext,
|
|
43
|
+
),
|
|
44
|
+
Wrap(
|
|
45
|
+
spacing: 12,
|
|
46
|
+
runSpacing: 12,
|
|
47
|
+
children: <Widget>[
|
|
48
|
+
if (_selectedPlatform != null)
|
|
49
|
+
OnboardingGhostButton(
|
|
50
|
+
label: 'Configure',
|
|
51
|
+
icon: Icons.settings_rounded,
|
|
52
|
+
onPressed: () async {
|
|
53
|
+
try {
|
|
54
|
+
await openMessagingConfig(
|
|
55
|
+
context,
|
|
56
|
+
widget.controller,
|
|
57
|
+
_selectedPlatform!,
|
|
58
|
+
);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
if (context.mounted) {
|
|
61
|
+
ScaffoldMessenger.of(context).showSnackBar(
|
|
62
|
+
SnackBar(content: Text('Failed to connect: $e')),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
),
|
|
68
|
+
OnboardingPrimaryButton(
|
|
69
|
+
label: _selectedPlatform == null ? 'Continue' : 'Next',
|
|
70
|
+
icon: Icons.arrow_forward_rounded,
|
|
71
|
+
onPressed: widget.onNext,
|
|
52
72
|
),
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
],
|
|
76
|
+
),
|
|
77
|
+
child: ListView.separated(
|
|
78
|
+
itemCount: platforms.length + 1,
|
|
79
|
+
separatorBuilder: (_, __) => const SizedBox(height: 14),
|
|
80
|
+
itemBuilder: (context, index) {
|
|
81
|
+
if (index == platforms.length) {
|
|
82
|
+
return const SizedBox.shrink();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
final platform = platforms[index];
|
|
86
|
+
final selected = _selectedPlatform?.id == platform.id;
|
|
87
|
+
return OnboardingOptionCard(
|
|
88
|
+
selected: selected,
|
|
89
|
+
accent: platform.accent,
|
|
90
|
+
onTap: () => setState(() => _selectedPlatform = platform),
|
|
91
|
+
child: Row(
|
|
92
|
+
children: <Widget>[
|
|
93
|
+
Container(
|
|
94
|
+
width: 58,
|
|
95
|
+
height: 58,
|
|
96
|
+
decoration: BoxDecoration(
|
|
97
|
+
color: platform.accent.withValues(alpha: 0.18),
|
|
98
|
+
borderRadius: BorderRadius.circular(18),
|
|
77
99
|
),
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
),
|
|
98
|
-
|
|
99
|
-
// Bottom Action
|
|
100
|
-
Row(
|
|
101
|
-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
102
|
-
children: <Widget>[
|
|
103
|
-
TextButton(
|
|
104
|
-
onPressed: widget.onNext,
|
|
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,
|
|
100
|
+
child: Icon(
|
|
101
|
+
platform.icon,
|
|
102
|
+
color: platform.accent,
|
|
103
|
+
size: 30,
|
|
158
104
|
),
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
105
|
+
),
|
|
106
|
+
const SizedBox(width: 18),
|
|
107
|
+
Expanded(
|
|
108
|
+
child: Column(
|
|
109
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
110
|
+
children: <Widget>[
|
|
111
|
+
Text(
|
|
112
|
+
platform.label,
|
|
113
|
+
style: const TextStyle(
|
|
114
|
+
color: Colors.white,
|
|
115
|
+
fontSize: 20,
|
|
116
|
+
fontWeight: FontWeight.w800,
|
|
117
|
+
),
|
|
118
|
+
),
|
|
119
|
+
const SizedBox(height: 5),
|
|
120
|
+
Text(
|
|
121
|
+
platform.subtitle,
|
|
122
|
+
style: TextStyle(
|
|
123
|
+
color: Colors.white.withValues(alpha: 0.68),
|
|
124
|
+
fontSize: 14,
|
|
125
|
+
height: 1.45,
|
|
126
|
+
),
|
|
127
|
+
),
|
|
128
|
+
],
|
|
163
129
|
),
|
|
164
|
-
).animate().fadeIn(delay: 800.ms),
|
|
165
|
-
],
|
|
166
|
-
),
|
|
167
|
-
],
|
|
168
|
-
),
|
|
169
|
-
],
|
|
170
|
-
),
|
|
171
|
-
),
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
class _PlatformCard extends StatelessWidget {
|
|
177
|
-
const _PlatformCard({
|
|
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,
|
|
206
|
-
),
|
|
207
|
-
boxShadow: isSelected ? [
|
|
208
|
-
BoxShadow(
|
|
209
|
-
color: color.withValues(alpha: 0.2),
|
|
210
|
-
blurRadius: 20,
|
|
211
|
-
offset: const Offset(0, 8),
|
|
212
|
-
)
|
|
213
|
-
] : [],
|
|
214
|
-
),
|
|
215
|
-
child: Row(
|
|
216
|
-
children: <Widget>[
|
|
217
|
-
Container(
|
|
218
|
-
padding: const EdgeInsets.all(12),
|
|
219
|
-
decoration: BoxDecoration(
|
|
220
|
-
color: color.withValues(alpha: 0.2),
|
|
221
|
-
shape: BoxShape.circle,
|
|
222
|
-
),
|
|
223
|
-
child: Icon(
|
|
224
|
-
platform.icon,
|
|
225
|
-
color: color,
|
|
226
|
-
size: 32,
|
|
227
|
-
),
|
|
228
|
-
),
|
|
229
|
-
const SizedBox(width: 20),
|
|
230
|
-
Expanded(
|
|
231
|
-
child: Column(
|
|
232
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
233
|
-
mainAxisSize: MainAxisSize.min,
|
|
234
|
-
children: [
|
|
235
|
-
Text(
|
|
236
|
-
platform.label,
|
|
237
|
-
style: const TextStyle(
|
|
238
|
-
fontSize: 22,
|
|
239
|
-
fontWeight: FontWeight.w600,
|
|
240
|
-
color: Colors.white,
|
|
241
130
|
),
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
131
|
+
AnimatedSwitcher(
|
|
132
|
+
duration: const Duration(milliseconds: 220),
|
|
133
|
+
child: selected
|
|
134
|
+
? Icon(
|
|
135
|
+
Icons.check_circle_rounded,
|
|
136
|
+
key: ValueKey<String>(platform.id),
|
|
137
|
+
color: platform.accent,
|
|
138
|
+
size: 28,
|
|
139
|
+
)
|
|
140
|
+
: Icon(
|
|
141
|
+
Icons.add_circle_outline_rounded,
|
|
142
|
+
key: ValueKey<String>('idle-${platform.id}'),
|
|
143
|
+
color: Colors.white.withValues(alpha: 0.26),
|
|
144
|
+
size: 28,
|
|
145
|
+
),
|
|
249
146
|
),
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
],
|
|
258
|
-
),
|
|
147
|
+
],
|
|
148
|
+
),
|
|
149
|
+
)
|
|
150
|
+
.animate()
|
|
151
|
+
.fadeIn(duration: 420.ms, delay: (180 + (index * 80)).ms)
|
|
152
|
+
.slideY(begin: 0.16, end: 0);
|
|
153
|
+
},
|
|
259
154
|
),
|
|
260
155
|
);
|
|
261
156
|
}
|