77 files changed
+701
-622
lib/bootstrap/bootstrap_screen.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_localizations/flutter_localizations.dart';
4
import 'package:loading_animation_widget/loading_animation_widget.dart';
@@ -104,7 +105,7 @@ class BootstrapScreen extends StatelessWidget {
105
),
106
),
107
] else ...[
107
- Icon(Icons.error_outline, size: 40, color: AppColors.error),
108
+ HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle, size: 40, color: AppColors.error),
109
const SizedBox(height: 16),
110
Text(
111
l10n.something_went_wrong,
@@ -131,7 +132,7 @@ class BootstrapScreen extends StatelessWidget {
132
if (onRetry != null)
133
ElevatedButton.icon(
134
onPressed: onRetry,
134
- icon: const Icon(Icons.refresh, size: 18),
135
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh, size: 18),
136
label: Text(l10n.retry),
137
),
138
],
@@ -145,4 +146,4 @@ class BootstrapScreen extends StatelessWidget {
146
}),
147
);
148
}
148
-}
149
+}
\ No newline at end of file
lib/core/components/app_button.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
4
import '../theme/colors.dart';
@@ -17,7 +18,7 @@ class AppButton extends StatelessWidget {
18
19
final String label;
20
final VoidCallback? onPressed;
20
- final IconData? icon;
21
+ final List<List<dynamic>>? icon;
22
final AppButtonVariant variant;
23
final bool isLoading;
24
final bool isFullWidth;
@@ -48,7 +49,7 @@ class AppButton extends StatelessWidget {
49
mainAxisSize: MainAxisSize.min,
50
children: [
51
if (icon != null) ...[
51
- Icon(icon, size: 18),
52
+ HugeIcon(icon: icon!, size: 18),
53
const SizedBox(width: AppSizes.sm),
54
],
55
Text(label),
@@ -161,4 +162,4 @@ class AppLoadingIndicator extends StatelessWidget {
162
),
163
);
164
}
164
-}
165
+}
\ No newline at end of file
lib/core/components/folder_filter_bar.dart
+10
-9
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/l10n/app_localizations.dart';
4
@@ -44,7 +45,7 @@ class FolderFilterBar extends StatelessWidget {
45
children: [
46
SystemFolderFilterChip(
47
label: l10n.all_chats,
47
- icon: Icons.view_list_rounded,
48
+ icon: HugeIcons.strokeRoundedView,
49
selected: selectedFolderId == null,
50
isDark: isDark,
51
onSelected: (_) => onFilterChanged(null),
@@ -52,7 +53,7 @@ class FolderFilterBar extends StatelessWidget {
53
const SizedBox(width: 6),
54
SystemFolderFilterChip(
55
label: l10n.unfiled_chats,
55
- icon: Icons.inbox_outlined,
56
+ icon: HugeIcons.strokeRoundedInbox,
57
selected: selectedFolderId != null && selectedFolderId!.isEmpty,
58
isDark: isDark,
59
outlined: true,
@@ -62,8 +63,8 @@ class FolderFilterBar extends StatelessWidget {
63
(folder) => Padding(
64
padding: const EdgeInsets.only(left: 6),
65
child: FilterChip(
65
- avatar: Icon(
66
- Icons.folder_outlined,
66
+ avatar: HugeIcon(icon:
67
+ HugeIcons.strokeRoundedFolder01,
68
size: 16,
69
color: selectedFolderId == folder.id
70
? theme.colorScheme.onSecondaryContainer
@@ -79,8 +80,8 @@ class FolderFilterBar extends StatelessWidget {
80
if (showCreateFolder) ...[
81
const SizedBox(width: 6),
82
ActionChip(
82
- avatar: Icon(
83
- Icons.create_new_folder_outlined,
83
+ avatar: HugeIcon(icon:
84
+ HugeIcons.strokeRoundedFolderAdd,
85
size: 16,
86
color: theme.colorScheme.primary,
87
),
@@ -110,7 +111,7 @@ class SystemFolderFilterChip extends StatelessWidget {
111
});
112
113
final String label;
113
- final IconData icon;
114
+ final List<List<dynamic>> icon;
115
final bool selected;
116
final bool isDark;
117
final bool outlined;
@@ -131,7 +132,7 @@ class SystemFolderFilterChip extends StatelessWidget {
132
: (isDark ? const Color(0xFF333333) : const Color(0xFFE0E0E0)));
133
134
return FilterChip(
134
- avatar: Icon(
135
+ avatar: HugeIcon(icon:
136
icon,
137
size: 16,
138
color: selected
@@ -152,4 +153,4 @@ class SystemFolderFilterChip extends StatelessWidget {
153
onSelected: onSelected,
154
);
155
}
155
-}
156
+}
\ No newline at end of file
lib/core/components/list_filter_button.dart
+10
-9
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
4
class ListFilterOption<T> {
@@ -9,7 +10,7 @@ class ListFilterOption<T> {
10
11
final T value;
12
final String label;
12
- final IconData? icon;
13
+ final List<List<dynamic>>? icon;
14
}
15
16
class ListFilterButton<T> extends StatelessWidget {
@@ -19,7 +20,7 @@ class ListFilterButton<T> extends StatelessWidget {
20
required this.selected,
21
required this.onChanged,
22
this.tooltip,
22
- this.icon = Icons.filter_list_rounded,
23
+ this.icon = HugeIcons.strokeRoundedFilterHorizontal,
24
this.showBadgeWhenNotDefault = true,
25
});
26
@@ -27,7 +28,7 @@ class ListFilterButton<T> extends StatelessWidget {
28
final T selected;
29
final ValueChanged<T> onChanged;
30
final String? tooltip;
30
- final IconData icon;
31
+ final List<List<dynamic>> icon;
32
final bool showBadgeWhenNotDefault;
33
34
bool get _hasActiveFilter {
@@ -45,7 +46,7 @@ class ListFilterButton<T> extends StatelessWidget {
46
icon: Badge(
47
isLabelVisible: _hasActiveFilter,
48
smallSize: 8,
48
- child: Icon(
49
+ child: HugeIcon(icon:
50
icon,
51
color: _hasActiveFilter
52
? theme.colorScheme.primary
@@ -67,8 +68,8 @@ class ListFilterButton<T> extends StatelessWidget {
68
...options.map(
69
(option) => ListTile(
70
leading: option.icon != null
70
- ? Icon(
71
- option.icon,
71
+ ? HugeIcon(icon:
72
+ option.icon!,
73
color: selected == option.value
74
? Theme.of(ctx).colorScheme.primary
75
: null,
@@ -76,8 +77,8 @@ class ListFilterButton<T> extends StatelessWidget {
77
: null,
78
title: Text(option.label),
79
trailing: selected == option.value
79
- ? Icon(
80
- Icons.check,
80
+ ? HugeIcon(icon:
81
+ HugeIcons.strokeRoundedTick01,
82
color: Theme.of(ctx).colorScheme.primary,
83
)
84
: null,
@@ -94,4 +95,4 @@ class ListFilterButton<T> extends StatelessWidget {
95
},
96
);
97
}
97
-}
98
+}
\ No newline at end of file
lib/features/chat/views/components/audio_player_widget.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:async';
3
4
import 'package:audioplayers/audioplayers.dart';
@@ -95,8 +96,8 @@ class _AudioPlayerWidgetState extends State<AudioPlayerWidget> {
96
mainAxisSize: MainAxisSize.min,
97
children: [
98
IconButton(
98
- icon: Icon(
99
- _state == PlayerState.playing ? Icons.pause_circle_filled : Icons.play_circle_filled,
99
+ icon: HugeIcon(icon:
100
+ _state == PlayerState.playing ? HugeIcons.strokeRoundedPauseCircle : HugeIcons.strokeRoundedPlayCircle,
101
size: 28,
102
color: isDark ? Colors.white : Colors.black87,
103
),
@@ -164,4 +165,4 @@ class _AudioPlayerWidgetState extends State<AudioPlayerWidget> {
165
),
166
);
167
}
167
-}
168
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/assistant_bubble.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:async';
3
import 'package:flutter/material.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -141,7 +142,7 @@ class AssistantBubble extends StatelessWidget {
142
),
143
if (message.status == MessageStatus.error) ...[
144
const SizedBox(width: 4),
144
- Icon(Icons.error_outline, size: 14, color: Colors.red[400]),
145
+ HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle, size: 14, color: Colors.red[400]),
146
],
147
const Spacer(),
148
if (!isStreaming)
@@ -310,4 +311,4 @@ String _formatTime(DateTime dateTime) {
311
final hour = dateTime.hour.toString().padLeft(2, '0');
312
final minute = dateTime.minute.toString().padLeft(2, '0');
313
return '$hour:$minute';
313
-}
314
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/attachment_list.dart
+8
-7
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:io';
3
import 'package:flutter/material.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -91,8 +92,8 @@ class _AttachmentItem extends StatelessWidget {
92
child: Row(
93
mainAxisSize: MainAxisSize.min,
94
children: [
94
- Icon(
95
- Icons.description_outlined,
95
+ HugeIcon(icon:
96
+ HugeIcons.strokeRoundedFile01,
97
size: 20,
98
color: theme.colorScheme.primary,
99
),
@@ -138,8 +139,8 @@ class _AttachmentItem extends StatelessWidget {
139
child: Row(
140
mainAxisSize: MainAxisSize.min,
141
children: [
141
- Icon(
142
- Icons.insert_drive_file_outlined,
142
+ HugeIcon(icon:
143
+ HugeIcons.strokeRoundedFile01,
144
size: 20,
145
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
146
),
@@ -196,7 +197,7 @@ class _TextPreviewSheet extends StatelessWidget {
197
padding: const EdgeInsets.all(16),
198
child: Row(
199
children: [
199
- Icon(Icons.description_outlined, color: theme.colorScheme.primary),
200
+ HugeIcon(icon: HugeIcons.strokeRoundedFile01, color: theme.colorScheme.primary),
201
const SizedBox(width: 8),
202
Expanded(
203
child: Text(
@@ -209,7 +210,7 @@ class _TextPreviewSheet extends StatelessWidget {
210
),
211
),
212
IconButton(
212
- icon: const Icon(Icons.close),
213
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
214
onPressed: () => Navigator.pop(context),
215
),
216
],
@@ -262,4 +263,4 @@ class _FilePlaceholder extends StatelessWidget {
263
),
264
);
265
}
265
-}
266
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/markdown/themed_gpt_markdown.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:gpt_markdown/gpt_markdown.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -119,7 +120,7 @@ class ThemedGptMarkdown extends StatelessWidget {
120
},
121
errorBuilder: (context, error, stackTrace) => Container(
122
color: Colors.grey[800],
122
- child: const Center(child: Icon(Icons.broken_image, color: Colors.white54)),
123
+ child: const Center(child: HugeIcon(icon: HugeIcons.strokeRoundedImageNotFound01, color: Colors.white54)),
124
),
125
),
126
);
@@ -161,4 +162,4 @@ class MarkdownBodyContent extends StatelessWidget {
162
),
163
);
164
}
164
-}
165
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/tool_bubble/tool_bubble.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/features/chat/data/models/message.dart';
@@ -39,8 +40,8 @@ class ToolBubble extends StatelessWidget {
40
children: [
41
Row(
42
children: [
42
- Icon(
43
- Icons.build_outlined,
43
+ HugeIcon(icon:
44
+ HugeIcons.strokeRoundedTools,
45
size: 14,
46
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
47
),
@@ -71,4 +72,4 @@ class ToolBubble extends StatelessWidget {
72
),
73
);
74
}
74
-}
75
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/tool_bubble/tool_row.dart
+13
-12
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/features/chat/data/tools/tool_event.dart';
@@ -98,16 +99,16 @@ class _ToolRowWidgetState extends State<ToolRowWidget> {
99
if (call.status == ToolEventStatus.running)
100
_AnimatedRunningIcon(color: iconColor)
101
else
101
- Icon(
102
+ HugeIcon(icon:
103
switch (call.status) {
104
ToolEventStatus.requested =>
104
- Icons.hourglass_empty_rounded,
105
+ HugeIcons.strokeRoundedClock01,
106
ToolEventStatus.approved =>
106
- Icons.check_circle_outline_rounded,
107
- ToolEventStatus.rejected => Icons.block_flipped,
108
- ToolEventStatus.running => Icons.cached_rounded,
109
- ToolEventStatus.completed => Icons.check_circle_rounded,
110
- ToolEventStatus.failed => Icons.error_rounded,
107
+ HugeIcons.strokeRoundedCheckmarkCircle01,
108
+ ToolEventStatus.rejected => HugeIcons.strokeRoundedUnavailable,
109
+ ToolEventStatus.running => HugeIcons.strokeRoundedRefresh,
110
+ ToolEventStatus.completed => HugeIcons.strokeRoundedCheckmarkCircle01,
111
+ ToolEventStatus.failed => HugeIcons.strokeRoundedAlertCircle,
112
},
113
size: 14,
114
color: iconColor,
@@ -186,10 +187,10 @@ class _ToolRowWidgetState extends State<ToolRowWidget> {
187
],
188
if (showCodeBlock) ...[
189
const SizedBox(width: 6),
189
- Icon(
190
+ HugeIcon(icon:
191
_isExpanded
191
- ? Icons.keyboard_arrow_up_rounded
192
- : Icons.keyboard_arrow_down_rounded,
192
+ ? HugeIcons.strokeRoundedArrowUp01
193
+ : HugeIcons.strokeRoundedArrowDown01,
194
size: 16,
195
color: isDark
196
? AppColors.darkMutedText
@@ -341,7 +342,7 @@ class _AnimatedRunningIconState extends State<_AnimatedRunningIcon>
342
Widget build(BuildContext context) {
343
return RotationTransition(
344
turns: _controller,
344
- child: Icon(Icons.cached_rounded, size: 14, color: widget.color),
345
+ child: HugeIcon(icon: HugeIcons.strokeRoundedRefresh, size: 14, color: widget.color),
346
);
347
}
347
-}
348
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/tool_bubble/tool_timeline.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:convert';
3
import 'package:flutter/material.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -106,8 +107,8 @@ class ToolTimeline extends StatelessWidget {
107
),
108
child: Row(
109
children: [
109
- Icon(
110
- Icons.terminal_rounded,
110
+ HugeIcon(icon:
111
+ HugeIcons.strokeRoundedComputerTerminal01,
112
size: 16,
113
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
114
),
@@ -169,4 +170,4 @@ class ToolTimeline extends StatelessWidget {
170
),
171
);
172
}
172
-}
173
+}
\ No newline at end of file
lib/features/chat/views/components/chat_bubble/user_bubble.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/models/enums.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -112,7 +113,7 @@ class UserBubble extends StatelessWidget {
113
),
114
if (message.status == MessageStatus.error) ...[
115
const SizedBox(width: 4),
115
- Icon(Icons.error_outline, size: 14, color: Colors.red[200]),
116
+ HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle, size: 14, color: Colors.red[200]),
117
],
118
const SizedBox(width: 8),
119
MessageActionBar(
@@ -140,4 +141,4 @@ String _formatTime(DateTime dateTime) {
141
final hour = dateTime.hour.toString().padLeft(2, '0');
142
final minute = dateTime.minute.toString().padLeft(2, '0');
143
return '$hour:$minute';
143
-}
144
+}
\ No newline at end of file
lib/features/chat/views/components/chat_input_bar.dart
+13
-13
@@ -294,7 +294,7 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
294
295
children: [
296
ListTile(
297
- leading: const Icon(Icons.description_outlined),
297
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFile01),
298
title: Text(l10n.attach_text_document),
299
onTap: () {
300
Navigator.pop(ctx);
@@ -302,7 +302,7 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
302
},
303
),
304
ListTile(
305
- leading: const Icon(Icons.image_outlined),
305
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedImage01),
306
title: Text(l10n.attach_image),
307
onTap: () {
308
Navigator.pop(ctx);
@@ -311,7 +311,7 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
311
),
312
313
ListTile(
314
- leading: const Icon(Icons.bookmark_outline),
314
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedBookmark01),
315
316
title: Text(l10n.insert_saved_message),
317
@@ -504,8 +504,8 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
504
setState(() => _sendAsAssistant = !_sendAsAssistant);
505
}
506
: null,
507
- icon: Icon(
508
- Icons.swap_horiz_rounded,
507
+ icon: HugeIcon(icon:
508
+ HugeIcons.strokeRoundedExchange01,
509
size: 20,
510
color: _sendAsAssistant
511
? theme.colorScheme.primary
@@ -566,8 +566,8 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
566
top: 6,
567
bottom: 6,
568
),
569
- child: Icon(
570
- enabled ? Icons.check_box : Icons.check_box_outline_blank,
569
+ child: HugeIcon(icon:
570
+ enabled ? HugeIcons.strokeRoundedTick01 : HugeIcons.strokeRoundedSquare01,
571
size: 18,
572
color: fgColor,
573
),
@@ -936,8 +936,8 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
936
.colorScheme
937
.surfaceContainerHighest,
938
939
- child: Icon(
940
- Icons.description_outlined,
939
+ child: HugeIcon(icon:
940
+ HugeIcons.strokeRoundedFile01,
941
942
size: 22,
943
@@ -968,8 +968,8 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
968
shape: BoxShape.circle,
969
),
970
971
- child: const Icon(
972
- Icons.close,
971
+ child: const HugeIcon(icon:
972
+ HugeIcons.strokeRoundedCancel01,
973
974
size: 10,
975
@@ -1016,8 +1016,8 @@ class ChatInputBarState extends ConsumerState<ChatInputBar>
1016
minHeight: 36,
1017
),
1018
1019
- icon: Icon(
1020
- Icons.add,
1019
+ icon: HugeIcon(icon:
1020
+ HugeIcons.strokeRoundedAdd01,
1021
1022
size: 24,
1023
lib/features/chat/views/components/chat_settings_sheet.dart
+6
-6
@@ -100,7 +100,7 @@ class _ChatSettingsSheetState extends ConsumerState<ChatSettingsSheet> {
100
if (hasOverrides)
101
ShadButton.ghost(
102
onPressed: () => _resetToDefaults(ref, activeConv?.id),
103
- leading: const Icon(Icons.restore, size: 16),
103
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh, size: 16),
104
child: Text(l10n.reset_defaults),
105
),
106
],
@@ -231,8 +231,8 @@ class _ChatSettingsSheetState extends ConsumerState<ChatSettingsSheet> {
231
),
232
child: Row(
233
children: [
234
- const Icon(
235
- Icons.warning_amber_rounded,
234
+ const HugeIcon(icon:
235
+ HugeIcons.strokeRoundedAlertCircle,
236
color: Colors.orange,
237
size: 20,
238
),
@@ -298,7 +298,7 @@ class _ChatSettingsSheetState extends ConsumerState<ChatSettingsSheet> {
298
),
299
const SizedBox(width: 8),
300
ShadIconButton(
301
- icon: const Icon(Icons.add),
301
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
302
onPressed: _addServer,
303
),
304
],
@@ -342,8 +342,8 @@ class _ChatSettingsSheetState extends ConsumerState<ChatSettingsSheet> {
342
style: const TextStyle(fontSize: 11),
343
),
344
trailing: ShadIconButton.ghost(
345
- icon: const Icon(
346
- Icons.delete_outline,
345
+ icon: const HugeIcon(icon:
346
+ HugeIcons.strokeRoundedDelete01,
347
size: 18,
348
color: Colors.red,
349
),
lib/features/chat/views/components/image_preview_dialog.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:io';
3
4
import 'package:flutter/material.dart';
@@ -23,7 +24,7 @@ class _ImagePreviewDialog extends StatelessWidget {
24
backgroundColor: Colors.transparent,
25
elevation: 0,
26
leading: IconButton(
26
- icon: const Icon(Icons.close, color: Colors.white),
27
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, color: Colors.white),
28
onPressed: () => Navigator.pop(context),
29
),
30
),
@@ -36,4 +37,4 @@ class _ImagePreviewDialog extends StatelessWidget {
37
),
38
);
39
}
39
-}
40
+}
\ No newline at end of file
lib/features/chat/views/components/message_action_bar.dart
+25
-24
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter/services.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -106,7 +107,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
107
mainAxisSize: MainAxisSize.min,
108
children: [
109
_ActionButton(
109
- icon: Icons.copy,
110
+ icon: HugeIcons.strokeRoundedCopy,
111
label: l10n.copy,
112
onTap: () async {
113
await Clipboard.setData(ClipboardData(text: widget.content));
@@ -124,7 +125,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
125
if (widget.onSave != null) ...[
126
const SizedBox(width: 4),
127
_ActionButton(
127
- icon: isSaved ? Icons.bookmark : Icons.bookmark_border,
128
+ icon: isSaved ? HugeIcons.strokeRoundedBookmark01 : HugeIcons.strokeRoundedBookmark01,
129
label: isSaved ? l10n.message_already_saved : l10n.save_message,
130
onTap: widget.onSave,
131
isActive: isSaved,
@@ -133,7 +134,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
134
if (widget.onRetry != null) ...[
135
const SizedBox(width: 4),
136
_ActionButton(
136
- icon: Icons.refresh,
137
+ icon: HugeIcons.strokeRoundedRefresh,
138
label: l10n.retry,
139
onTap: widget.onRetry,
140
),
@@ -141,19 +142,19 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
142
if (widget.onContinue != null) ...[
143
const SizedBox(width: 4),
144
_ActionButton(
144
- icon: Icons.arrow_forward,
145
+ icon: HugeIcons.strokeRoundedArrowRight01,
146
label: l10n.continue_action,
147
onTap: widget.onContinue,
148
),
149
],
150
if (widget.onEdit != null) ...[
151
const SizedBox(width: 4),
151
- _ActionButton(icon: Icons.edit, label: l10n.edit, onTap: widget.onEdit),
152
+ _ActionButton(icon: HugeIcons.strokeRoundedPencilEdit02, label: l10n.edit, onTap: widget.onEdit),
153
],
154
if (widget.onDelete != null) ...[
155
const SizedBox(width: 4),
156
_ActionButton(
156
- icon: Icons.delete_outline,
157
+ icon: HugeIcons.strokeRoundedDelete01,
158
label: l10n.delete,
159
onTap: () => _showDeleteConfirmation(context),
160
isDestructive: true,
@@ -162,7 +163,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
163
if (widget.onShare != null) ...[
164
const SizedBox(width: 4),
165
_ActionButton(
165
- icon: Icons.ios_share,
166
+ icon: HugeIcons.strokeRoundedShare01,
167
label: l10n.share,
168
onTap: widget.onShare,
169
),
@@ -171,9 +172,9 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
172
_ActionButton(
173
icon: isThisActive
174
? (isThisPlaying
174
- ? Icons.pause_circle_filled
175
- : Icons.play_circle_filled)
176
- : (isThisInitializing ? Icons.hourglass_top : Icons.volume_up),
175
+ ? HugeIcons.strokeRoundedPauseCircle
176
+ : HugeIcons.strokeRoundedPlayCircle)
177
+ : (isThisInitializing ? HugeIcons.strokeRoundedClock01 : HugeIcons.strokeRoundedVolumeUp),
178
label: isThisActive
179
? (isThisPlaying ? l10n.pause : l10n.resume)
180
: (isThisInitializing ? l10n.initializing : l10n.read_aloud),
@@ -181,7 +182,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
182
),
183
const SizedBox(width: 4),
184
_ActionButton(
184
- icon: Icons.more_horiz,
185
+ icon: HugeIcons.strokeRoundedMoreHorizontal,
186
label: l10n.more,
187
onTap: () => _showMoreOptions(context, isSaved),
188
),
@@ -280,7 +281,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
281
),
282
),
283
_CompactOptionTile(
283
- icon: Icons.code,
284
+ icon: HugeIcons.strokeRoundedCode,
285
label: sheetL10n.copy_markdown,
286
onTap: () {
287
Navigator.pop(ctx);
@@ -292,7 +293,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
293
),
294
if (widget.messageId != null)
295
_CompactOptionTile(
295
- icon: Icons.checklist_outlined,
296
+ icon: HugeIcons.strokeRoundedCheckList,
297
label: sheetL10n.select,
298
onTap: () {
299
Navigator.pop(ctx);
@@ -305,9 +306,9 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
306
_CompactOptionTile(
307
icon: isThisActive
308
? (isThisPlaying
308
- ? Icons.pause_circle_filled
309
- : Icons.play_circle_filled)
310
- : Icons.volume_up,
309
+ ? HugeIcons.strokeRoundedPauseCircle
310
+ : HugeIcons.strokeRoundedPlayCircle)
311
+ : HugeIcons.strokeRoundedVolumeUp,
312
label: isThisActive
313
? (isThisPlaying ? sheetL10n.pause : sheetL10n.resume)
314
: sheetL10n.read_aloud,
@@ -318,7 +319,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
319
),
320
if (widget.onShare != null)
321
_CompactOptionTile(
321
- icon: Icons.ios_share,
322
+ icon: HugeIcons.strokeRoundedShare01,
323
label: sheetL10n.share,
324
onTap: () {
325
Navigator.pop(ctx);
@@ -327,7 +328,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
328
),
329
if (widget.onBranch != null)
330
_CompactOptionTile(
330
- icon: Icons.call_split,
331
+ icon: HugeIcons.strokeRoundedGitBranch,
332
label: sheetL10n.branch_chat,
333
onTap: () {
334
Navigator.pop(ctx);
@@ -336,7 +337,7 @@ class _MessageActionBarState extends ConsumerState<MessageActionBar> {
337
),
338
if (widget.onSave != null)
339
_CompactOptionTile(
339
- icon: isSaved ? Icons.bookmark : Icons.bookmark_outline,
340
+ icon: isSaved ? HugeIcons.strokeRoundedBookmark01 : HugeIcons.strokeRoundedBookmark01,
341
label: isSaved
342
? sheetL10n.message_already_saved
343
: sheetL10n.save_message,
@@ -415,7 +416,7 @@ class _CompactOptionTile extends StatelessWidget {
416
required this.onTap,
417
});
418
418
- final IconData icon;
419
+ final List<List<dynamic>> icon;
420
final String label;
421
final VoidCallback onTap;
422
@@ -425,7 +426,7 @@ class _CompactOptionTile extends StatelessWidget {
426
dense: true,
427
visualDensity: VisualDensity.compact,
428
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
428
- leading: Icon(icon, size: 20),
429
+ leading: HugeIcon(icon: icon, size: 20),
430
title: Text(label, style: const TextStyle(fontSize: 14)),
431
onTap: onTap,
432
);
@@ -441,7 +442,7 @@ class _ActionButton extends StatefulWidget {
442
this.isActive = false,
443
});
444
444
- final IconData icon;
445
+ final List<List<dynamic>> icon;
446
final String label;
447
final VoidCallback? onTap;
448
final bool isDestructive;
@@ -519,7 +520,7 @@ class _ActionButtonState extends State<_ActionButton>
520
: Colors.transparent,
521
borderRadius: BorderRadius.circular(4),
522
),
522
- child: Icon(
523
+ child: HugeIcon(icon:
524
widget.icon,
525
size: 16,
526
color: _isHovered ? hoverColor : baseColor,
@@ -530,4 +531,4 @@ class _ActionButtonState extends State<_ActionButton>
531
),
532
);
533
}
533
-}
534
+}
\ No newline at end of file
lib/features/chat/views/components/message_list/corrupted_state.dart
+5
-4
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter/services.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -122,8 +123,8 @@ Error: $errorMessage
123
color: Colors.red.withValues(alpha: 0.1),
124
shape: BoxShape.circle,
125
),
125
- child: const Icon(
126
- Icons.history_toggle_off_rounded,
126
+ child: const HugeIcon(icon:
127
+ HugeIcons.strokeRoundedClock01,
128
size: 48,
129
color: Colors.red,
130
),
@@ -152,7 +153,7 @@ Error: $errorMessage
153
children: [
154
ShadButton(
155
onPressed: onStartNewChat,
155
- leading: const Icon(Icons.add_rounded, size: 20),
156
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01, size: 20),
157
child: Text(l10n.start_new_chat),
158
),
159
const SizedBox(width: 12),
@@ -167,4 +168,4 @@ Error: $errorMessage
168
),
169
);
170
}
170
-}
171
+}
\ No newline at end of file
lib/features/chat/views/components/message_list/empty_state.dart
+6
-5
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:async';
3
4
import 'package:flutter/material.dart';
@@ -172,7 +173,7 @@ class _EmptyStateState extends State<EmptyState>
173
child: Row(
174
mainAxisSize: MainAxisSize.min,
175
children: [
175
- Icon(Icons.settings_suggest,
176
+ HugeIcon(icon: HugeIcons.strokeRoundedSettings01,
177
size: 18, color: theme.colorScheme.primary),
178
const SizedBox(width: 8),
179
Flexible(
@@ -188,7 +189,7 @@ class _EmptyStateState extends State<EmptyState>
189
),
190
),
191
const SizedBox(width: 4),
191
- const Icon(Icons.expand_more, size: 16, color: Colors.grey),
192
+ const HugeIcon(icon: HugeIcons.strokeRoundedArrowDown01, size: 16, color: Colors.grey),
193
],
194
),
195
),
@@ -224,7 +225,7 @@ class _EmptyStateState extends State<EmptyState>
225
),
226
),
227
] else ...[
227
- Icon(Icons.smart_toy_outlined,
228
+ HugeIcon(icon: HugeIcons.strokeRoundedRobot01,
229
size: 18, color: theme.colorScheme.primary),
230
const SizedBox(width: 8),
231
Flexible(
@@ -241,7 +242,7 @@ class _EmptyStateState extends State<EmptyState>
242
),
243
],
244
const SizedBox(width: 4),
244
- const Icon(Icons.expand_more, size: 16, color: Colors.grey),
245
+ const HugeIcon(icon: HugeIcons.strokeRoundedArrowDown01, size: 16, color: Colors.grey),
246
],
247
),
248
),
@@ -363,4 +364,4 @@ class _EmptyStateState extends State<EmptyState>
364
],
365
);
366
}
366
-}
367
+}
\ No newline at end of file
lib/features/chat/views/components/message_list/message_list.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/core/models/enums.dart';
@@ -353,7 +354,7 @@ class _MessageList extends ConsumerWidget {
354
alignment: Alignment.centerLeft,
355
child: OutlinedButton.icon(
356
onPressed: onGenerateResponse,
356
- icon: const Icon(Icons.auto_awesome, size: 16),
357
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedSparkles, size: 16),
358
label: Text(
359
AppLocalizations.of(context)!.generate_ai_response,
360
),
@@ -365,4 +366,4 @@ class _MessageList extends ConsumerWidget {
366
},
367
);
368
}
368
-}
369
+}
\ No newline at end of file
lib/features/chat/views/components/message_list/recent_conversation_item.dart
+7
-6
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -29,8 +30,8 @@ class RecentConversationItem extends ConsumerWidget {
30
),
31
child: Row(
32
children: [
32
- Icon(
33
- Icons.chat_bubble_outline,
33
+ HugeIcon(icon:
34
+ HugeIcons.strokeRoundedChatting01,
35
size: 18,
36
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
37
),
@@ -62,10 +63,10 @@ class RecentConversationItem extends ConsumerWidget {
63
],
64
),
65
),
65
- Icon(
66
+ HugeIcon(icon:
67
Directionality.of(context) == TextDirection.rtl
67
- ? Icons.chevron_left
68
- : Icons.chevron_right,
68
+ ? HugeIcons.strokeRoundedArrowLeft01
69
+ : HugeIcons.strokeRoundedArrowRight01,
70
size: 18,
71
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
72
),
@@ -74,4 +75,4 @@ class RecentConversationItem extends ConsumerWidget {
75
),
76
);
77
}
77
-}
78
+}
\ No newline at end of file
lib/features/chat/views/components/message_variant_navigator.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/features/chat/data/models/message.dart';
@@ -35,7 +36,7 @@ class MessageVariantNavigator extends StatelessWidget {
36
padding: EdgeInsets.zero,
37
constraints: const BoxConstraints(minWidth: 28, minHeight: 28),
38
onPressed: currentIndex > 0 ? () => onCycle(-1) : null,
38
- icon: Icon(Icons.chevron_left, size: 18, color: muted),
39
+ icon: HugeIcon(icon: HugeIcons.strokeRoundedArrowLeft01, size: 18, color: muted),
40
),
41
Text(
42
'${currentIndex + 1} / ${variants.length}',
@@ -51,10 +52,10 @@ class MessageVariantNavigator extends StatelessWidget {
52
constraints: const BoxConstraints(minWidth: 28, minHeight: 28),
53
onPressed:
54
currentIndex < variants.length - 1 ? () => onCycle(1) : null,
54
- icon: Icon(Icons.chevron_right, size: 18, color: muted),
55
+ icon: HugeIcon(icon: HugeIcons.strokeRoundedArrowRight01, size: 18, color: muted),
56
),
57
],
58
),
59
);
60
}
60
-}
61
+}
\ No newline at end of file
lib/features/chat/views/components/model_info_sheet.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter/services.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -69,7 +70,7 @@ class _ModelInfoRow extends StatelessWidget {
70
title: Text(label, style: const TextStyle(fontSize: 12)),
71
subtitle: SelectableText(value),
72
trailing: IconButton(
72
- icon: const Icon(Icons.copy, size: 18),
73
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCopy, size: 18),
74
tooltip: l10n.copy,
75
onPressed: () async {
76
await Clipboard.setData(ClipboardData(text: value));
@@ -82,4 +83,4 @@ class _ModelInfoRow extends StatelessWidget {
83
),
84
);
85
}
85
-}
86
+}
\ No newline at end of file
lib/features/chat/views/components/reasoning_widget.dart
+6
-5
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:gpt_markdown/gpt_markdown.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -123,8 +124,8 @@ class _ReasoningWidgetState extends State<ReasoningWidget>
124
),
125
child: Row(
126
children: [
126
- Icon(
127
- Icons.psychology_outlined,
127
+ HugeIcon(icon:
128
+ HugeIcons.strokeRoundedBrain,
129
size: 18,
130
color: isDark
131
? AppColors.darkMutedText
@@ -159,8 +160,8 @@ class _ReasoningWidgetState extends State<ReasoningWidget>
160
begin: 0.0,
161
end: 0.5,
162
).animate(_expandAnimation),
162
- child: Icon(
163
- Icons.keyboard_arrow_down_rounded,
163
+ child: HugeIcon(icon:
164
+ HugeIcons.strokeRoundedArrowDown01,
165
size: 18,
166
color: isDark
167
? AppColors.darkMutedText
@@ -203,4 +204,4 @@ class _ReasoningWidgetState extends State<ReasoningWidget>
204
),
205
);
206
}
206
-}
207
+}
\ No newline at end of file
lib/features/chat/views/components/top_bar/connection_banner.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:go_router/go_router.dart';
4
import 'package:localmind/core/models/enums.dart';
@@ -22,8 +23,8 @@ class ConnectionBanner extends StatelessWidget {
23
: Colors.orange.withValues(alpha: 0.1),
24
child: Row(
25
children: [
25
- Icon(
26
- isError ? Icons.error_outline : Icons.wifi_off,
26
+ HugeIcon(icon:
27
+ isError ? HugeIcons.strokeRoundedInformationCircle : HugeIcons.strokeRoundedWifiOff01,
28
size: 16,
29
color: isError ? Colors.red : Colors.orange,
30
),
@@ -51,4 +52,4 @@ class ConnectionBanner extends StatelessWidget {
52
),
53
);
54
}
54
-}
55
+}
\ No newline at end of file
lib/features/chat/views/components/top_bar/model_top_bar.dart
+1
-1
@@ -103,7 +103,7 @@ class ModelTopBar extends ConsumerWidget {
103
overflow: TextOverflow.ellipsis,
104
),
105
),
106
- Icon(Icons.expand_more, size: 14, color: mutedColor),
106
+ HugeIcon(icon: HugeIcons.strokeRoundedArrowDown01, size: 14, color: mutedColor),
107
],
108
),
109
),
lib/features/chat/views/components/top_bar/persona_indicator.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/features/personas/data/models/persona.dart';
@@ -72,7 +73,7 @@ class PersonaIndicator extends StatelessWidget {
73
),
74
const SizedBox(width: 8),
75
IconButton(
75
- icon: const Icon(Icons.close, size: 16),
76
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 16),
77
onPressed: onClear,
78
padding: EdgeInsets.zero,
79
constraints: const BoxConstraints(),
@@ -83,4 +84,4 @@ class PersonaIndicator extends StatelessWidget {
84
),
85
);
86
}
86
-}
87
+}
\ No newline at end of file
lib/features/chat/views/components/top_bar/screen_app_bar.dart
+17
-17
@@ -50,7 +50,7 @@ class ScreenAppBar extends ConsumerWidget {
50
child: Row(
51
children: [
52
IconButton(
53
- icon: const Icon(Icons.close),
53
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
54
onPressed: () =>
55
ref.read(messageSelectionModeProvider.notifier).disable(),
56
),
@@ -64,7 +64,7 @@ class ScreenAppBar extends ConsumerWidget {
64
),
65
),
66
IconButton(
67
- icon: const Icon(Icons.ios_share),
67
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedShare01),
68
tooltip: l10n.export_conversation,
69
onPressed: selectedMessageIds.isEmpty
70
? null
@@ -75,7 +75,7 @@ class ScreenAppBar extends ConsumerWidget {
75
),
76
),
77
IconButton(
78
- icon: const Icon(Icons.delete_outline, color: Colors.red),
78
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red),
79
tooltip: l10n.delete,
80
onPressed: selectedMessageIds.isEmpty
81
? null
@@ -101,7 +101,7 @@ class ScreenAppBar extends ConsumerWidget {
101
breakpoint >= ShadTheme.of(context).breakpoints.md;
102
if (isDesktop) return const SizedBox.shrink();
103
return IconButton(
104
- icon: const Icon(Icons.menu),
104
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
105
onPressed: () => Scaffold.of(context).openDrawer(),
106
);
107
},
@@ -152,13 +152,13 @@ class ScreenAppBar extends ConsumerWidget {
152
onPressed: onChatModeAction,
153
),
154
PopupMenuButton<String>(
155
- icon: const Icon(Icons.more_vert),
155
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMoreVertical),
156
onSelected: onMenuAction,
157
itemBuilder: (context) => [
158
PopupMenuItem(
159
value: 'new_chat',
160
child: ListTile(
161
- leading: const Icon(Icons.add),
161
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
162
title: Text(l10n.nav_new_chat),
163
contentPadding: EdgeInsets.zero,
164
),
@@ -167,7 +167,7 @@ class ScreenAppBar extends ConsumerWidget {
167
PopupMenuItem(
168
value: 'rename',
169
child: ListTile(
170
- leading: const Icon(Icons.drive_file_rename_outline),
170
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedPencilEdit02),
171
title: Text(l10n.rename_conversation),
172
contentPadding: EdgeInsets.zero,
173
),
@@ -175,7 +175,7 @@ class ScreenAppBar extends ConsumerWidget {
175
PopupMenuItem(
176
value: 'move_to_folder',
177
child: ListTile(
178
- leading: const Icon(Icons.folder_outlined),
178
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
179
title: Text(l10n.move_to_folder),
180
contentPadding: EdgeInsets.zero,
181
),
@@ -185,7 +185,7 @@ class ScreenAppBar extends ConsumerWidget {
185
PopupMenuItem(
186
value: 'export_chat',
187
child: ListTile(
188
- leading: const Icon(Icons.upload_outlined),
188
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedUpload01),
189
title: Text(l10n.export_conversation),
190
contentPadding: EdgeInsets.zero,
191
),
@@ -193,7 +193,7 @@ class ScreenAppBar extends ConsumerWidget {
193
PopupMenuItem(
194
value: 'share_chat',
195
child: ListTile(
196
- leading: const Icon(Icons.share_outlined),
196
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedShare01),
197
title: Text(l10n.share_conversation),
198
contentPadding: EdgeInsets.zero,
199
),
@@ -202,8 +202,8 @@ class ScreenAppBar extends ConsumerWidget {
202
PopupMenuItem(
203
value: 'persona',
204
child: ListTile(
205
- leading: Icon(
206
- hasPersonas ? Icons.swap_horiz : Icons.smart_toy_outlined,
205
+ leading: HugeIcon(icon:
206
+ hasPersonas ? HugeIcons.strokeRoundedExchange01 : HugeIcons.strokeRoundedRobot01,
207
),
208
title: Text(
209
hasPersonas ? l10n.change_persona : l10n.set_persona,
@@ -214,7 +214,7 @@ class ScreenAppBar extends ConsumerWidget {
214
PopupMenuItem(
215
value: 'clear',
216
child: ListTile(
217
- leading: const Icon(Icons.delete_outline),
217
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01),
218
title: Text(l10n.clear_conversation),
219
contentPadding: EdgeInsets.zero,
220
),
@@ -328,17 +328,17 @@ class ChatModeIconButton extends StatelessWidget {
328
color: activeColor.withValues(alpha: 0.25),
329
shape: BoxShape.circle,
330
),
331
- child: Icon(LucideIcons.ghost, size: 20, color: activeColor),
331
+ child: HugeIcon(icon: HugeIcons.strokeRoundedIncognito, size: 20, color: activeColor),
332
)
333
- : Icon(LucideIcons.ghost, size: 22, color: inactiveColor),
333
+ : HugeIcon(icon: HugeIcons.strokeRoundedIncognito, size: 22, color: inactiveColor),
334
);
335
}
336
337
return IconButton(
338
onPressed: onPressed,
339
tooltip: l10n.nav_new_chat,
340
- icon: Icon(
341
- Icons.add_comment_outlined,
340
+ icon: HugeIcon(icon:
341
+ HugeIcons.strokeRoundedMessageAdd01,
342
size: 22,
343
color: isDark ? Colors.white70 : Colors.black87,
344
),
lib/features/conversations/views/chat_history_screen.dart
+15
-14
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -55,7 +56,7 @@ class ChatHistoryScreen extends ConsumerWidget {
56
? Row(
57
children: [
58
IconButton(
58
- icon: const Icon(Icons.close),
59
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
60
onPressed: () => ref
61
.read(historySelectionModeProvider.notifier)
62
.disable(),
@@ -71,7 +72,7 @@ class ChatHistoryScreen extends ConsumerWidget {
72
),
73
),
74
IconButton(
74
- icon: const Icon(Icons.folder_outlined),
75
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
76
tooltip: l10n.move_to_folder,
77
onPressed: selectedIds.isEmpty
78
? null
@@ -79,7 +80,7 @@ class ChatHistoryScreen extends ConsumerWidget {
80
context, ref, selectedIds),
81
),
82
IconButton(
82
- icon: const Icon(Icons.ios_share),
83
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedShare01),
84
tooltip: l10n.export_conversation,
85
onPressed: selectedIds.isEmpty
86
? null
@@ -87,7 +88,7 @@ class ChatHistoryScreen extends ConsumerWidget {
88
context, ref, selectedIds),
89
),
90
IconButton(
90
- icon: const Icon(Icons.auto_awesome_outlined),
91
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedSparkles),
92
tooltip: l10n.ai_rename_tooltip,
93
onPressed: selectedIds.isEmpty
94
? null
@@ -105,7 +106,7 @@ class ChatHistoryScreen extends ConsumerWidget {
106
children: [
107
Builder(
108
builder: (context) => IconButton(
108
- icon: const Icon(Icons.menu),
109
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
110
onPressed: () => Scaffold.of(context).openDrawer(),
111
),
112
),
@@ -120,7 +121,7 @@ class ChatHistoryScreen extends ConsumerWidget {
121
),
122
const Spacer(),
123
IconButton(
123
- icon: const Icon(Icons.checklist_outlined),
124
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCheckList),
125
tooltip: l10n.select,
126
onPressed: () => ref
127
.read(historySelectionModeProvider.notifier)
@@ -128,7 +129,7 @@ class ChatHistoryScreen extends ConsumerWidget {
129
),
130
ListFilterButton<HistorySortOption>(
131
tooltip: l10n.sort_title,
131
- icon: Icons.sort,
132
+ icon: HugeIcons.strokeRoundedSlidersHorizontal,
133
showBadgeWhenNotDefault: false,
134
selected: ref.watch(historySortOptionProvider),
135
onChanged: (option) => ref
@@ -138,12 +139,12 @@ class ChatHistoryScreen extends ConsumerWidget {
139
ListFilterOption(
140
value: HistorySortOption.modified,
141
label: l10n.sort_by_modified_date,
141
- icon: Icons.edit_calendar_outlined,
142
+ icon: HugeIcons.strokeRoundedCalendar01,
143
),
144
ListFilterOption(
145
value: HistorySortOption.created,
146
label: l10n.sort_by_created_date,
146
- icon: Icons.calendar_today_outlined,
147
+ icon: HugeIcons.strokeRoundedCalendar01,
148
),
149
],
150
),
@@ -157,17 +158,17 @@ class ChatHistoryScreen extends ConsumerWidget {
158
ListFilterOption(
159
value: HistoryListFilter.all,
160
label: l10n.all_chats,
160
- icon: Icons.view_list_rounded,
161
+ icon: HugeIcons.strokeRoundedView,
162
),
163
ListFilterOption(
164
value: HistoryListFilter.pinned,
165
label: l10n.filter_pinned,
165
- icon: Icons.push_pin_outlined,
166
+ icon: HugeIcons.strokeRoundedPin,
167
),
168
ListFilterOption(
169
value: HistoryListFilter.archived,
170
label: l10n.filter_archived,
170
- icon: Icons.archive_outlined,
171
+ icon: HugeIcons.strokeRoundedArchive,
172
),
173
],
174
),
@@ -225,10 +226,10 @@ class ChatHistoryScreen extends ConsumerWidget {
226
ref.read(chatProvider.notifier).startNewConversation();
227
context.go(AppRoutes.home);
228
},
228
- child: const Icon(Icons.add),
229
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
230
),
231
),
232
],
233
);
234
}
234
-}
235
+}
\ No newline at end of file
lib/features/conversations/views/components/conversation_empty_state.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/l10n/app_localizations.dart';
4
@@ -21,8 +22,8 @@ class ConversationEmptyState extends StatelessWidget {
22
child: Column(
23
mainAxisAlignment: MainAxisAlignment.center,
24
children: [
24
- Icon(
25
- isSearching ? Icons.search_off : Icons.chat_bubble_outline,
25
+ HugeIcon(icon:
26
+ isSearching ? HugeIcons.strokeRoundedSearch01 : HugeIcons.strokeRoundedChatting01,
27
size: 48,
28
color: isDark ? const Color(0xFF3A3A3A) : const Color(0xFFE5E5E5),
29
),
@@ -52,4 +53,4 @@ class ConversationEmptyState extends StatelessWidget {
53
),
54
);
55
}
55
-}
56
+}
\ No newline at end of file
lib/features/conversations/views/components/conversation_list.dart
+6
-5
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -206,7 +207,7 @@ void showMoveToFolderSheet(
207
mainAxisSize: MainAxisSize.min,
208
children: [
209
ListTile(
209
- leading: const Icon(Icons.folder_off_outlined),
210
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
211
title: Text(l10n.remove_from_folder),
212
onTap: () async {
213
Navigator.pop(ctx);
@@ -217,7 +218,7 @@ void showMoveToFolderSheet(
218
),
219
...folders.map(
220
(folder) => ListTile(
220
- leading: const Icon(Icons.folder_outlined),
221
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
222
title: Text(folder.name),
223
onTap: () async {
224
Navigator.pop(ctx);
@@ -250,7 +251,7 @@ Future<void> showBulkMoveToFolderSheet(
251
mainAxisSize: MainAxisSize.min,
252
children: [
253
ListTile(
253
- leading: const Icon(Icons.folder_off_outlined),
254
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
255
title: Text(l10n.remove_from_folder),
256
onTap: () async {
257
Navigator.pop(ctx);
@@ -263,7 +264,7 @@ Future<void> showBulkMoveToFolderSheet(
264
),
265
...folders.map(
266
(folder) => ListTile(
266
- leading: const Icon(Icons.folder_outlined),
267
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
268
title: Text(folder.name),
269
onTap: () async {
270
Navigator.pop(ctx);
@@ -368,4 +369,4 @@ Future<void> runBulkAiRename(
369
}
370
371
if (context.mounted) Navigator.of(context, rootNavigator: true).pop();
371
-}
372
+}
\ No newline at end of file
lib/features/conversations/views/components/conversation_search_bar.dart
+14
-9
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -76,17 +77,21 @@ class _ConversationSearchBarState extends ConsumerState<ConversationSearchBar> {
77
fontSize: 14,
78
color: isDark ? const Color(0xFF666666) : const Color(0xFF999999),
79
),
79
- prefixIcon: Icon(
80
- Icons.search,
81
- size: 20,
82
- color: isDark ? const Color(0xFF666666) : const Color(0xFF999999),
80
+ prefixIcon: Center(
81
+ widthFactor: 1.0,
82
+ heightFactor: 1.0,
83
+ child: HugeIcon(icon:
84
+ HugeIcons.strokeRoundedSearch01,
85
+ size: 20,
86
+ color: isDark ? const Color(0xFF666666) : const Color(0xFF999999),
87
+ ),
88
),
89
suffixIcon: Row(
90
mainAxisSize: MainAxisSize.min,
91
children: [
92
IconButton(
88
- icon: Icon(
89
- searchContents ? Icons.article : Icons.article_outlined,
93
+ icon: HugeIcon(icon:
94
+ searchContents ? HugeIcons.strokeRoundedDocumentCode : HugeIcons.strokeRoundedDocumentCode,
95
size: 20,
96
color: searchContents
97
? theme.colorScheme.primary
@@ -101,8 +106,8 @@ class _ConversationSearchBarState extends ConsumerState<ConversationSearchBar> {
106
),
107
if (_controller.text.isNotEmpty)
108
IconButton(
104
- icon: Icon(
105
- Icons.clear,
109
+ icon: HugeIcon(icon:
110
+ HugeIcons.strokeRoundedCancel01,
111
size: 18,
112
color: isDark
113
? const Color(0xFF666666)
@@ -125,4 +130,4 @@ class _ConversationSearchBarState extends ConsumerState<ConversationSearchBar> {
130
),
131
);
132
}
128
-}
133
+}
\ No newline at end of file
lib/features/conversations/views/components/conversation_tile.dart
+19
-19
@@ -68,10 +68,10 @@ class ConversationTile extends StatelessWidget {
68
alignment: AlignmentDirectional.centerStart,
69
padding: const EdgeInsetsDirectional.only(start: 16),
70
color: Colors.blue,
71
- child: Icon(
71
+ child: HugeIcon(icon:
72
conversation.isArchived
73
- ? Icons.unarchive_outlined
74
- : Icons.archive_outlined,
73
+ ? HugeIcons.strokeRoundedArchive
74
+ : HugeIcons.strokeRoundedArchive,
75
color: Colors.white,
76
),
77
),
@@ -79,7 +79,7 @@ class ConversationTile extends StatelessWidget {
79
alignment: AlignmentDirectional.centerEnd,
80
padding: const EdgeInsetsDirectional.only(end: 16),
81
color: Colors.red,
82
- child: const Icon(Icons.delete, color: Colors.white),
82
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.white),
83
),
84
confirmDismiss: (direction) async {
85
if (direction == DismissDirection.startToEnd) {
@@ -105,10 +105,10 @@ class ConversationTile extends StatelessWidget {
105
if (selectionMode)
106
Checkbox(value: isSelected, onChanged: (_) => onTap())
107
else
108
- Icon(
108
+ HugeIcon(icon:
109
conversation.isPinned
110
- ? Icons.push_pin
111
- : Icons.chat_bubble_outline,
110
+ ? HugeIcons.strokeRoundedPin
111
+ : HugeIcons.strokeRoundedChatting01,
112
size: 20,
113
color: isActive
114
? (isDark
@@ -210,7 +210,7 @@ class ConversationTile extends StatelessWidget {
210
children: [
211
if (onEnterSelectionMode != null)
212
ListTile(
213
- leading: const Icon(Icons.checklist_outlined),
213
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCheckList),
214
title: Text(l10n.select),
215
onTap: () {
216
Navigator.pop(ctx);
@@ -218,10 +218,10 @@ class ConversationTile extends StatelessWidget {
218
},
219
),
220
ListTile(
221
- leading: Icon(
221
+ leading: HugeIcon(icon:
222
conversation.isPinned
223
- ? Icons.push_pin_outlined
224
- : Icons.push_pin,
223
+ ? HugeIcons.strokeRoundedPin
224
+ : HugeIcons.strokeRoundedPin,
225
),
226
title: Text(conversation.isPinned ? l10n.unpin : l10n.pin),
227
onTap: () {
@@ -230,7 +230,7 @@ class ConversationTile extends StatelessWidget {
230
},
231
),
232
ListTile(
233
- leading: const Icon(Icons.edit_outlined),
233
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedPencilEdit02),
234
title: Text(l10n.rename),
235
onTap: () {
236
Navigator.pop(ctx);
@@ -238,7 +238,7 @@ class ConversationTile extends StatelessWidget {
238
},
239
),
240
ListTile(
241
- leading: const Icon(Icons.copy_outlined),
241
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCopy),
242
title: Text(l10n.duplicate_chat),
243
onTap: () {
244
Navigator.pop(ctx);
@@ -246,7 +246,7 @@ class ConversationTile extends StatelessWidget {
246
},
247
),
248
ListTile(
249
- leading: const Icon(Icons.folder_outlined),
249
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
250
title: Text(l10n.move_to_folder),
251
onTap: () {
252
Navigator.pop(ctx);
@@ -254,7 +254,7 @@ class ConversationTile extends StatelessWidget {
254
},
255
),
256
ListTile(
257
- leading: const Icon(Icons.upload_outlined),
257
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedUpload01),
258
title: Text(l10n.export_conversation),
259
onTap: () {
260
Navigator.pop(ctx);
@@ -262,10 +262,10 @@ class ConversationTile extends StatelessWidget {
262
},
263
),
264
ListTile(
265
- leading: Icon(
265
+ leading: HugeIcon(icon:
266
conversation.isArchived
267
- ? Icons.unarchive_outlined
268
- : Icons.archive_outlined,
267
+ ? HugeIcons.strokeRoundedArchive
268
+ : HugeIcons.strokeRoundedArchive,
269
),
270
title: Text(
271
conversation.isArchived
@@ -278,7 +278,7 @@ class ConversationTile extends StatelessWidget {
278
},
279
),
280
ListTile(
281
- leading: const Icon(Icons.delete_outline, color: Colors.red),
281
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red),
282
title: Text(
283
l10n.delete,
284
style: const TextStyle(color: Colors.red),
lib/features/conversations/views/components/message_search_results_list.dart
+5
-4
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -37,10 +38,10 @@ class MessageSearchResultsList extends ConsumerWidget {
38
itemBuilder: (context, index) {
39
final hit = hits[index];
40
return ListTile(
40
- leading: Icon(
41
+ leading: HugeIcon(icon:
42
hit.role == MessageRole.user
42
- ? Icons.person_outline
43
- : Icons.smart_toy_outlined,
43
+ ? HugeIcons.strokeRoundedUser
44
+ : HugeIcons.strokeRoundedRobot01,
45
),
46
title: Text(
47
hit.conversationTitle,
@@ -84,4 +85,4 @@ class MessageSearchResultsList extends ConsumerWidget {
85
],
86
);
87
}
87
-}
88
+}
\ No newline at end of file
lib/features/conversations/views/components/new_chat_button.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -24,10 +25,10 @@ class NewChatButton extends ConsumerWidget {
25
Navigator.pop(context);
26
}
27
},
27
- icon: const Icon(Icons.add, size: 18),
28
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01, size: 18),
29
label: Text(l10n.nav_new_chat),
30
),
31
),
32
);
33
}
33
-}
34
+}
\ No newline at end of file
lib/features/conversations/views/components/rename_conversation_dialog.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -65,7 +66,7 @@ Future<void> showRenameConversationDialog(
66
height: 16,
67
child: CircularProgressIndicator(strokeWidth: 2),
68
)
68
- : const Icon(Icons.auto_awesome_outlined, size: 18),
69
+ : const HugeIcon(icon: HugeIcons.strokeRoundedSparkles, size: 18),
70
label: Text(
71
isGenerating
72
? l10n.generating_title
@@ -103,4 +104,4 @@ Future<void> showRenameConversationDialog(
104
);
105
106
controller.dispose();
106
-}
107
+}
\ No newline at end of file
lib/features/lm_studio_catalog/views/lm_studio_download_widgets.dart
+3
-2
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
@@ -229,11 +230,11 @@ class _DownloadJobTile extends ConsumerWidget {
230
trailing: job.status.isActive
231
? null
232
: IconButton(
232
- icon: const Icon(Icons.close, size: 18),
233
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 18),
234
onPressed: () => ref
235
.read(lmDownloadManagerProvider.notifier)
236
.removeJob(job.jobId),
237
),
238
);
239
}
239
-}
240
+}
\ No newline at end of file
lib/features/lm_studio_catalog/views/lm_studio_model_browser_screen.dart
+36
-31
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:gpt_markdown/gpt_markdown.dart';
@@ -129,10 +130,14 @@ class _LmStudioModelBrowserScreenState
130
onChanged: _onSearchChanged,
131
decoration: InputDecoration(
132
hintText: l10n.lm_studio_model_search_hint,
132
- prefixIcon: const Icon(Icons.search),
133
+ prefixIcon: const Center(
134
+ widthFactor: 1.0,
135
+ heightFactor: 1.0,
136
+ child: HugeIcon(icon: HugeIcons.strokeRoundedSearch01, size: 20),
137
+ ),
138
suffixIcon: _searchQuery.isNotEmpty
139
? IconButton(
135
- icon: const Icon(Icons.close),
140
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 18),
141
onPressed: () {
142
_searchController.clear();
143
_onSearchChanged('');
@@ -364,8 +369,8 @@ class _ModelListTile extends StatelessWidget {
369
),
370
),
371
if (model.isVerified)
367
- Icon(
368
- Icons.verified,
372
+ HugeIcon(icon:
373
+ HugeIcons.strokeRoundedCheckmarkBadge01,
374
size: 16,
375
color: isDark
376
? AppColors.darkAccent
@@ -373,8 +378,8 @@ class _ModelListTile extends StatelessWidget {
378
),
379
if (model.isStaffPick) ...[
380
const SizedBox(width: 4),
376
- Icon(
377
- Icons.auto_awesome,
381
+ HugeIcon(icon:
382
+ HugeIcons.strokeRoundedSparkles,
383
size: 14,
384
color: Colors.purple.shade300,
385
),
@@ -405,7 +410,7 @@ class _ModelListTile extends StatelessWidget {
410
_CapabilityIcons(model: model),
411
const Spacer(),
412
if (model.likes > 0) ...[
408
- Icon(Icons.favorite_border,
413
+ HugeIcon(icon: HugeIcons.strokeRoundedFavourite,
414
size: 14, color: theme.hintColor),
415
const SizedBox(width: 2),
416
Text(
@@ -415,7 +420,7 @@ class _ModelListTile extends StatelessWidget {
420
const SizedBox(width: 8),
421
],
422
if (model.downloads > 0) ...[
418
- Icon(Icons.download_outlined,
423
+ HugeIcon(icon: HugeIcons.strokeRoundedDownload01,
424
size: 14, color: theme.hintColor),
425
const SizedBox(width: 2),
426
Text(
@@ -480,21 +485,21 @@ class _CapabilityIcons extends StatelessWidget {
485
Widget build(BuildContext context) {
486
final icons = <Widget>[];
487
if (model.metadata.vision) {
483
- icons.add(_capIcon(Icons.visibility_outlined, Colors.amber));
488
+ icons.add(_capIcon(HugeIcons.strokeRoundedEye, Colors.amber));
489
}
490
if (model.metadata.trainedForToolUse) {
486
- icons.add(_capIcon(Icons.build_outlined, Colors.blue));
491
+ icons.add(_capIcon(HugeIcons.strokeRoundedTools, Colors.blue));
492
}
493
if (model.metadata.reasoning) {
489
- icons.add(_capIcon(Icons.psychology_outlined, Colors.green));
494
+ icons.add(_capIcon(HugeIcons.strokeRoundedBrain, Colors.green));
495
}
496
return Row(children: icons);
497
}
498
494
- Widget _capIcon(IconData icon, Color color) {
499
+ Widget _capIcon(List<List<dynamic>> icon, Color color) {
500
return Padding(
501
padding: const EdgeInsets.only(right: 4),
497
- child: Icon(icon, size: 16, color: color),
502
+ child: HugeIcon(icon: icon, size: 16, color: color),
503
);
504
}
505
}
@@ -635,7 +640,7 @@ class _ModelDetailPanelState extends ConsumerState<_ModelDetailPanel> {
640
child: Row(
641
children: [
642
IconButton(
638
- icon: const Icon(Icons.arrow_back),
643
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedArrowLeft01),
644
onPressed: widget.onClose,
645
),
646
Expanded(
@@ -649,7 +654,7 @@ class _ModelDetailPanelState extends ConsumerState<_ModelDetailPanel> {
654
),
655
),
656
IconButton(
652
- icon: const Icon(Icons.close),
657
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
658
onPressed: widget.onClose,
659
),
660
],
@@ -686,14 +691,14 @@ class _ModelDetailPanelState extends ConsumerState<_ModelDetailPanel> {
691
Row(
692
children: [
693
if (widget.model.likes > 0) ...[
689
- Icon(Icons.favorite_border,
694
+ HugeIcon(icon: HugeIcons.strokeRoundedFavourite,
695
size: 16, color: theme.hintColor),
696
const SizedBox(width: 4),
697
Text(_formatCount(widget.model.likes)),
698
const SizedBox(width: 16),
699
],
700
if (widget.model.downloads > 0) ...[
696
- Icon(Icons.download_outlined,
701
+ HugeIcon(icon: HugeIcons.strokeRoundedDownload01,
702
size: 16, color: theme.hintColor),
703
const SizedBox(width: 4),
704
Text(_formatCount(widget.model.downloads)),
@@ -806,10 +811,10 @@ class _ModelDetailPanelState extends ConsumerState<_ModelDetailPanel> {
811
value: activeJob.progressFraction,
812
),
813
)
809
- : Icon(
814
+ : HugeIcon(icon:
815
selectedDownloaded
811
- ? Icons.check
812
- : Icons.download,
816
+ ? HugeIcons.strokeRoundedTick01
817
+ : HugeIcons.strokeRoundedDownload01,
818
),
819
label: Text(
820
activeJob != null
@@ -948,19 +953,19 @@ class _CapabilityRow extends StatelessWidget {
953
final l10n = AppLocalizations.of(context)!;
954
final caps = <Widget>[];
955
if (model.metadata.vision) {
951
- caps.add(_capLabel(Icons.visibility_outlined, l10n.lm_studio_vision, Colors.amber));
956
+ caps.add(_capLabel(HugeIcons.strokeRoundedEye, l10n.lm_studio_vision, Colors.amber));
957
}
958
if (model.metadata.trainedForToolUse) {
954
- caps.add(_capLabel(Icons.build_outlined, l10n.lm_studio_tool_use, Colors.blue));
959
+ caps.add(_capLabel(HugeIcons.strokeRoundedTools, l10n.lm_studio_tool_use, Colors.blue));
960
}
961
if (model.metadata.reasoning) {
957
- caps.add(_capLabel(Icons.psychology_outlined, l10n.lm_studio_reasoning, Colors.green));
962
+ caps.add(_capLabel(HugeIcons.strokeRoundedBrain, l10n.lm_studio_reasoning, Colors.green));
963
}
964
if (caps.isEmpty) return const SizedBox.shrink();
965
return Wrap(spacing: 8, runSpacing: 8, children: caps);
966
}
967
963
- Widget _capLabel(IconData icon, String label, Color color) {
968
+ Widget _capLabel(List<List<dynamic>> icon, String label, Color color) {
969
return Container(
970
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
971
decoration: BoxDecoration(
@@ -970,7 +975,7 @@ class _CapabilityRow extends StatelessWidget {
975
child: Row(
976
mainAxisSize: MainAxisSize.min,
977
children: [
973
- Icon(icon, size: 14, color: color),
978
+ HugeIcon(icon: icon, size: 14, color: color),
979
const SizedBox(width: 4),
980
Text(label, style: TextStyle(color: color, fontSize: 12)),
981
],
@@ -989,21 +994,21 @@ class _CompatibilityBadge extends StatelessWidget {
994
final l10n = AppLocalizations.of(context)!;
995
late final String label;
996
late final Color color;
992
- late final IconData icon;
997
+ late final List<List<dynamic>> icon;
998
999
switch (compatibility) {
1000
case MemoryCompatibility.fullGpuOffload:
1001
label = l10n.lm_studio_full_gpu_offload;
1002
color = Colors.green;
998
- icon = Icons.rocket_launch_outlined;
1003
+ icon = HugeIcons.strokeRoundedRocket;
1004
case MemoryCompatibility.partialGpuOffload:
1005
label = l10n.lm_studio_partial_gpu_offload;
1006
color = Colors.blue;
1002
- icon = Icons.memory_outlined;
1007
+ icon = HugeIcons.strokeRoundedCpu;
1008
case MemoryCompatibility.likelyTooLarge:
1009
label = l10n.lm_studio_likely_too_large;
1010
color = Colors.red;
1006
- icon = Icons.cancel_outlined;
1011
+ icon = HugeIcons.strokeRoundedCancel01;
1012
case MemoryCompatibility.unknown:
1013
return const SizedBox.shrink();
1014
}
@@ -1017,7 +1022,7 @@ class _CompatibilityBadge extends StatelessWidget {
1022
child: Row(
1023
mainAxisSize: MainAxisSize.min,
1024
children: [
1020
- Icon(icon, size: 14, color: color),
1025
+ HugeIcon(icon: icon, size: 14, color: color),
1026
const SizedBox(width: 6),
1027
Text(
1028
label,
@@ -1027,4 +1032,4 @@ class _CompatibilityBadge extends StatelessWidget {
1032
),
1033
);
1034
}
1030
-}
1035
+}
\ No newline at end of file
lib/features/lm_studio_catalog/views/lm_studio_quant_selector.dart
+18
-17
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/features/models/data/models/model_info.dart';
@@ -57,21 +58,21 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
58
59
late final String label;
60
late final Color color;
60
- late final IconData icon;
61
+ late final List<List<dynamic>> icon;
62
63
switch (compatibility) {
64
case MemoryCompatibility.fullGpuOffload:
65
label = l10n.lm_studio_full_gpu_offload;
66
color = Colors.green;
66
- icon = Icons.rocket_launch_outlined;
67
+ icon = HugeIcons.strokeRoundedRocket;
68
case MemoryCompatibility.partialGpuOffload:
69
label = l10n.lm_studio_partial_gpu_offload;
70
color = Colors.blue;
70
- icon = Icons.memory_outlined;
71
+ icon = HugeIcons.strokeRoundedCpu;
72
case MemoryCompatibility.likelyTooLarge:
73
label = l10n.lm_studio_likely_too_large;
74
color = Colors.red;
74
- icon = Icons.cancel_outlined;
75
+ icon = HugeIcons.strokeRoundedCancel01;
76
case MemoryCompatibility.unknown:
77
return const SizedBox.shrink();
78
}
@@ -85,7 +86,7 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
86
child: Row(
87
mainAxisSize: MainAxisSize.min,
88
children: [
88
- Icon(icon, size: 12, color: color),
89
+ HugeIcon(icon: icon, size: 12, color: color),
90
const SizedBox(width: 4),
91
Flexible(
92
child: Text(
@@ -143,8 +144,8 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
144
overflow: TextOverflow.ellipsis,
145
),
146
),
146
- Icon(
147
- _expanded ? Icons.expand_less : Icons.expand_more,
147
+ HugeIcon(icon:
148
+ _expanded ? HugeIcons.strokeRoundedArrowUp01 : HugeIcons.strokeRoundedArrowDown01,
149
color: theme.hintColor,
150
),
151
],
@@ -209,10 +210,10 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
210
child: Row(
211
crossAxisAlignment: CrossAxisAlignment.start,
212
children: [
212
- Icon(
213
+ HugeIcon(icon:
214
isSelected
214
- ? Icons.check_circle
215
- : Icons.circle_outlined,
215
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
216
+ : HugeIcons.strokeRoundedCircle,
217
size: 18,
218
color: isSelected
219
? (isDark
@@ -237,11 +238,11 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
238
?.copyWith(fontWeight: FontWeight.w600),
239
),
240
if (widget.modelCapabilities.metadata.vision)
240
- _CapIcon(Icons.visibility_outlined, Colors.amber),
241
+ _CapIcon(HugeIcons.strokeRoundedEye, Colors.amber),
242
if (widget.modelCapabilities.metadata.reasoning)
242
- _CapIcon(Icons.psychology_outlined, Colors.green),
243
+ _CapIcon(HugeIcons.strokeRoundedBrain, Colors.green),
244
if (widget.modelCapabilities.metadata.trainedForToolUse)
244
- _CapIcon(Icons.build_outlined, Colors.blue),
245
+ _CapIcon(HugeIcons.strokeRoundedTools, Colors.blue),
246
if (isRecommended) _RecommendedTag(l10n: l10n),
247
],
248
),
@@ -272,7 +273,7 @@ class _LmStudioQuantSelectorState extends State<LmStudioQuantSelector> {
273
Row(
274
mainAxisSize: MainAxisSize.min,
275
children: [
275
- Icon(Icons.check, size: 14, color: Colors.green.shade400),
276
+ HugeIcon(icon: HugeIcons.strokeRoundedTick01, size: 14, color: Colors.green.shade400),
277
const SizedBox(width: 2),
278
Text(
279
l10n.downloaded,
@@ -334,12 +335,12 @@ class _GgufTag extends StatelessWidget {
335
class _CapIcon extends StatelessWidget {
336
const _CapIcon(this.icon, this.color);
337
337
- final IconData icon;
338
+ final List<List<dynamic>> icon;
339
final Color color;
340
341
@override
342
Widget build(BuildContext context) {
342
- return Icon(icon, size: 14, color: color);
343
+ return HugeIcon(icon: icon, size: 14, color: color);
344
}
345
}
346
@@ -372,4 +373,4 @@ class _RecommendedTag extends StatelessWidget {
373
/// Collect downloaded models from server catalog for download detection.
374
List<ModelInfo> downloadedModelsList(List<dynamic> models) {
375
return models.whereType<ModelInfo>().toList();
375
-}
376
+}
\ No newline at end of file
lib/features/mcp/views/mcp_tools_screen.dart
+8
-8
@@ -78,7 +78,7 @@ class _McpToolsScreenState extends ConsumerState<McpToolsScreen> {
78
children: [
79
Builder(
80
builder: (context) => IconButton(
81
- icon: const Icon(Icons.menu),
81
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
82
onPressed: () => Scaffold.of(context).openDrawer(),
83
),
84
),
@@ -126,7 +126,7 @@ class _McpToolsScreenState extends ConsumerState<McpToolsScreen> {
126
127
if (snapshot.hasError) {
128
return _StatusPanel(
129
- icon: Icons.error_outline,
129
+ icon: HugeIcons.strokeRoundedInformationCircle,
130
title: l10n.unable_load_tools,
131
body: snapshot.error.toString(),
132
);
@@ -135,7 +135,7 @@ class _McpToolsScreenState extends ConsumerState<McpToolsScreen> {
135
final tools = snapshot.data ?? const <ToolDefinition>[];
136
if (tools.isEmpty) {
137
return _StatusPanel(
138
- icon: Icons.extension_outlined,
138
+ icon: HugeIcons.strokeRoundedPuzzle,
139
title: l10n.no_tools_registered,
140
body: l10n.no_tools_registered_desc,
141
);
@@ -224,7 +224,7 @@ class _ExampleServerPanel extends StatelessWidget {
224
const SizedBox(height: 16),
225
ShadButton(
226
onPressed: onToggle,
227
- leading: Icon(enabled ? Icons.power_settings_new : Icons.add),
227
+ leading: HugeIcon(icon: enabled ? HugeIcons.strokeRoundedPower : HugeIcons.strokeRoundedAdd01),
228
child: Text(
229
enabled
230
? l10n.disable_example_server
@@ -262,8 +262,8 @@ class _ToolRow extends StatelessWidget {
262
child: Row(
263
crossAxisAlignment: CrossAxisAlignment.start,
264
children: [
265
- Icon(
266
- isMcp ? Icons.hub_outlined : Icons.functions,
265
+ HugeIcon(icon:
266
+ isMcp ? HugeIcons.strokeRoundedShare01 : HugeIcons.strokeRoundedCalculate,
267
size: 20,
268
color: isMcp
269
? theme.colorScheme.primary
@@ -349,7 +349,7 @@ class _StatusPanel extends StatelessWidget {
349
required this.body,
350
});
351
352
- final IconData icon;
352
+ final List<List<dynamic>> icon;
353
final String title;
354
final String body;
355
@@ -364,7 +364,7 @@ class _StatusPanel extends StatelessWidget {
364
),
365
child: Column(
366
children: [
367
- Icon(icon, size: 32, color: theme.colorScheme.outline),
367
+ HugeIcon(icon: icon, size: 32, color: theme.colorScheme.outline),
368
const SizedBox(height: 12),
369
Text(
370
title,
lib/features/models/components/model_list.dart
+9
-8
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/core/providers/app_providers.dart';
@@ -121,10 +122,10 @@ class _ModelListState extends ConsumerState<ModelList> {
122
const SizedBox(height: 16),
123
ListTile(
124
contentPadding: EdgeInsets.zero,
124
- leading: Icon(
125
+ leading: HugeIcon(icon:
126
metadata?.isFavorite == true
126
- ? Icons.star
127
- : Icons.star_border,
127
+ ? HugeIcons.strokeRoundedStar
128
+ : HugeIcons.strokeRoundedStar,
129
color: Colors.amber[700],
130
),
131
title: Text(l10n.model_favorite_toggle),
@@ -189,7 +190,7 @@ class _ModelListState extends ConsumerState<ModelList> {
190
child: Column(
191
mainAxisAlignment: MainAxisAlignment.center,
192
children: [
192
- Icon(Icons.cloud_off_rounded, size: 64, color: Colors.red[300]),
193
+ HugeIcon(icon: HugeIcons.strokeRoundedCloud, size: 64, color: Colors.red[300]),
194
const SizedBox(height: 16),
195
Text(
196
l10n.server_offline,
@@ -214,7 +215,7 @@ class _ModelListState extends ConsumerState<ModelList> {
215
await ref.read(connectionStatusProvider.notifier).refresh();
216
ref.invalidate(availableModelsProvider(widget.serverId));
217
},
217
- icon: const Icon(Icons.refresh),
218
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh),
219
label: Text(l10n.retry_connection),
220
),
221
],
@@ -235,7 +236,7 @@ class _ModelListState extends ConsumerState<ModelList> {
236
child: Column(
237
mainAxisAlignment: MainAxisAlignment.center,
238
children: [
238
- Icon(Icons.error_outline, size: 48, color: Colors.red[400]),
239
+ HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle, size: 48, color: Colors.red[400]),
240
const SizedBox(height: 16),
241
Text(
242
l10n.failed_load_models,
@@ -258,7 +259,7 @@ class _ModelListState extends ConsumerState<ModelList> {
259
OutlinedButton.icon(
260
onPressed: () =>
261
ref.invalidate(availableModelsProvider(widget.serverId)),
261
- icon: const Icon(Icons.refresh),
262
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh),
263
label: Text(l10n.retry),
264
),
265
],
@@ -424,4 +425,4 @@ class _ModelListState extends ConsumerState<ModelList> {
425
},
426
);
427
}
427
-}
428
+}
\ No newline at end of file
lib/features/models/components/model_search_field.dart
+8
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -14,7 +15,11 @@ class ModelSearchField extends ConsumerWidget {
15
return TextField(
16
decoration: InputDecoration(
17
hintText: l10n.search_models_hint,
17
- prefixIcon: const Icon(Icons.search, size: 20),
18
+ prefixIcon: const Center(
19
+ widthFactor: 1.0,
20
+ heightFactor: 1.0,
21
+ child: HugeIcon(icon: HugeIcons.strokeRoundedSearch01, size: 20),
22
+ ),
23
isDense: true,
24
contentPadding: const EdgeInsets.symmetric(
25
horizontal: 12,
@@ -25,7 +30,7 @@ class ModelSearchField extends ConsumerWidget {
30
),
31
suffixIcon: searchQuery.isNotEmpty
32
? IconButton(
28
- icon: const Icon(Icons.clear, size: 18),
33
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 18),
34
onPressed: () =>
35
ref.read(modelSearchQueryProvider.notifier).clear(),
36
)
@@ -35,4 +40,4 @@ class ModelSearchField extends ConsumerWidget {
40
ref.read(modelSearchQueryProvider.notifier).setQuery(q),
41
);
42
}
38
-}
43
+}
\ No newline at end of file
lib/features/models/components/model_sort_control.dart
+9
-8
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -21,17 +22,17 @@ class ModelSortControl extends ConsumerWidget {
22
}
23
}
24
24
- IconData _iconFor(ModelSortOption option) {
25
+ List<List<dynamic>> _iconFor(ModelSortOption option) {
26
switch (option) {
27
case ModelSortOption.favorites:
27
- return Icons.star_outline;
28
+ return HugeIcons.strokeRoundedStar;
29
case ModelSortOption.nameAsc:
29
- return Icons.sort_by_alpha;
30
+ return HugeIcons.strokeRoundedAlpha;
31
case ModelSortOption.sizeAsc:
32
case ModelSortOption.sizeDesc:
32
- return Icons.sd_storage_outlined;
33
+ return HugeIcons.strokeRoundedDatabase;
34
case ModelSortOption.contextDesc:
34
- return Icons.view_column_outlined;
35
+ return HugeIcons.strokeRoundedView;
36
}
37
}
38
@@ -45,13 +46,13 @@ class ModelSortControl extends ConsumerWidget {
46
initialValue: current,
47
onSelected: (option) =>
48
ref.read(modelSortOptionProvider.notifier).setOption(option),
48
- icon: const Icon(Icons.sort, size: 20),
49
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedSlidersHorizontal, size: 20),
50
itemBuilder: (context) => ModelSortOption.values.map((option) {
51
return PopupMenuItem(
52
value: option,
53
child: Row(
54
children: [
54
- Icon(
55
+ HugeIcon(icon:
56
_iconFor(option),
57
size: 18,
58
color: option == current
@@ -75,4 +76,4 @@ class ModelSortControl extends ConsumerWidget {
76
}).toList(),
77
);
78
}
78
-}
79
+}
\ No newline at end of file
lib/features/models/components/model_tile.dart
+8
-9
@@ -1,6 +1,5 @@
1
import 'package:flutter/material.dart';
2
import 'package:hugeicons/hugeicons.dart';
3
-import 'package:shadcn_ui/shadcn_ui.dart';
3
import 'package:localmind/core/models/enums.dart';
4
import 'package:localmind/core/theme/colors.dart';
5
import 'package:localmind/features/models/data/models/model_info.dart';
@@ -63,7 +62,7 @@ class ModelTile extends StatelessWidget {
62
Row(
63
children: [
64
if (isFavorite) ...[
66
- Icon(Icons.star, size: 16, color: Colors.amber[600]),
65
+ HugeIcon(icon: HugeIcons.strokeRoundedStar, size: 16, color: Colors.amber[600]),
66
const SizedBox(width: 6),
67
],
68
Expanded(
@@ -135,8 +134,8 @@ class ModelTile extends StatelessWidget {
134
model.serverType == ServerType.ollama) &&
135
isLoaded) ...[
136
IconButton(
138
- icon: Icon(
139
- Icons.power_settings_new_outlined,
137
+ icon: HugeIcon(icon:
138
+ HugeIcons.strokeRoundedPower,
139
size: 18,
140
color: Colors.red[400],
141
),
@@ -196,19 +195,19 @@ class _ModelCapabilityIcons extends StatelessWidget {
195
children: [
196
if (model.supportsVision)
197
_CapabilityIcon(
199
- icon: LucideIcons.eye,
198
+ icon: HugeIcons.strokeRoundedEye,
199
tooltip: l10n.lm_studio_vision,
200
color: color,
201
),
202
if (model.supportsReasoning)
203
_CapabilityIcon(
205
- icon: LucideIcons.brain,
204
+ icon: HugeIcons.strokeRoundedBrain,
205
tooltip: l10n.lm_studio_reasoning,
206
color: color,
207
),
208
if (model.supportsToolUse)
209
_CapabilityIcon(
211
- icon: LucideIcons.hammer,
210
+ icon: HugeIcons.strokeRoundedTools,
211
tooltip: l10n.lm_studio_tool_use,
212
color: color,
213
),
@@ -224,7 +223,7 @@ class _CapabilityIcon extends StatelessWidget {
223
required this.color,
224
});
225
227
- final IconData icon;
226
+ final List<List<dynamic>> icon;
227
final String tooltip;
228
final Color color;
229
@@ -234,7 +233,7 @@ class _CapabilityIcon extends StatelessWidget {
233
padding: const EdgeInsets.only(left: 4),
234
child: Tooltip(
235
message: tooltip,
237
- child: Icon(icon, size: 14, color: color),
236
+ child: HugeIcon(icon: icon, size: 14, color: color),
237
),
238
);
239
}
lib/features/models/components/no_server_state.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/theme/colors.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -13,8 +14,8 @@ class NoServerState extends StatelessWidget {
14
child: Column(
15
mainAxisAlignment: MainAxisAlignment.center,
16
children: [
16
- Icon(
17
- Icons.computer_outlined,
17
+ HugeIcon(icon:
18
+ HugeIcons.strokeRoundedComputer,
19
size: 48,
20
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
21
),
@@ -39,4 +40,4 @@ class NoServerState extends StatelessWidget {
40
),
41
);
42
}
42
-}
43
+}
\ No newline at end of file
lib/features/models/views/model_picker_sheet.dart
+9
-8
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -324,8 +325,8 @@ class _ModelPickerHeader extends ConsumerWidget {
325
child: Row(
326
mainAxisSize: MainAxisSize.min,
327
children: [
327
- Icon(
328
- Icons.layers_outlined,
328
+ HugeIcon(icon:
329
+ HugeIcons.strokeRoundedLayers01,
330
size: 14,
331
color: isDark ? Colors.grey[400] : Colors.grey[600],
332
),
@@ -348,8 +349,8 @@ class _ModelPickerHeader extends ConsumerWidget {
349
IconButton(
350
onPressed: onUnloadAll,
351
tooltip: l10n.unload_all_models,
351
- icon: Icon(
352
- Icons.power_settings_new_outlined,
352
+ icon: HugeIcon(icon:
353
+ HugeIcons.strokeRoundedPower,
354
size: 20,
355
color: Colors.red[400],
356
),
@@ -358,12 +359,12 @@ class _ModelPickerHeader extends ConsumerWidget {
359
IconButton(
360
onPressed: onBrowseModels,
361
tooltip: l10n.lm_studio_browse_models,
361
- icon: const Icon(Icons.explore_outlined, size: 20),
362
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCompass01, size: 20),
363
),
364
const LmDownloadIndicatorButton(compact: true),
365
if (onRefresh != null)
366
IconButton(
366
- icon: const Icon(Icons.refresh, size: 20),
367
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh, size: 20),
368
onPressed: onRefresh,
369
tooltip: l10n.refresh_models,
370
),
@@ -476,7 +477,7 @@ class __ContextLengthEditDialogState
477
borderRadius: BorderRadius.circular(10),
478
),
479
suffixIcon: IconButton(
479
- icon: const Icon(Icons.clear, size: 18),
480
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 18),
481
onPressed: () => _controller.clear(),
482
),
483
),
@@ -539,4 +540,4 @@ class __ContextLengthEditDialogState
540
),
541
);
542
}
542
-}
543
+}
\ No newline at end of file
lib/features/on_device/components/memory_stats_panel.dart
+10
-9
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:shadcn_ui/shadcn_ui.dart';
@@ -93,8 +94,8 @@ class _MemoryPanelContent extends StatelessWidget {
94
children: [
95
Row(
96
children: [
96
- Icon(
97
- Icons.memory_rounded,
97
+ HugeIcon(icon:
98
+ HugeIcons.strokeRoundedCpu,
99
size: 20,
100
color: theme.colorScheme.primary,
101
),
@@ -111,7 +112,7 @@ class _MemoryPanelContent extends StatelessWidget {
112
ShadButton.ghost(
113
size: ShadButtonSize.sm,
114
onPressed: () => ref.invalidate(deviceMemoryProvider),
114
- child: const Icon(Icons.refresh_rounded, size: 18),
115
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh, size: 18),
116
),
117
],
118
),
@@ -216,7 +217,7 @@ class _MemoryPanelContent extends StatelessWidget {
217
child: _MemoryStat(
218
label: l10n.available_ram,
219
value: info.availableMemoryFormatted,
219
- icon: Icons.speed_rounded,
220
+ icon: HugeIcons.strokeRoundedDashboardSpeed01,
221
color: statusColor,
222
isPrimary: true,
223
),
@@ -230,7 +231,7 @@ class _MemoryPanelContent extends StatelessWidget {
231
child: _MemoryStat(
232
label: l10n.total_capacity,
233
value: info.totalMemoryFormatted,
233
- icon: Icons.storage_rounded,
234
+ icon: HugeIcons.strokeRoundedDatabase,
235
alignment: CrossAxisAlignment.end,
236
),
237
),
@@ -246,7 +247,7 @@ class _MemoryPanelContent extends StatelessWidget {
247
class _MemoryStat extends StatelessWidget {
248
final String label;
249
final String value;
249
- final IconData icon;
250
+ final List<List<dynamic>> icon;
251
final Color? color;
252
final CrossAxisAlignment alignment;
253
final bool isPrimary;
@@ -272,7 +273,7 @@ class _MemoryStat extends StatelessWidget {
273
mainAxisSize: MainAxisSize.min,
274
children: [
275
if (alignment == CrossAxisAlignment.start) ...[
275
- Icon(icon, size: 14, color: iconColor),
276
+ HugeIcon(icon: icon, size: 14, color: iconColor),
277
const SizedBox(width: 6),
278
],
279
Text(
@@ -284,7 +285,7 @@ class _MemoryStat extends StatelessWidget {
285
),
286
if (alignment == CrossAxisAlignment.end) ...[
287
const SizedBox(width: 6),
287
- Icon(icon, size: 14, color: iconColor),
288
+ HugeIcon(icon: icon, size: 14, color: iconColor),
289
],
290
],
291
),
@@ -308,4 +309,4 @@ String _formatMb(int mb) {
309
return '${(mb / 1024).toStringAsFixed(1)} GB';
310
}
311
return '$mb MB';
311
-}
312
+}
\ No newline at end of file
lib/features/on_device/components/model_card.dart
+7
-6
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:io';
3
4
import 'package:flutter/material.dart';
@@ -186,8 +187,8 @@ class _MemoryWarningBadge extends StatelessWidget {
187
child: Row(
188
mainAxisSize: MainAxisSize.min,
189
children: [
189
- const Icon(
190
- Icons.warning_amber_rounded,
190
+ const HugeIcon(icon:
191
+ HugeIcons.strokeRoundedAlertCircle,
192
color: Colors.orange,
193
size: 14,
194
),
@@ -430,8 +431,8 @@ class _DownloadedActions extends ConsumerWidget {
431
432
return Row(
433
children: [
433
- Icon(
434
- isLoaded ? Icons.check_circle : Icons.check_circle_outline,
434
+ HugeIcon(icon:
435
+ isLoaded ? HugeIcons.strokeRoundedCheckmarkCircle01 : HugeIcons.strokeRoundedCheckmarkCircle01,
436
color: isLoaded ? Colors.green : Colors.grey,
437
size: 18,
438
),
@@ -758,7 +759,7 @@ class _NotDownloadedActions extends ConsumerWidget {
759
builder: (ctx) => AlertDialog(
760
title: Row(
761
children: [
761
- const Icon(Icons.warning_amber_rounded, color: Colors.orange),
762
+ const HugeIcon(icon: HugeIcons.strokeRoundedAlertCircle, color: Colors.orange),
763
const SizedBox(width: 8),
764
Text(l10n.ram_warning),
765
],
@@ -779,4 +780,4 @@ class _NotDownloadedActions extends ConsumerWidget {
780
);
781
return result ?? false;
782
}
782
-}
783
+}
\ No newline at end of file
lib/features/on_device/components/on_device_picker_section.dart
+17
-16
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:io';
3
4
import 'package:flutter/material.dart';
@@ -46,7 +47,7 @@ class OnDevicePickerSection extends ConsumerWidget {
47
child: Column(
48
mainAxisAlignment: MainAxisAlignment.center,
49
children: [
49
- Icon(Icons.error_outline, size: 48, color: Colors.red[400]),
50
+ HugeIcon(icon: HugeIcons.strokeRoundedInformationCircle, size: 48, color: Colors.red[400]),
51
const SizedBox(height: 16),
52
Text(
53
l10n.failed_load_models,
@@ -59,7 +60,7 @@ class OnDevicePickerSection extends ConsumerWidget {
60
const SizedBox(height: 16),
61
OutlinedButton.icon(
62
onPressed: () => ref.invalidate(downloadedModelsProvider),
62
- icon: const Icon(Icons.refresh),
63
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedRefresh),
64
label: Text(l10n.retry),
65
),
66
],
@@ -303,8 +304,8 @@ class _OnDeviceModelTile extends ConsumerWidget {
304
padding: const EdgeInsets.only(top: 2),
305
child: Row(
306
children: [
306
- const Icon(
307
- Icons.warning_amber_rounded,
307
+ const HugeIcon(icon:
308
+ HugeIcons.strokeRoundedAlertCircle,
309
color: Colors.orange,
310
size: 12,
311
),
@@ -396,8 +397,8 @@ class _OnDeviceModelTile extends ConsumerWidget {
397
),
398
const SizedBox(width: 8),
399
_IconButton(
399
- icon: Icon(
400
- Icons.power_settings_new_outlined,
400
+ icon: HugeIcon(icon:
401
+ HugeIcons.strokeRoundedPower,
402
size: 18,
403
color: Colors.red[400],
404
),
@@ -406,14 +407,14 @@ class _OnDeviceModelTile extends ConsumerWidget {
407
),
408
] else if (isDownloaded) ...[
409
_IconButton(
409
- icon: Icon(Icons.play_arrow, size: 20, color: accent),
410
+ icon: HugeIcon(icon: HugeIcons.strokeRoundedPlay, size: 20, color: accent),
411
tooltip: l10n.load,
412
onPressed: () => _loadModel(context, ref),
413
),
414
const SizedBox(width: 4),
415
_IconButton(
415
- icon: Icon(
416
- Icons.delete_outline,
416
+ icon: HugeIcon(icon:
417
+ HugeIcons.strokeRoundedDelete01,
418
size: 18,
419
color: isDark
420
? AppColors.darkMutedText
@@ -424,8 +425,8 @@ class _OnDeviceModelTile extends ConsumerWidget {
425
),
426
] else if (isDownloading) ...[
427
_IconButton(
427
- icon: Icon(
428
- Icons.close,
428
+ icon: HugeIcon(icon:
429
+ HugeIcons.strokeRoundedCancel01,
430
size: 16,
431
color: isDark
432
? AppColors.darkMutedText
@@ -438,8 +439,8 @@ class _OnDeviceModelTile extends ConsumerWidget {
439
),
440
] else ...[
441
_IconButton(
441
- icon: Icon(
442
- Icons.cloud_download_outlined,
442
+ icon: HugeIcon(icon:
443
+ HugeIcons.strokeRoundedCloudDownload,
444
size: 18,
445
color: isDark
446
? AppColors.darkMutedText
@@ -478,7 +479,7 @@ class _OnDeviceModelTile extends ConsumerWidget {
479
],
480
if (isDownloaded && isSelected && isLoaded) ...[
481
const SizedBox(width: 4),
481
- Icon(Icons.check_circle, color: accent, size: 22),
482
+ HugeIcon(icon: HugeIcons.strokeRoundedCheckmarkCircle01, color: accent, size: 22),
483
],
484
],
485
),
@@ -538,7 +539,7 @@ class _OnDeviceModelTile extends ConsumerWidget {
539
builder: (ctx) => AlertDialog(
540
title: Row(
541
children: [
541
- const Icon(Icons.warning_amber_rounded, color: Colors.orange),
542
+ const HugeIcon(icon: HugeIcons.strokeRoundedAlertCircle, color: Colors.orange),
543
const SizedBox(width: 8),
544
Text(l10n.ram_warning),
545
],
@@ -674,4 +675,4 @@ class _IconButton extends StatelessWidget {
675
),
676
);
677
}
677
-}
678
+}
\ No newline at end of file
lib/features/on_device/views/backend_selector.dart
+5
-4
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_gemma/flutter_gemma.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -36,10 +37,10 @@ class BackendSelector extends ConsumerWidget {
37
.setPreferredBackend(backend),
38
child: Row(
39
children: [
39
- Icon(
40
+ HugeIcon(icon:
41
isSelected
41
- ? Icons.radio_button_checked
42
- : Icons.radio_button_off,
42
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
43
+ : HugeIcons.strokeRoundedCircle,
44
size: 20,
45
color: isSelected
46
? Theme.of(context).colorScheme.primary
@@ -87,4 +88,4 @@ class BackendSelector extends ConsumerWidget {
88
return 'Neural Processing Unit';
89
}
90
}
90
-}
91
+}
\ No newline at end of file
lib/features/on_device/views/model_manager_screen.dart
+40
-35
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:dio/dio.dart';
3
import 'package:file_picker/file_picker.dart';
4
import 'package:flutter/foundation.dart';
@@ -244,7 +245,7 @@ class _ManagerHeader extends StatelessWidget {
245
children: [
246
Builder(
247
builder: (context) => IconButton(
247
- icon: const Icon(Icons.menu),
248
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
249
onPressed: () => Scaffold.of(context).openDrawer(),
250
),
251
),
@@ -278,7 +279,7 @@ class _ManagerHeader extends StatelessWidget {
279
value: _ImportAction.localFile,
280
child: ListTile(
281
contentPadding: EdgeInsets.zero,
281
- leading: const Icon(Icons.folder_open_outlined),
282
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
283
title: Text(l10n.gguf_import_local_title),
284
subtitle: Text(l10n.gguf_import_local_subtitle),
285
),
@@ -287,7 +288,7 @@ class _ManagerHeader extends StatelessWidget {
288
value: _ImportAction.huggingFace,
289
child: ListTile(
290
contentPadding: EdgeInsets.zero,
290
- leading: const Icon(Icons.cloud_download_outlined),
291
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCloudDownload),
292
title: Text(l10n.gguf_import_huggingface_title),
293
subtitle: Text(l10n.gguf_import_huggingface_subtitle),
294
),
@@ -307,8 +308,8 @@ class _ManagerHeader extends StatelessWidget {
308
child: Row(
309
mainAxisSize: MainAxisSize.min,
310
children: [
310
- Icon(
311
- Icons.add_circle_outline,
311
+ HugeIcon(icon:
312
+ HugeIcons.strokeRoundedAddCircle,
313
size: 18,
314
color: theme.colorScheme.primary,
315
),
@@ -368,8 +369,8 @@ class _ImportOverviewCard extends StatelessWidget {
369
color: theme.colorScheme.primary.withValues(alpha: 0.1),
370
borderRadius: BorderRadius.circular(12),
371
),
371
- child: Icon(
372
- Icons.memory_outlined,
372
+ child: HugeIcon(icon:
373
+ HugeIcons.strokeRoundedCpu,
374
color: theme.colorScheme.primary,
375
),
376
),
@@ -404,16 +405,16 @@ class _ImportOverviewCard extends StatelessWidget {
405
runSpacing: 8,
406
children: [
407
_SummaryPill(
407
- icon: Icons.layers_outlined,
408
+ icon: HugeIcons.strokeRoundedLayers01,
409
label:
410
'${importedModels.length} ${l10n.gguf_imported_count_label}',
411
),
412
_SummaryPill(
412
- icon: Icons.folder_open_outlined,
413
+ icon: HugeIcons.strokeRoundedFolder01,
414
label: '$localImports ${l10n.gguf_local_files_label}',
415
),
416
_SummaryPill(
416
- icon: Icons.cloud_download_outlined,
417
+ icon: HugeIcons.strokeRoundedCloudDownload,
418
label: '$huggingFaceImports ${l10n.gguf_huggingface_label}',
419
),
420
],
@@ -425,12 +426,12 @@ class _ImportOverviewCard extends StatelessWidget {
426
children: [
427
OutlinedButton.icon(
428
onPressed: onImportLocalGguf,
428
- icon: const Icon(Icons.folder_open_outlined),
429
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
430
label: Text(l10n.gguf_import_local_title),
431
),
432
OutlinedButton.icon(
433
onPressed: onImportFromHuggingFace,
433
- icon: const Icon(Icons.cloud_download_outlined),
434
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCloudDownload),
435
label: Text(l10n.gguf_import_huggingface_title),
436
),
437
],
@@ -444,7 +445,7 @@ class _ImportOverviewCard extends StatelessWidget {
445
class _SummaryPill extends StatelessWidget {
446
const _SummaryPill({required this.icon, required this.label});
447
447
- final IconData icon;
448
+ final List<List<dynamic>> icon;
449
final String label;
450
451
@override
@@ -462,7 +463,7 @@ class _SummaryPill extends StatelessWidget {
463
child: Row(
464
mainAxisSize: MainAxisSize.min,
465
children: [
465
- Icon(icon, size: 14, color: theme.colorScheme.primary),
466
+ HugeIcon(icon: icon, size: 14, color: theme.colorScheme.primary),
467
const SizedBox(width: 6),
468
Text(
469
label,
@@ -555,12 +556,12 @@ class _EmptyImportedModelsCard extends StatelessWidget {
556
children: [
557
OutlinedButton.icon(
558
onPressed: onImportLocalGguf,
558
- icon: const Icon(Icons.folder_open_outlined),
559
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
560
label: Text(l10n.gguf_import_local_title),
561
),
562
OutlinedButton.icon(
563
onPressed: onImportFromHuggingFace,
563
- icon: const Icon(Icons.cloud_download_outlined),
564
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCloudDownload),
565
label: Text(l10n.gguf_import_huggingface_title),
566
),
567
],
@@ -627,8 +628,8 @@ class _HuggingFaceGgufImportDialogState
628
color: theme.colorScheme.primary.withValues(alpha: 0.10),
629
borderRadius: BorderRadius.circular(12),
630
),
630
- child: Icon(
631
- Icons.cloud_download_outlined,
631
+ child: HugeIcon(icon:
632
+ HugeIcons.strokeRoundedCloudDownload,
633
color: theme.colorScheme.primary,
634
),
635
),
@@ -674,7 +675,11 @@ class _HuggingFaceGgufImportDialogState
675
hintText:
676
'owner/repo/blob/main/model.gguf\nhttps://huggingface.co/owner/repo/resolve/main/model.gguf',
677
border: const OutlineInputBorder(),
677
- prefixIcon: const Icon(Icons.link_rounded),
678
+ prefixIcon: const Center(
679
+ widthFactor: 1.0,
680
+ heightFactor: 1.0,
681
+ child: HugeIcon(icon: HugeIcons.strokeRoundedLink01, size: 20),
682
+ ),
683
),
684
),
685
const SizedBox(height: 10),
@@ -684,21 +689,21 @@ class _HuggingFaceGgufImportDialogState
689
children: [
690
OutlinedButton.icon(
691
onPressed: _isImporting ? null : _pasteFromClipboard,
687
- icon: const Icon(Icons.content_paste_rounded, size: 18),
692
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedClipboard, size: 18),
693
label: Text(l10n.paste),
694
),
695
OutlinedButton.icon(
696
onPressed: _isImporting || input.isEmpty
697
? null
698
: _clearInput,
694
- icon: const Icon(Icons.close_rounded, size: 18),
699
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 18),
700
label: Text(l10n.clear_huggingface_token),
701
),
702
OutlinedButton.icon(
703
onPressed: _isImporting
704
? null
705
: () => _openHuggingFace(context),
701
- icon: const Icon(Icons.open_in_new_rounded, size: 18),
706
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedShare01, size: 18),
707
label: Text(l10n.gguf_browse),
708
),
709
],
@@ -721,10 +726,10 @@ class _HuggingFaceGgufImportDialogState
726
child: Row(
727
crossAxisAlignment: CrossAxisAlignment.start,
728
children: [
724
- Icon(
729
+ HugeIcon(icon:
730
hasHuggingFaceToken
726
- ? Icons.verified_user_outlined
727
- : Icons.info_outline,
731
+ ? HugeIcons.strokeRoundedCheckmarkBadge01
732
+ : HugeIcons.strokeRoundedInformationCircle,
733
size: 18,
734
color: hasHuggingFaceToken
735
? Colors.green
@@ -840,8 +845,8 @@ class _HuggingFaceGgufImportDialogState
845
child: Row(
846
crossAxisAlignment: CrossAxisAlignment.start,
847
children: [
843
- const Icon(
844
- Icons.error_outline_rounded,
848
+ const HugeIcon(icon:
849
+ HugeIcons.strokeRoundedInformationCircle,
850
color: Colors.red,
851
size: 18,
852
),
@@ -875,7 +880,7 @@ class _HuggingFaceGgufImportDialogState
880
),
881
ElevatedButton.icon(
882
onPressed: _isImporting || input.isEmpty ? null : _startImport,
878
- icon: const Icon(Icons.download_rounded, size: 18),
883
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedDownload01, size: 18),
884
label: Text(l10n.gguf_import_action),
885
),
886
],
@@ -1042,15 +1047,15 @@ class _ImportPreviewCard extends StatelessWidget {
1047
children: [
1048
_PreviewPill(
1049
icon: preview.isBlobLink
1045
- ? Icons.sync_alt_rounded
1046
- : Icons.link_rounded,
1050
+ ? HugeIcons.strokeRoundedRefresh
1051
+ : HugeIcons.strokeRoundedLink01,
1052
label: preview.isBlobLink
1053
? l10n.gguf_blob_link
1054
: preview.inputStyleLabel,
1055
),
1056
if (preview.fileName != null)
1057
_PreviewPill(
1053
- icon: Icons.insert_drive_file_outlined,
1058
+ icon: HugeIcons.strokeRoundedFile01,
1059
label: preview.fileName!,
1060
),
1061
],
@@ -1075,7 +1080,7 @@ class _ImportPreviewCard extends StatelessWidget {
1080
class _PreviewPill extends StatelessWidget {
1081
const _PreviewPill({required this.icon, required this.label});
1082
1078
- final IconData icon;
1083
+ final List<List<dynamic>> icon;
1084
final String label;
1085
1086
@override
@@ -1090,7 +1095,7 @@ class _PreviewPill extends StatelessWidget {
1095
child: Row(
1096
mainAxisSize: MainAxisSize.min,
1097
children: [
1093
- Icon(icon, size: 14, color: theme.colorScheme.primary),
1098
+ HugeIcon(icon: icon, size: 14, color: theme.colorScheme.primary),
1099
const SizedBox(width: 6),
1100
Text(
1101
label,
@@ -1259,7 +1264,7 @@ class _EngineStatusCard extends StatelessWidget {
1264
),
1265
child: Row(
1266
children: [
1262
- const Icon(Icons.check_circle, color: Colors.green, size: 20),
1267
+ const HugeIcon(icon: HugeIcons.strokeRoundedCheckmarkCircle01, color: Colors.green, size: 20),
1268
const SizedBox(width: 8),
1269
Expanded(
1270
child: Text(
@@ -1300,4 +1305,4 @@ class _EngineStatusCard extends StatelessWidget {
1305
1306
return const SizedBox.shrink();
1307
}
1303
-}
1308
+}
\ No newline at end of file
lib/features/onboarding/screens/onboarding_language_screen.dart
+2
-2
@@ -368,8 +368,8 @@ class _OnboardingLanguageScreenState
368
),
369
),
370
child: isSelected
371
- ? const Icon(
372
- Icons.check,
371
+ ? const HugeIcon(icon:
372
+ HugeIcons.strokeRoundedTick01,
373
color: Colors.white,
374
size: 14,
375
)
lib/features/onboarding/screens/onboarding_model_download_screen.dart
+12
-11
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:async';
3
import 'dart:io';
4
@@ -80,8 +81,8 @@ class _OnboardingModelDownloadScreenState
81
),
82
child: Row(
83
children: [
83
- const Icon(
84
- Icons.info_outline,
84
+ const HugeIcon(icon:
85
+ HugeIcons.strokeRoundedInformationCircle,
86
color: Colors.orange,
87
size: 20,
88
),
@@ -241,13 +242,13 @@ class _OnboardingModelDownloadScreenState
242
_MemoryStat(
243
label: l10n.total_ram,
244
value: info.totalMemoryFormatted,
244
- icon: Icons.memory,
245
+ icon: HugeIcons.strokeRoundedCpu,
246
),
247
const SizedBox(width: 24),
248
_MemoryStat(
249
label: l10n.available,
250
value: info.availableMemoryFormatted,
250
- icon: Icons.event_available,
251
+ icon: HugeIcons.strokeRoundedCalendarCheckIn01,
252
color: info.availableMemoryMb < 1024 ? Colors.orange : null,
253
),
254
],
@@ -263,7 +264,7 @@ class _OnboardingModelDownloadScreenState
264
class _MemoryStat extends StatelessWidget {
265
final String label;
266
final String value;
266
- final IconData icon;
267
+ final List<List<dynamic>> icon;
268
final Color? color;
269
270
const _MemoryStat({
@@ -278,7 +279,7 @@ class _MemoryStat extends StatelessWidget {
279
final theme = Theme.of(context);
280
return Row(
281
children: [
281
- Icon(icon, size: 16, color: color ?? theme.colorScheme.primary),
282
+ HugeIcon(icon: icon, size: 16, color: color ?? theme.colorScheme.primary),
283
const SizedBox(width: 8),
284
Column(
285
crossAxisAlignment: CrossAxisAlignment.start,
@@ -380,8 +381,8 @@ class _ModelCard extends ConsumerWidget {
381
padding: const EdgeInsets.only(top: 4),
382
child: Row(
383
children: [
383
- const Icon(
384
- Icons.warning_amber_rounded,
384
+ const HugeIcon(icon:
385
+ HugeIcons.strokeRoundedAlertCircle,
386
color: Colors.orange,
387
size: 14,
388
),
@@ -424,7 +425,7 @@ class _ModelCard extends ConsumerWidget {
425
if (isDownloaded)
426
Row(
427
children: [
427
- const Icon(Icons.check_circle, color: Colors.green, size: 18),
428
+ const HugeIcon(icon: HugeIcons.strokeRoundedCheckmarkCircle01, color: Colors.green, size: 18),
429
const SizedBox(width: 4),
430
Text(
431
l10n.downloaded,
@@ -590,7 +591,7 @@ class _ModelCard extends ConsumerWidget {
591
return AlertDialog(
592
title: Row(
593
children: [
593
- const Icon(Icons.warning_amber_rounded, color: Colors.orange),
594
+ const HugeIcon(icon: HugeIcons.strokeRoundedAlertCircle, color: Colors.orange),
595
const SizedBox(width: 8),
596
Text(dialogL10n.ram_warning),
597
],
@@ -617,4 +618,4 @@ class _ModelCard extends ConsumerWidget {
618
);
619
return result ?? false;
620
}
620
-}
621
+}
\ No newline at end of file
lib/features/onboarding/screens/onboarding_server_setup_screen.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:io' show Platform;
3
4
import 'package:flutter/material.dart';
@@ -324,8 +325,8 @@ class _OnboardingServerSetupScreenState
325
),
326
child: Row(
327
children: [
327
- Icon(
328
- _testSuccess ? Icons.check_circle : Icons.error,
328
+ HugeIcon(icon:
329
+ _testSuccess ? HugeIcons.strokeRoundedCheckmarkCircle01 : HugeIcons.strokeRoundedAlertCircle,
330
color: _testSuccess ? Colors.green : Colors.red,
331
),
332
const SizedBox(width: 8),
@@ -382,4 +383,4 @@ class _OnboardingServerSetupScreenState
383
),
384
);
385
}
385
-}
386
+}
\ No newline at end of file
lib/features/onboarding/screens/onboarding_server_type_screen.dart
+10
-10
@@ -151,8 +151,8 @@ class _OnboardingServerTypeScreenState
151
type: ServerType.onDevice,
152
title: l10n.server_type_on_device,
153
subtitle: l10n.server_type_on_device_desc,
154
- iconWidget: Icon(
155
- Icons.phone_android_rounded,
154
+ iconWidget: HugeIcon(icon:
155
+ HugeIcons.strokeRoundedSmartPhone01,
156
color: _selectedType == ServerType.onDevice
157
? theme.colorScheme.primary
158
: theme.colorScheme.onSurface,
@@ -163,8 +163,8 @@ class _OnboardingServerTypeScreenState
163
type: ServerType.lmStudio,
164
title: l10n.server_type_lm_studio,
165
subtitle: l10n.server_type_lm_studio_desc,
166
- iconWidget: Icon(
167
- Icons.terminal_rounded,
166
+ iconWidget: HugeIcon(icon:
167
+ HugeIcons.strokeRoundedComputerTerminal01,
168
color: _selectedType == ServerType.lmStudio
169
? theme.colorScheme.primary
170
: theme.colorScheme.onSurface,
@@ -189,8 +189,8 @@ class _OnboardingServerTypeScreenState
189
type: ServerType.ollama,
190
title: l10n.server_type_ollama,
191
subtitle: l10n.server_type_ollama_desc,
192
- iconWidget: Icon(
193
- Icons.smart_toy_rounded,
192
+ iconWidget: HugeIcon(icon:
193
+ HugeIcons.strokeRoundedRobot01,
194
color: _selectedType == ServerType.ollama
195
? theme.colorScheme.primary
196
: theme.colorScheme.onSurface,
@@ -367,8 +367,8 @@ class _OnboardingServerTypeScreenState
367
),
368
const Spacer(),
369
if (disabled)
370
- const Icon(
371
- Icons.lock_outline_rounded,
370
+ const HugeIcon(icon:
371
+ HugeIcons.strokeRoundedLock,
372
size: 18,
373
color: Colors.orange,
374
),
@@ -451,8 +451,8 @@ class _OnboardingServerTypeScreenState
451
),
452
borderRadius: BorderRadius.circular(11),
453
),
454
- child: Icon(
455
- Icons.add_rounded,
454
+ child: HugeIcon(icon:
455
+ HugeIcons.strokeRoundedAdd01,
456
size: 18,
457
color: theme.colorScheme.primary,
458
),
lib/features/onboarding/screens/onboarding_theme_screen.dart
+2
-2
@@ -29,7 +29,7 @@ class _OnboardingThemeScreenState extends ConsumerState<OnboardingThemeScreen> {
29
appBar: AppBar(
30
title: Text(l10n.choose_theme),
31
leading: IconButton(
32
- icon: const Icon(Icons.arrow_back),
32
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedArrowLeft01),
33
onPressed: () {
34
context.pop();
35
},
@@ -213,7 +213,7 @@ class _OnboardingThemeScreenState extends ConsumerState<OnboardingThemeScreen> {
213
),
214
),
215
if (isSelected)
216
- Icon(Icons.check_circle, color: theme.colorScheme.primary),
216
+ HugeIcon(icon: HugeIcons.strokeRoundedCheckmarkCircle01, color: theme.colorScheme.primary),
217
],
218
),
219
),
lib/features/personas/views/create_persona_screen.dart
+7
-6
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -172,7 +173,7 @@ class _CreatePersonaScreenState extends ConsumerState<CreatePersonaScreen> {
173
appBar: AppBar(
174
title: Text(_isEditing ? l10n.edit_persona : l10n.create_persona),
175
leading: IconButton(
175
- icon: const Icon(Icons.close),
176
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
177
onPressed: () => context.pop(),
178
),
179
actions: [
@@ -315,8 +316,8 @@ class _CreatePersonaScreenState extends ConsumerState<CreatePersonaScreen> {
316
),
317
const SizedBox(width: 8),
318
IconButton(
318
- icon: Icon(
319
- _showPreview ? Icons.edit : Icons.visibility,
319
+ icon: HugeIcon(icon:
320
+ _showPreview ? HugeIcons.strokeRoundedPencilEdit02 : HugeIcons.strokeRoundedEye,
321
size: 18,
322
),
323
tooltip: _showPreview ? l10n.edit : l10n.preview,
@@ -382,8 +383,8 @@ class _CreatePersonaScreenState extends ConsumerState<CreatePersonaScreen> {
383
onTap: () => setState(() => _showAdvanced = !_showAdvanced),
384
child: Row(
385
children: [
385
- Icon(
386
- _showAdvanced ? Icons.expand_less : Icons.expand_more,
386
+ HugeIcon(icon:
387
+ _showAdvanced ? HugeIcons.strokeRoundedArrowUp01 : HugeIcons.strokeRoundedArrowDown01,
388
color: isDark
389
? const Color(0xFF888888)
390
: const Color(0xFF999999),
@@ -477,4 +478,4 @@ class _CreatePersonaScreenState extends ConsumerState<CreatePersonaScreen> {
478
),
479
);
480
}
480
-}
481
+}
\ No newline at end of file
lib/features/personas/views/persona_list_screen.dart
+14
-13
@@ -1,4 +1,5 @@
1
import "package:localmind/core/theme/colors.dart";
2
+import 'package:hugeicons/hugeicons.dart';
3
import 'package:flutter/material.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
5
import 'package:go_router/go_router.dart';
@@ -49,7 +50,7 @@ class PersonaListScreen extends ConsumerWidget {
50
children: [
51
Builder(
52
builder: (context) => IconButton(
52
- icon: const Icon(Icons.menu),
53
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
54
onPressed: () => Scaffold.of(context).openDrawer(),
55
),
56
),
@@ -64,10 +65,10 @@ class PersonaListScreen extends ConsumerWidget {
65
),
66
const Spacer(),
67
IconButton(
67
- icon: Icon(
68
+ icon: HugeIcon(icon:
69
previewSystemPrompts
69
- ? Icons.visibility
70
- : Icons.visibility_outlined,
70
+ ? HugeIcons.strokeRoundedEye
71
+ : HugeIcons.strokeRoundedEye,
72
),
73
tooltip: l10n.preview_system_prompts,
74
onPressed: () => ref
@@ -215,7 +216,7 @@ class PersonaListScreen extends ConsumerWidget {
216
end: 24,
217
child: FloatingActionButton(
218
onPressed: () => context.push(AppRoutes.createPersona),
218
- child: const Icon(Icons.add),
219
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
220
),
221
),
222
],
@@ -238,7 +239,7 @@ class PersonaListScreen extends ConsumerWidget {
239
children: [
240
if (!isBuiltIn)
241
ListTile(
241
- leading: const Icon(Icons.edit),
242
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedPencilEdit02),
243
title: Text(sheetL10n.edit),
244
onTap: () {
245
Navigator.pop(ctx);
@@ -246,7 +247,7 @@ class PersonaListScreen extends ConsumerWidget {
247
},
248
),
249
ListTile(
249
- leading: const Icon(Icons.delete_outline, color: Colors.red),
250
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red),
251
title: Text(
252
sheetL10n.delete,
253
style: const TextStyle(color: Colors.red),
@@ -288,7 +289,7 @@ class PersonaListScreen extends ConsumerWidget {
289
},
290
),
291
ListTile(
291
- leading: const Icon(Icons.copy),
292
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCopy),
293
title: Text(sheetL10n.clone_edit),
294
onTap: () {
295
Navigator.pop(ctx);
@@ -481,8 +482,8 @@ class _PersonaCard extends StatelessWidget {
482
),
483
),
484
const SizedBox(width: 8),
484
- Icon(
485
- Icons.chevron_right,
485
+ HugeIcon(icon:
486
+ HugeIcons.strokeRoundedArrowRight01,
487
size: 20,
488
color: isDark ? const Color(0xFF555555) : const Color(0xFFCCCCCC),
489
),
@@ -506,8 +507,8 @@ class _EmptyState extends StatelessWidget {
507
child: Column(
508
mainAxisAlignment: MainAxisAlignment.center,
509
children: [
509
- Icon(
510
- Icons.smart_toy_outlined,
510
+ HugeIcon(icon:
511
+ HugeIcons.strokeRoundedRobot01,
512
size: 64,
513
color: isDark ? const Color(0xFF444444) : const Color(0xFFCCCCCC),
514
),
@@ -536,4 +537,4 @@ class _EmptyState extends StatelessWidget {
537
),
538
);
539
}
539
-}
540
+}
\ No newline at end of file
lib/features/saved_messages/views/components/save_message_sheet.dart
+9
-8
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:shadcn_ui/shadcn_ui.dart';
@@ -43,20 +44,20 @@ Future<void> showSaveMessageSheet(
44
),
45
),
46
ListTile(
46
- leading: Icon(
47
+ leading: HugeIcon(icon:
48
selectedFolderId == null
48
- ? Icons.radio_button_checked
49
- : Icons.radio_button_off,
49
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
50
+ : HugeIcons.strokeRoundedCircle,
51
),
52
title: Text(l10n.unfiled_chats),
53
onTap: () => setState(() => selectedFolderId = null),
54
),
55
...folders.map(
56
(folder) => ListTile(
56
- leading: Icon(
57
+ leading: HugeIcon(icon:
58
selectedFolderId == folder.id
58
- ? Icons.radio_button_checked
59
- : Icons.radio_button_off,
59
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
60
+ : HugeIcons.strokeRoundedCircle,
61
),
62
title: Text(folder.name),
63
onTap: () => setState(() => selectedFolderId = folder.id),
@@ -72,7 +73,7 @@ Future<void> showSaveMessageSheet(
73
ref.invalidate(isMessageSavedProvider(message.id));
74
if (context.mounted) Navigator.pop(context);
75
},
75
- icon: const Icon(Icons.bookmark_remove_outlined),
76
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedBookmarkRemove01),
77
label: Text(l10n.remove_from_saved),
78
),
79
const SizedBox(height: 8),
@@ -95,4 +96,4 @@ Future<void> showSaveMessageSheet(
96
},
97
),
98
);
98
-}
99
+}
\ No newline at end of file
lib/features/saved_messages/views/components/saved_message_folder_sheet.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:localmind/l10n/app_localizations.dart';
@@ -27,7 +28,7 @@ Future<void> showSavedMessagesBulkMoveToFolderSheet(
28
mainAxisSize: MainAxisSize.min,
29
children: [
30
ListTile(
30
- leading: const Icon(Icons.folder_off_outlined),
31
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
32
title: Text(l10n.remove_from_folder),
33
onTap: () async {
34
Navigator.pop(ctx);
@@ -40,7 +41,7 @@ Future<void> showSavedMessagesBulkMoveToFolderSheet(
41
),
42
...folders.map(
43
(folder) => ListTile(
43
- leading: const Icon(Icons.folder_outlined),
44
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
45
title: Text(folder.name),
46
onTap: () async {
47
Navigator.pop(ctx);
@@ -58,4 +59,4 @@ Future<void> showSavedMessagesBulkMoveToFolderSheet(
59
);
60
},
61
);
61
-}
62
+}
\ No newline at end of file
lib/features/saved_messages/views/components/saved_message_picker_tile.dart
+5
-4
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:localmind/core/models/enums.dart';
4
import 'package:localmind/core/theme/colors.dart';
@@ -34,10 +35,10 @@ class SavedMessagePickerTile extends StatelessWidget {
35
child: Row(
36
crossAxisAlignment: CrossAxisAlignment.start,
37
children: [
37
- Icon(
38
+ HugeIcon(icon:
39
isUser
39
- ? Icons.person_outline
40
- : Icons.auto_awesome_outlined,
40
+ ? HugeIcons.strokeRoundedUser
41
+ : HugeIcons.strokeRoundedSparkles,
42
size: 20,
43
color: mutedColor,
44
),
@@ -91,4 +92,4 @@ class SavedMessagePickerTile extends StatelessWidget {
92
),
93
);
94
}
94
-}
95
+}
\ No newline at end of file
lib/features/saved_messages/views/components/saved_message_tile.dart
+13
-13
@@ -46,8 +46,8 @@ class SavedMessageTile extends StatelessWidget {
46
alignment: AlignmentDirectional.centerStart,
47
padding: const EdgeInsetsDirectional.only(start: 16),
48
color: Colors.blue,
49
- child: Icon(
50
- saved.isArchived ? Icons.unarchive_outlined : Icons.archive_outlined,
49
+ child: HugeIcon(icon:
50
+ saved.isArchived ? HugeIcons.strokeRoundedArchive : HugeIcons.strokeRoundedArchive,
51
color: Colors.white,
52
),
53
),
@@ -55,7 +55,7 @@ class SavedMessageTile extends StatelessWidget {
55
alignment: AlignmentDirectional.centerEnd,
56
padding: const EdgeInsetsDirectional.only(end: 16),
57
color: Colors.red,
58
- child: const Icon(Icons.delete, color: Colors.white),
58
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.white),
59
),
60
confirmDismiss: (direction) async {
61
if (direction == DismissDirection.startToEnd) {
@@ -78,10 +78,10 @@ class SavedMessageTile extends StatelessWidget {
78
if (selectionMode)
79
Checkbox(value: isSelected, onChanged: (_) => onTap())
80
else
81
- Icon(
81
+ HugeIcon(icon:
82
isUser
83
- ? Icons.person_outline
84
- : Icons.auto_awesome_outlined,
83
+ ? HugeIcons.strokeRoundedUser
84
+ : HugeIcons.strokeRoundedSparkles,
85
size: 20,
86
color: mutedColor,
87
),
@@ -164,7 +164,7 @@ class SavedMessageTile extends StatelessWidget {
164
children: [
165
if (onEnterSelectionMode != null)
166
ListTile(
167
- leading: const Icon(Icons.checklist_outlined),
167
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCheckList),
168
title: Text(l10n.select),
169
onTap: () {
170
Navigator.pop(ctx);
@@ -172,7 +172,7 @@ class SavedMessageTile extends StatelessWidget {
172
},
173
),
174
ListTile(
175
- leading: const Icon(Icons.copy_outlined),
175
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedCopy),
176
title: Text(l10n.copy),
177
onTap: () {
178
Navigator.pop(ctx);
@@ -180,7 +180,7 @@ class SavedMessageTile extends StatelessWidget {
180
},
181
),
182
ListTile(
183
- leading: const Icon(Icons.folder_outlined),
183
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
184
title: Text(l10n.move_to_folder),
185
onTap: () {
186
Navigator.pop(ctx);
@@ -188,10 +188,10 @@ class SavedMessageTile extends StatelessWidget {
188
},
189
),
190
ListTile(
191
- leading: Icon(
191
+ leading: HugeIcon(icon:
192
saved.isArchived
193
- ? Icons.unarchive_outlined
194
- : Icons.archive_outlined,
193
+ ? HugeIcons.strokeRoundedArchive
194
+ : HugeIcons.strokeRoundedArchive,
195
),
196
title: Text(
197
saved.isArchived ? l10n.unarchive_chat : l10n.archive_chat,
@@ -202,7 +202,7 @@ class SavedMessageTile extends StatelessWidget {
202
},
203
),
204
ListTile(
205
- leading: const Icon(Icons.delete_outline, color: Colors.red),
205
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red),
206
title: Text(
207
l10n.delete,
208
style: const TextStyle(color: Colors.red),
lib/features/saved_messages/views/saved_messages_screen.dart
+11
-10
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter/services.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -50,7 +51,7 @@ class SavedMessagesScreen extends ConsumerWidget {
51
? Row(
52
children: [
53
IconButton(
53
- icon: const Icon(Icons.close),
54
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
55
onPressed: () => ref
56
.read(savedMessageSelectionModeProvider.notifier)
57
.disable(),
@@ -66,7 +67,7 @@ class SavedMessagesScreen extends ConsumerWidget {
67
),
68
),
69
IconButton(
69
- icon: const Icon(Icons.folder_outlined),
70
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01),
71
tooltip: l10n.move_to_folder,
72
onPressed: selectedIds.isEmpty
73
? null
@@ -79,7 +80,7 @@ class SavedMessagesScreen extends ConsumerWidget {
80
children: [
81
Builder(
82
builder: (context) => IconButton(
82
- icon: const Icon(Icons.menu),
83
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
84
onPressed: () => Scaffold.of(context).openDrawer(),
85
),
86
),
@@ -94,7 +95,7 @@ class SavedMessagesScreen extends ConsumerWidget {
95
),
96
const Spacer(),
97
IconButton(
97
- icon: const Icon(Icons.checklist_outlined),
98
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCheckList),
99
tooltip: l10n.select,
100
onPressed: () => ref
101
.read(savedMessageSelectionModeProvider.notifier)
@@ -110,27 +111,27 @@ class SavedMessagesScreen extends ConsumerWidget {
111
ListFilterOption(
112
value: SavedMessageListFilter.all,
113
label: l10n.all_chats,
113
- icon: Icons.view_list_rounded,
114
+ icon: HugeIcons.strokeRoundedView,
115
),
116
ListFilterOption(
117
value: SavedMessageListFilter.tempChats,
118
label: l10n.filter_temp_chats,
118
- icon: Icons.bolt_outlined,
119
+ icon: HugeIcons.strokeRoundedZap,
120
),
121
ListFilterOption(
122
value: SavedMessageListFilter.user,
123
label: l10n.filter_user_messages,
123
- icon: Icons.person_outline,
124
+ icon: HugeIcons.strokeRoundedUser,
125
),
126
ListFilterOption(
127
value: SavedMessageListFilter.assistant,
128
label: l10n.filter_assistant_messages,
128
- icon: Icons.auto_awesome_outlined,
129
+ icon: HugeIcons.strokeRoundedSparkles,
130
),
131
ListFilterOption(
132
value: SavedMessageListFilter.archived,
133
label: l10n.filter_archived,
133
- icon: Icons.archive_outlined,
134
+ icon: HugeIcons.strokeRoundedArchive,
135
),
136
],
137
),
@@ -250,4 +251,4 @@ class SavedMessagesScreen extends ConsumerWidget {
251
],
252
);
253
}
253
-}
254
+}
\ No newline at end of file
lib/features/servers/views/add_server_screen.dart
+11
-11
@@ -287,7 +287,7 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
287
appBar: AppBar(
288
title: Text(_isEditing ? l10n.edit_server : l10n.add_server_title),
289
leading: IconButton(
290
- icon: const Icon(Icons.close),
290
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01),
291
onPressed: () => context.pop(),
292
),
293
),
@@ -379,8 +379,8 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
379
],
380
),
381
),
382
- Icon(
383
- Icons.arrow_forward_ios_rounded,
382
+ HugeIcon(icon:
383
+ HugeIcons.strokeRoundedArrowRight01,
384
size: 16,
385
color: colorScheme.onSurfaceVariant,
386
),
@@ -554,12 +554,12 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
554
children: [
555
_buildInfoPill(
556
context,
557
- icon: Icons.hub_outlined,
557
+ icon: HugeIcons.strokeRoundedShare01,
558
label: _serverTypeLabel(context),
559
),
560
_buildInfoPill(
561
context,
562
- icon: _requiresMandatoryApiKey ? Icons.key_outlined : Icons.dns,
562
+ icon: _requiresMandatoryApiKey ? HugeIcons.strokeRoundedKey01 : HugeIcons.strokeRoundedDatabase,
563
label: _requiresMandatoryApiKey
564
? l10n.api_key_required
565
: l10n.host_label,
@@ -629,8 +629,8 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
629
child: Row(
630
crossAxisAlignment: CrossAxisAlignment.start,
631
children: [
632
- Icon(
633
- success ? Icons.check_circle_rounded : Icons.error_rounded,
632
+ HugeIcon(icon:
633
+ success ? HugeIcons.strokeRoundedCheckmarkCircle01 : HugeIcons.strokeRoundedAlertCircle,
634
color: accent,
635
),
636
const SizedBox(width: 10),
@@ -692,7 +692,7 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
692
height: 16,
693
child: CircularProgressIndicator(strokeWidth: 2),
694
)
695
- : const Icon(Icons.network_check_rounded),
695
+ : const HugeIcon(icon: HugeIcons.strokeRoundedWifi01),
696
label: Text(_isTesting ? l10n.testing : l10n.test_connection),
697
),
698
),
@@ -712,7 +712,7 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
712
height: 18,
713
child: CircularProgressIndicator(strokeWidth: 2),
714
)
715
- : const Icon(Icons.save_rounded),
715
+ : const HugeIcon(icon: HugeIcons.strokeRoundedFloppyDisk),
716
label: Text(
717
_isSaving
718
? l10n.save
@@ -729,7 +729,7 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
729
730
Widget _buildInfoPill(
731
BuildContext context, {
732
- required IconData icon,
732
+ required List<List<dynamic>> icon,
733
required String label,
734
}) {
735
final theme = Theme.of(context);
@@ -745,7 +745,7 @@ class _AddServerScreenState extends ConsumerState<AddServerScreen> {
745
child: Row(
746
mainAxisSize: MainAxisSize.min,
747
children: [
748
- Icon(icon, size: 16, color: colorScheme.primary),
748
+ HugeIcon(icon: icon, size: 16, color: colorScheme.primary),
749
const SizedBox(width: 8),
750
Text(
751
label,
lib/features/servers/views/components/https_scheme_hint.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
4
import '../../../../l10n/app_localizations.dart';
@@ -41,8 +42,8 @@ class HttpsSchemeHint extends StatelessWidget {
42
child: Row(
43
crossAxisAlignment: CrossAxisAlignment.start,
44
children: [
44
- Icon(
45
- Icons.lock_outline_rounded,
45
+ HugeIcon(icon:
46
+ HugeIcons.strokeRoundedLock,
47
size: 18,
48
color: colorScheme.tertiary,
49
),
@@ -78,4 +79,4 @@ class HttpsSchemeHint extends StatelessWidget {
79
},
80
);
81
}
81
-}
82
+}
\ No newline at end of file
lib/features/servers/views/components/server_card.dart
+5
-5
@@ -125,8 +125,8 @@ class ServerCard extends StatelessWidget {
125
? activeGreen
126
: theme.colorScheme.onSurfaceVariant,
127
)
128
- : Icon(
129
- Icons.dns,
128
+ : HugeIcon(icon:
129
+ HugeIcons.strokeRoundedDatabase,
130
color: isActive
131
? activeGreen
132
: theme.colorScheme.onSurfaceVariant,
@@ -237,7 +237,7 @@ class ServerCard extends StatelessWidget {
237
value: 'edit',
238
child: Row(
239
children: [
240
- const Icon(Icons.edit, size: 18),
240
+ const HugeIcon(icon: HugeIcons.strokeRoundedPencilEdit02, size: 18),
241
const SizedBox(width: 8),
242
Text(l10n.edit),
243
],
@@ -248,7 +248,7 @@ class ServerCard extends StatelessWidget {
248
value: 'setDefault',
249
child: Row(
250
children: [
251
- const Icon(Icons.star, size: 18),
251
+ const HugeIcon(icon: HugeIcons.strokeRoundedStar, size: 18),
252
const SizedBox(width: 8),
253
Text(l10n.set_as_default),
254
],
@@ -258,7 +258,7 @@ class ServerCard extends StatelessWidget {
258
value: 'delete',
259
child: Row(
260
children: [
261
- const Icon(Icons.delete, size: 18, color: Colors.red),
261
+ const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, size: 18, color: Colors.red),
262
const SizedBox(width: 8),
263
Text(l10n.delete, style: const TextStyle(color: Colors.red)),
264
],
lib/features/servers/views/components/server_icon_picker.dart
+1
-1
@@ -131,7 +131,7 @@ class _ServerIconPickerState extends State<ServerIconPicker> {
131
placeholder: Text(l10n.search_icons_hint),
132
leading: const Padding(
133
padding: EdgeInsetsDirectional.only(start: 8),
134
- child: Icon(Icons.search, size: 18),
134
+ child: HugeIcon(icon: HugeIcons.strokeRoundedSearch01, size: 18),
135
),
136
onChanged: _filterIcons,
137
),
lib/features/servers/views/components/server_picker_sheet.dart
+6
-6
@@ -69,7 +69,7 @@ void showServerPickerSheet(BuildContext context, WidgetRef ref) {
69
),
70
IconButton(
71
onPressed: () => Navigator.pop(context),
72
- icon: const Icon(Icons.close, size: 20),
72
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 20),
73
visualDensity: VisualDensity.compact,
74
color: colorScheme.onSurfaceVariant,
75
),
@@ -176,14 +176,14 @@ void showServerPickerSheet(BuildContext context, WidgetRef ref) {
176
),
177
),
178
if (isCurrentlyActive)
179
- Icon(
180
- Icons.check_circle,
179
+ HugeIcon(icon:
180
+ HugeIcons.strokeRoundedCheckmarkCircle01,
181
size: 20,
182
color: colorScheme.primary,
183
)
184
else
185
- const Icon(
186
- Icons.chevron_right,
185
+ const HugeIcon(icon:
186
+ HugeIcons.strokeRoundedArrowRight01,
187
size: 20,
188
color: Colors.grey,
189
),
@@ -198,7 +198,7 @@ void showServerPickerSheet(BuildContext context, WidgetRef ref) {
198
const SizedBox(height: 12),
199
ShadButton.ghost(
200
width: double.infinity,
201
- leading: const Icon(Icons.settings, size: 18),
201
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedSettings01, size: 18),
202
onPressed: () {
203
Navigator.pop(context);
204
context.go(AppRoutes.servers);
lib/features/servers/views/components/server_type_selector.dart
+2
-2
@@ -135,8 +135,8 @@ class ServerTypeSelector extends StatelessWidget {
135
PositionedDirectional(
136
top: 6,
137
end: 6,
138
- child: Icon(
139
- Icons.check_circle,
138
+ child: HugeIcon(icon:
139
+ HugeIcons.strokeRoundedCheckmarkCircle01,
140
size: 17,
141
color: accentColor,
142
),
lib/features/servers/views/server_list_screen.dart
+8
-7
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -49,7 +50,7 @@ class ServerListScreen extends ConsumerWidget {
50
children: [
51
Builder(
52
builder: (context) => IconButton(
52
- icon: const Icon(Icons.menu),
53
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
54
onPressed: () => Scaffold.of(context).openDrawer(),
55
),
56
),
@@ -138,8 +139,8 @@ class ServerListScreen extends ConsumerWidget {
139
child: Column(
140
mainAxisAlignment: MainAxisAlignment.center,
141
children: [
141
- const Icon(
142
- Icons.error_outline,
142
+ const HugeIcon(icon:
143
+ HugeIcons.strokeRoundedInformationCircle,
144
color: Colors.red,
145
size: 48,
146
),
@@ -161,7 +162,7 @@ class ServerListScreen extends ConsumerWidget {
162
end: 24,
163
child: FloatingActionButton(
164
onPressed: () => context.push(AppRoutes.addServer),
164
- child: const Icon(Icons.add),
165
+ child: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
166
),
167
),
168
],
@@ -179,7 +180,7 @@ class ServerListScreen extends ConsumerWidget {
180
child: Column(
181
mainAxisAlignment: MainAxisAlignment.center,
182
children: [
182
- Icon(Icons.computer, size: 80, color: theme.colorScheme.outline),
183
+ HugeIcon(icon: HugeIcons.strokeRoundedComputer, size: 80, color: theme.colorScheme.outline),
184
const SizedBox(height: 24),
185
Text(l10n.no_servers_yet, style: theme.textTheme.headlineSmall),
186
const SizedBox(height: 8),
@@ -193,7 +194,7 @@ class ServerListScreen extends ConsumerWidget {
194
const SizedBox(height: 24),
195
ElevatedButton.icon(
196
onPressed: () => context.push(AppRoutes.addServer),
196
- icon: const Icon(Icons.add),
197
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01),
198
label: Text(l10n.add_server),
199
),
200
],
@@ -237,4 +238,4 @@ class ServerListScreen extends ConsumerWidget {
238
},
239
);
240
}
240
-}
241
+}
\ No newline at end of file
lib/features/settings/views/data_backup_actions.dart
+4
-3
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:convert';
3
import 'dart:io';
4
import 'dart:typed_data';
@@ -312,7 +313,7 @@ class DataBackupActions extends ConsumerWidget {
313
'localmind_backup_${DateTime.now().millisecondsSinceEpoch}.zip',
314
),
315
width: double.infinity,
315
- leading: const Icon(Icons.folder_zip_outlined, size: 16),
316
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedFolder01, size: 16),
317
child: Align(
318
alignment: Alignment.centerLeft,
319
child: Text(l10n.export_all_zip),
@@ -322,7 +323,7 @@ class DataBackupActions extends ConsumerWidget {
323
ShadButton.outline(
324
onPressed: () => _importZipFile(context, ref),
325
width: double.infinity,
325
- leading: const Icon(Icons.unarchive_outlined, size: 16),
326
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedArchive, size: 16),
327
child: Align(
328
alignment: Alignment.centerLeft,
329
child: Text(l10n.import_all_zip),
@@ -331,4 +332,4 @@ class DataBackupActions extends ConsumerWidget {
332
],
333
);
334
}
334
-}
335
+}
\ No newline at end of file
lib/features/settings/views/settings_screen.dart
+81
-74
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:go_router/go_router.dart';
@@ -62,7 +63,7 @@ class SettingsViews extends ConsumerWidget {
63
children: [
64
Builder(
65
builder: (context) => IconButton(
65
- icon: const Icon(Icons.menu),
66
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
67
onPressed: () => Scaffold.of(context).openDrawer(),
68
),
69
),
@@ -89,7 +90,7 @@ class SettingsViews extends ConsumerWidget {
90
91
final appearanceCard = _SettingsSectionCard(
92
title: l10n.settings_appearance,
92
- icon: Icons.palette_outlined,
93
+ icon: HugeIcons.strokeRoundedPaintBrush02,
94
accent: const Color(0xFF8B5CF6),
95
children: [
96
_ThemeToggle(ref: ref),
@@ -130,7 +131,7 @@ class SettingsViews extends ConsumerWidget {
131
132
final ttsCard = _SettingsSectionCard(
133
title: l10n.settings_tts,
133
- icon: Icons.graphic_eq_rounded,
134
+ icon: HugeIcons.strokeRoundedVoice,
135
accent: const Color(0xFF0EA5E9),
136
children: [
137
_EngineDropdown(
@@ -139,7 +140,7 @@ class SettingsViews extends ConsumerWidget {
140
ref.read(settingsProvider.notifier).setTtsEngine(value),
141
),
142
_SectionActionButton(
142
- icon: Icons.record_voice_over_outlined,
143
+ icon: HugeIcons.strokeRoundedVoice,
144
label: l10n.manage_tts_models,
145
onPressed: () => context.push(AppRoutes.ttsModels),
146
),
@@ -183,7 +184,7 @@ class SettingsViews extends ConsumerWidget {
184
185
final behaviorCard = _SettingsSectionCard(
186
title: l10n.settings_behavior,
186
- icon: Icons.tune_rounded,
187
+ icon: HugeIcons.strokeRoundedSlidersHorizontal,
188
accent: const Color(0xFF22C55E),
189
children: [
190
_ToggleSetting(
@@ -298,7 +299,7 @@ class SettingsViews extends ConsumerWidget {
299
300
final onDeviceCard = _SettingsSectionCard(
301
title: l10n.settings_on_device,
301
- icon: Icons.memory_rounded,
302
+ icon: HugeIcons.strokeRoundedCpu,
303
accent: const Color(0xFFF97316),
304
children: [
305
_ToggleSetting(
@@ -344,7 +345,7 @@ class SettingsViews extends ConsumerWidget {
345
},
346
),
347
_SectionActionButton(
347
- icon: Icons.phone_android_rounded,
348
+ icon: HugeIcons.strokeRoundedSmartPhone01,
349
label: l10n.manage_on_device_models,
350
onPressed: () => context.push(AppRoutes.onDeviceModels),
351
),
@@ -361,7 +362,7 @@ class SettingsViews extends ConsumerWidget {
362
363
final defaultsCard = _SettingsSectionCard(
364
title: l10n.settings_default_server,
364
- icon: Icons.hub_outlined,
365
+ icon: HugeIcons.strokeRoundedShare01,
366
accent: const Color(0xFF06B6D4),
367
children: [
368
_DropdownSetting(
@@ -371,7 +372,7 @@ class SettingsViews extends ConsumerWidget {
372
onChanged: (value) => ref
373
.read(settingsProvider.notifier)
374
.setDefaultServer(value),
374
- icon: Icons.computer_rounded,
375
+ icon: HugeIcons.strokeRoundedComputer,
376
),
377
_DropdownSetting(
378
label: l10n.settings_default_persona,
@@ -380,11 +381,11 @@ class SettingsViews extends ConsumerWidget {
381
onChanged: (value) => ref
382
.read(settingsProvider.notifier)
383
.setDefaultPersona(value),
383
- icon: Icons.smart_toy_outlined,
384
+ icon: HugeIcons.strokeRoundedRobot01,
385
),
386
const SizedBox(height: 8),
387
_SectionActionButton(
387
- icon: Icons.restore_rounded,
388
+ icon: HugeIcons.strokeRoundedRefresh,
389
label: l10n.restore_builtin_personas,
390
onPressed: () async {
391
await ref
@@ -405,7 +406,7 @@ class SettingsViews extends ConsumerWidget {
406
407
final privacyCard = _SettingsSectionCard(
408
title: l10n.settings_privacy,
408
- icon: Icons.lock_outline_rounded,
409
+ icon: HugeIcons.strokeRoundedLock,
410
accent: const Color(0xFF14B8A6),
411
children: [
412
_ToggleSetting(
@@ -421,20 +422,20 @@ class SettingsViews extends ConsumerWidget {
422
423
final dataCard = _SettingsSectionCard(
424
title: l10n.settings_data_management,
424
- icon: Icons.restore_page_outlined,
425
+ icon: HugeIcons.strokeRoundedRefresh,
426
accent: const Color(0xFFEF4444),
427
children: [
428
const DataBackupActions(),
429
const SizedBox(height: 8),
430
_DangerousAction(
431
label: l10n.delete_all_conversations,
431
- icon: Icons.delete_outline_rounded,
432
+ icon: HugeIcons.strokeRoundedDelete01,
433
onConfirm: () =>
434
ref.read(conversationsProvider.notifier).deleteAll(),
435
),
436
_DangerousAction(
437
label: l10n.reset_settings_defaults,
437
- icon: Icons.restore_rounded,
438
+ icon: HugeIcons.strokeRoundedRefresh,
439
onConfirm: () =>
440
ref.read(settingsProvider.notifier).resetToDefaults(),
441
),
@@ -443,7 +444,7 @@ class SettingsViews extends ConsumerWidget {
444
445
final aboutCard = _SettingsSectionCard(
446
title: l10n.settings_about,
446
- icon: Icons.info_outline_rounded,
447
+ icon: HugeIcons.strokeRoundedInformationCircle,
448
accent: const Color(0xFFF59E0B),
449
children: [
450
_AboutPanel(
@@ -588,10 +589,12 @@ class _SettingsHero extends StatelessWidget {
589
color: primary.withValues(alpha: 0.10),
590
borderRadius: BorderRadius.circular(12),
591
),
591
- child: Icon(
592
- Icons.settings_outlined,
593
- size: 18,
594
- color: primary,
592
+ child: Center(
593
+ child: HugeIcon(icon:
594
+ HugeIcons.strokeRoundedSettings01,
595
+ size: 18,
596
+ color: primary,
597
+ ),
598
),
599
),
600
const SizedBox(width: 10),
@@ -621,17 +624,17 @@ class _SettingsHero extends StatelessWidget {
624
_HeroStat(
625
label: l10n.theme,
626
value: _themeLabel(themeType, l10n),
624
- icon: Icons.auto_awesome_rounded,
627
+ icon: HugeIcons.strokeRoundedSparkles,
628
),
629
_HeroStat(
630
label: l10n.settings_language,
631
value: _languageLabel(settings.localeCode, l10n),
629
- icon: Icons.language_rounded,
632
+ icon: HugeIcons.strokeRoundedGlobe,
633
),
634
_HeroStat(
635
label: l10n.tts_engine,
636
value: _engineLabel(settings.ttsEngine, l10n),
634
- icon: Icons.record_voice_over_rounded,
637
+ icon: HugeIcons.strokeRoundedVoice,
638
),
639
],
640
),
@@ -651,7 +654,7 @@ class _HeroStat extends StatelessWidget {
654
655
final String label;
656
final String value;
654
- final IconData icon;
657
+ final List<List<dynamic>> icon;
658
659
@override
660
Widget build(BuildContext context) {
@@ -659,7 +662,7 @@ class _HeroStat extends StatelessWidget {
662
final primary = _primaryColor(context);
663
664
return Container(
662
- padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
665
+ padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
666
decoration: BoxDecoration(
667
color: _panelColor(context),
668
borderRadius: BorderRadius.circular(12),
@@ -668,7 +671,7 @@ class _HeroStat extends StatelessWidget {
671
child: Row(
672
mainAxisSize: MainAxisSize.min,
673
children: [
671
- Icon(icon, size: 14, color: primary),
674
+ HugeIcon(icon: icon, size: 14, color: primary),
675
const SizedBox(width: 8),
676
Text(
677
'$label: ',
@@ -701,7 +704,7 @@ class _SettingsSectionCard extends StatelessWidget {
704
});
705
706
final String title;
704
- final IconData icon;
707
+ final List<List<dynamic>> icon;
708
final Color accent;
709
final List<Widget> children;
710
@@ -727,7 +730,9 @@ class _SettingsSectionCard extends StatelessWidget {
730
color: accent.withValues(alpha: 0.10),
731
borderRadius: BorderRadius.circular(10),
732
),
730
- child: Icon(icon, color: accent, size: 16),
733
+ child: Center(
734
+ child: HugeIcon(icon: icon, color: accent, size: 16),
735
+ ),
736
),
737
const SizedBox(width: 10),
738
Expanded(
@@ -779,8 +784,8 @@ class _MutedCallout extends StatelessWidget {
784
child: Row(
785
crossAxisAlignment: CrossAxisAlignment.start,
786
children: [
782
- Icon(
783
- Icons.shield_moon_outlined,
787
+ HugeIcon(icon:
788
+ HugeIcons.strokeRoundedMoon02,
789
size: 18,
790
color: _mutedColor(context),
791
),
@@ -849,7 +854,7 @@ class _AboutPanel extends StatelessWidget {
854
children: providers
855
.map(
856
(provider) =>
852
- _AboutChip(label: provider, icon: Icons.hub_outlined),
857
+ _AboutChip(label: provider, icon: HugeIcons.strokeRoundedShare01),
858
)
859
.toList(),
860
),
@@ -863,7 +868,7 @@ class _AboutPanel extends StatelessWidget {
868
.map(
869
(highlight) => _AboutChip(
870
label: highlight,
866
- icon: Icons.check_circle_outline_rounded,
871
+ icon: HugeIcons.strokeRoundedCheckmarkCircle01,
872
),
873
)
874
.toList(),
@@ -876,7 +881,7 @@ class _AboutPanel extends StatelessWidget {
881
runSpacing: 6,
882
children: stack
883
.map(
879
- (item) => _AboutChip(label: item, icon: Icons.code_rounded),
884
+ (item) => _AboutChip(label: item, icon: HugeIcons.strokeRoundedCode),
885
)
886
.toList(),
887
),
@@ -892,8 +897,8 @@ class _AboutPanel extends StatelessWidget {
897
child: Row(
898
crossAxisAlignment: CrossAxisAlignment.start,
899
children: [
895
- Icon(
896
- Icons.open_in_new_rounded,
900
+ HugeIcon(icon:
901
+ HugeIcons.strokeRoundedShare01,
902
size: 15,
903
color: _mutedColor(context),
904
),
@@ -937,7 +942,7 @@ class _AboutChip extends StatelessWidget {
942
const _AboutChip({required this.label, required this.icon});
943
944
final String label;
940
- final IconData icon;
945
+ final List<List<dynamic>> icon;
946
947
@override
948
Widget build(BuildContext context) {
@@ -951,7 +956,7 @@ class _AboutChip extends StatelessWidget {
956
child: Row(
957
mainAxisSize: MainAxisSize.min,
958
children: [
954
- Icon(icon, size: 13, color: _mutedColor(context)),
959
+ HugeIcon(icon: icon, size: 13, color: _mutedColor(context)),
960
const SizedBox(width: 6),
961
Text(
962
label,
@@ -1008,8 +1013,8 @@ class _LanguageSetting extends StatelessWidget {
1013
value: null,
1014
child: Row(
1015
children: [
1011
- Icon(
1012
- Icons.settings_suggest_outlined,
1016
+ HugeIcon(icon:
1017
+ HugeIcons.strokeRoundedSettings01,
1018
size: 18,
1019
color: _mutedColor(context),
1020
),
@@ -1167,7 +1172,7 @@ class _SliderSetting extends StatelessWidget {
1172
const SizedBox(height: 8),
1173
Container(
1174
width: double.infinity,
1170
- padding: const EdgeInsets.all(10),
1175
+ padding: const EdgeInsets.all(14),
1176
decoration: BoxDecoration(
1177
color: theme.scaffoldBackgroundColor.withValues(alpha: 0.65),
1178
borderRadius: BorderRadius.circular(12),
@@ -1425,7 +1430,7 @@ class _ThemeToggle extends StatelessWidget {
1430
width: itemWidth,
1431
child: _ThemeOption(
1432
label: l10n.theme_system,
1428
- icon: Icons.brightness_auto_rounded,
1433
+ icon: HugeIcons.strokeRoundedSun01,
1434
isSelected: currentTheme == AppThemeType.system,
1435
onTap: () => ref
1436
.read(themeModeProvider.notifier)
@@ -1436,7 +1441,7 @@ class _ThemeToggle extends StatelessWidget {
1441
width: itemWidth,
1442
child: _ThemeOption(
1443
label: l10n.theme_light,
1439
- icon: Icons.light_mode_rounded,
1444
+ icon: HugeIcons.strokeRoundedSun01,
1445
isSelected: currentTheme == AppThemeType.light,
1446
onTap: () => ref
1447
.read(themeModeProvider.notifier)
@@ -1447,7 +1452,7 @@ class _ThemeToggle extends StatelessWidget {
1452
width: itemWidth,
1453
child: _ThemeOption(
1454
label: l10n.theme_dark,
1450
- icon: Icons.dark_mode_rounded,
1455
+ icon: HugeIcons.strokeRoundedMoon02,
1456
isSelected: currentTheme == AppThemeType.dark,
1457
onTap: () => ref
1458
.read(themeModeProvider.notifier)
@@ -1458,7 +1463,7 @@ class _ThemeToggle extends StatelessWidget {
1463
width: itemWidth,
1464
child: _ThemeOption(
1465
label: l10n.theme_claude,
1461
- icon: Icons.auto_awesome_rounded,
1466
+ icon: HugeIcons.strokeRoundedSparkles,
1467
isSelected: currentTheme == AppThemeType.claude,
1468
onTap: () => ref
1469
.read(themeModeProvider.notifier)
@@ -1484,7 +1489,7 @@ class _ThemeOption extends StatelessWidget {
1489
});
1490
1491
final String label;
1487
- final IconData icon;
1492
+ final List<List<dynamic>> icon;
1493
final bool isSelected;
1494
final VoidCallback onTap;
1495
@@ -1499,7 +1504,7 @@ class _ThemeOption extends StatelessWidget {
1504
onTap: onTap,
1505
borderRadius: BorderRadius.circular(14),
1506
child: Container(
1502
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
1507
+ padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
1508
decoration: BoxDecoration(
1509
color: isSelected
1510
? primary.withValues(alpha: 0.10)
@@ -1520,10 +1525,12 @@ class _ThemeOption extends StatelessWidget {
1525
: _panelColor(context),
1526
borderRadius: BorderRadius.circular(10),
1527
),
1523
- child: Icon(
1524
- icon,
1525
- size: 16,
1526
- color: isSelected ? primary : _mutedColor(context),
1528
+ child: Center(
1529
+ child: HugeIcon(icon:
1530
+ icon,
1531
+ size: 16,
1532
+ color: isSelected ? primary : _mutedColor(context),
1533
+ ),
1534
),
1535
),
1536
const SizedBox(width: 10),
@@ -1536,10 +1543,10 @@ class _ThemeOption extends StatelessWidget {
1543
),
1544
),
1545
),
1539
- Icon(
1546
+ HugeIcon(icon:
1547
isSelected
1541
- ? Icons.check_circle_rounded
1542
- : Icons.radio_button_unchecked_rounded,
1548
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
1549
+ : HugeIcons.strokeRoundedCircle,
1550
size: 16,
1551
color: isSelected ? primary : _mutedColor(context),
1552
),
@@ -1564,7 +1571,7 @@ class _DropdownSetting extends StatelessWidget {
1571
final String? currentValue;
1572
final List<(String id, String name)> items;
1573
final ValueChanged<String?> onChanged;
1567
- final IconData icon;
1574
+ final List<List<dynamic>> icon;
1575
1576
@override
1577
Widget build(BuildContext context) {
@@ -1601,7 +1608,7 @@ class _DropdownSetting extends StatelessWidget {
1608
value: item.$1,
1609
child: Row(
1610
children: [
1604
- Icon(icon, size: 16, color: _mutedColor(context)),
1611
+ HugeIcon(icon: icon, size: 16, color: _mutedColor(context)),
1612
const SizedBox(width: 8),
1613
Flexible(
1614
child: Text(
@@ -1694,7 +1701,7 @@ class _DangerousAction extends StatelessWidget {
1701
});
1702
1703
final String label;
1697
- final IconData icon;
1704
+ final List<List<dynamic>> icon;
1705
final VoidCallback onConfirm;
1706
1707
@override
@@ -1731,7 +1738,7 @@ class _DangerousAction extends StatelessWidget {
1738
},
1739
);
1740
},
1734
- icon: Icon(icon, color: Colors.red, size: 16),
1741
+ icon: HugeIcon(icon: icon, color: Colors.red, size: 16),
1742
label: Align(
1743
alignment: Alignment.centerLeft,
1744
child: Text(label, style: const TextStyle(color: Colors.red)),
@@ -1755,7 +1762,7 @@ class _SectionActionButton extends StatelessWidget {
1762
required this.onPressed,
1763
});
1764
1758
- final IconData icon;
1765
+ final List<List<dynamic>> icon;
1766
final String label;
1767
final VoidCallback onPressed;
1768
@@ -1764,7 +1771,7 @@ class _SectionActionButton extends StatelessWidget {
1771
return ShadButton.outline(
1772
onPressed: onPressed,
1773
width: double.infinity,
1767
- leading: Icon(icon, size: 16),
1774
+ leading: HugeIcon(icon: icon, size: 16),
1775
child: Align(alignment: Alignment.centerLeft, child: Text(label)),
1776
);
1777
}
@@ -1800,19 +1807,19 @@ class _EngineDropdown extends StatelessWidget {
1807
context,
1808
EngineId.system,
1809
l10n.tts_engine_system,
1803
- Icons.record_voice_over_rounded,
1810
+ HugeIcons.strokeRoundedVoice,
1811
),
1812
_engineItem(
1813
context,
1814
EngineId.kitten,
1815
l10n.tts_engine_kitten,
1809
- Icons.auto_awesome_rounded,
1816
+ HugeIcons.strokeRoundedSparkles,
1817
),
1818
_engineItem(
1819
context,
1820
EngineId.piper,
1821
EngineMeta.piper.name,
1815
- Icons.memory_rounded,
1822
+ HugeIcons.strokeRoundedCpu,
1823
),
1824
],
1825
onChanged: (value) {
@@ -1832,14 +1839,14 @@ class _EngineDropdown extends StatelessWidget {
1839
BuildContext context,
1840
EngineId id,
1841
String label,
1835
- IconData icon,
1842
+ List<List<dynamic>> icon,
1843
) {
1844
final meta = EngineMeta.forEngine(id);
1845
return DropdownMenuItem<EngineId>(
1846
value: id,
1847
child: Row(
1848
children: [
1842
- Icon(icon, size: 18, color: Color(meta.accentColor)),
1849
+ HugeIcon(icon: icon, size: 18, color: Color(meta.accentColor)),
1850
const SizedBox(width: 10),
1851
Flexible(child: Text(label, overflow: TextOverflow.ellipsis)),
1852
],
@@ -1996,10 +2003,10 @@ class _VoiceChip extends StatelessWidget {
2003
child: Row(
2004
mainAxisSize: MainAxisSize.min,
2005
children: [
1999
- Icon(
2006
+ HugeIcon(icon:
2007
selected
2001
- ? Icons.radio_button_checked_rounded
2002
- : Icons.radio_button_off_rounded,
2008
+ ? HugeIcons.strokeRoundedCheckmarkCircle01
2009
+ : HugeIcons.strokeRoundedCircle,
2010
size: 16,
2011
color: selected ? primary : _mutedColor(context),
2012
),
@@ -2049,12 +2056,12 @@ class _OnDeviceEngineStatusCard extends ConsumerWidget {
2056
2057
final (
2058
Color accent,
2052
- IconData icon,
2059
+ List<List<dynamic>> icon,
2060
String message,
2061
) = switch (engineState.status) {
2062
OnDeviceEngineStatus.loaded => (
2063
Colors.green,
2057
- Icons.check_circle_rounded,
2064
+ HugeIcons.strokeRoundedCheckmarkCircle01,
2065
l10n.model_loaded(
2066
engineState.loadedModelId ?? 'unknown',
2067
engineState.backend?.name ?? 'CPU',
@@ -2062,17 +2069,17 @@ class _OnDeviceEngineStatusCard extends ConsumerWidget {
2069
),
2070
OnDeviceEngineStatus.loading => (
2071
Colors.blue,
2065
- Icons.hourglass_top_rounded,
2072
+ HugeIcons.strokeRoundedClock01,
2073
l10n.loading,
2074
),
2075
OnDeviceEngineStatus.error => (
2076
Colors.red,
2070
- Icons.error_rounded,
2077
+ HugeIcons.strokeRoundedAlertCircle,
2078
l10n.error_with_message(engineState.error ?? l10n.unknown_error),
2079
),
2080
OnDeviceEngineStatus.notLoaded => (
2081
Colors.grey,
2075
- Icons.info_outline_rounded,
2082
+ HugeIcons.strokeRoundedInformationCircle,
2083
l10n.no_model_loaded,
2084
),
2085
};
@@ -2087,7 +2094,7 @@ class _OnDeviceEngineStatusCard extends ConsumerWidget {
2094
child: Row(
2095
crossAxisAlignment: CrossAxisAlignment.start,
2096
children: [
2090
- Icon(icon, size: 18, color: accent),
2097
+ HugeIcon(icon: icon, size: 18, color: accent),
2098
const SizedBox(width: 8),
2099
Expanded(
2100
child: Text(
@@ -2319,4 +2326,4 @@ String _languageLabel(String? localeCode, AppLocalizations l10n) {
2326
}
2327
2328
return localeCode.toUpperCase();
2322
-}
2329
+}
\ No newline at end of file
lib/features/sidebar/components/active_server_indicator.dart
+7
-7
@@ -153,7 +153,7 @@ class ActiveServerIndicator extends ConsumerWidget {
153
),
154
IconButton(
155
onPressed: () => Navigator.pop(context),
156
- icon: const Icon(Icons.close, size: 20),
156
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedCancel01, size: 20),
157
visualDensity: VisualDensity.compact,
158
color: colorScheme.onSurfaceVariant,
159
),
@@ -285,14 +285,14 @@ class ActiveServerIndicator extends ConsumerWidget {
285
),
286
),
287
if (isCurrentlyActive)
288
- Icon(
289
- Icons.check_circle,
288
+ HugeIcon(icon:
289
+ HugeIcons.strokeRoundedCheckmarkCircle01,
290
size: 20,
291
color: colorScheme.primary,
292
)
293
else
294
- const Icon(
295
- Icons.chevron_right,
294
+ const HugeIcon(icon:
295
+ HugeIcons.strokeRoundedArrowRight01,
296
size: 20,
297
color: Colors.grey,
298
),
@@ -308,7 +308,7 @@ class ActiveServerIndicator extends ConsumerWidget {
308
const SizedBox(height: 12),
309
ShadButton.ghost(
310
width: double.infinity,
311
- leading: const Icon(Icons.settings, size: 18),
311
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedSettings01, size: 18),
312
onPressed: () {
313
Navigator.pop(context);
314
context.go(AppRoutes.servers);
@@ -389,7 +389,7 @@ class ActiveServerIndicator extends ConsumerWidget {
389
],
390
),
391
),
392
- const Icon(Icons.unfold_more, size: 16, color: Colors.grey),
392
+ const HugeIcon(icon: HugeIcons.strokeRoundedArrowUpDown, size: 16, color: Colors.grey),
393
],
394
),
395
),
lib/features/sidebar/components/github_repo_card.dart
+2
-2
@@ -70,8 +70,8 @@ class GitHubRepoCard extends StatelessWidget {
70
],
71
),
72
),
73
- Icon(
74
- Icons.open_in_new,
73
+ HugeIcon(icon:
74
+ HugeIcons.strokeRoundedShare01,
75
size: 14,
76
color: isDark ? AppColors.darkMutedText : AppColors.lightMutedText,
77
),
lib/features/sidebar/components/theme_toggle_button.dart
+8
-7
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter_riverpod/flutter_riverpod.dart';
4
import 'package:shadcn_ui/shadcn_ui.dart';
@@ -28,7 +29,7 @@ class ThemeToggleButton extends ConsumerWidget {
29
),
30
);
31
},
31
- child: Icon(
32
+ child: HugeIcon(icon:
33
_getIconForMode(themeMode),
34
key: ValueKey(themeMode),
35
size: 20,
@@ -37,16 +38,16 @@ class ThemeToggleButton extends ConsumerWidget {
38
);
39
}
40
40
- IconData _getIconForMode(AppThemeType mode) {
41
+ List<List<dynamic>> _getIconForMode(AppThemeType mode) {
42
switch (mode) {
43
case AppThemeType.system:
43
- return LucideIcons.monitor;
44
+ return HugeIcons.strokeRoundedComputer;
45
case AppThemeType.light:
45
- return LucideIcons.sun;
46
+ return HugeIcons.strokeRoundedSun01;
47
case AppThemeType.dark:
47
- return LucideIcons.moon;
48
+ return HugeIcons.strokeRoundedMoon02;
49
case AppThemeType.claude:
49
- return LucideIcons.palmtree;
50
+ return HugeIcons.strokeRoundedTree01;
51
}
52
}
52
-}
53
+}
\ No newline at end of file
lib/features/sidebar/sidebar_widget.dart
+3
-3
@@ -60,7 +60,7 @@ class SidebarWidget extends ConsumerWidget {
60
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
61
child: ShadButton(
62
width: double.infinity,
63
- leading: const Icon(LucideIcons.plus, size: 20),
63
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedAdd01, size: 20),
64
onPressed: () {
65
ref.read(chatProvider.notifier).startNewConversation();
66
context.go(AppRoutes.home);
@@ -78,7 +78,7 @@ class SidebarWidget extends ConsumerWidget {
78
child: isTemporary
79
? ShadButton.outline(
80
width: double.infinity,
81
- leading: const Icon(Icons.arrow_back, size: 18),
81
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedArrowLeft01, size: 18),
82
onPressed: () {
83
if (!isHome) context.go(AppRoutes.home);
84
if (Scaffold.maybeOf(context)?.isDrawerOpen ??
@@ -90,7 +90,7 @@ class SidebarWidget extends ConsumerWidget {
90
)
91
: ShadButton.secondary(
92
width: double.infinity,
93
- leading: const Icon(Icons.arrow_back, size: 18),
93
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedArrowLeft01, size: 18),
94
onPressed: () {
95
if (!isHome) context.go(AppRoutes.home);
96
if (Scaffold.maybeOf(context)?.isDrawerOpen ??
lib/features/tts/views/components/tts_player_bar.dart
+12
-11
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:math' as math;
3
import 'package:flutter/material.dart';
4
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -159,10 +160,10 @@ class TtsPlayerBar extends ConsumerWidget {
160
color: theme.colorScheme.secondary.withValues(alpha: 0.1),
161
borderRadius: BorderRadius.circular(8),
162
),
162
- child: Icon(
163
+ child: HugeIcon(icon:
164
ttsState.isPaused
164
- ? Icons.play_arrow_rounded
165
- : Icons.pause_rounded,
165
+ ? HugeIcons.strokeRoundedPlay
166
+ : HugeIcons.strokeRoundedPause,
167
size: 20,
168
color: theme.colorScheme.primary,
169
),
@@ -240,7 +241,7 @@ class TtsPlayerBar extends ConsumerWidget {
241
if (!ttsState.isInitializing &&
242
ttsState.activeEngine != EngineId.system)
243
IconButton(
243
- icon: const Icon(Icons.download_outlined, size: 20),
244
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedDownload01, size: 20),
245
tooltip: l10n.download_tts_audio,
246
visualDensity: VisualDensity.compact,
247
onPressed: () async {
@@ -268,8 +269,8 @@ class TtsPlayerBar extends ConsumerWidget {
269
color: theme.colorScheme.error.withValues(alpha: 0.1),
270
borderRadius: BorderRadius.circular(8),
271
),
271
- child: Icon(
272
- Icons.stop_rounded,
272
+ child: HugeIcon(icon:
273
+ HugeIcons.strokeRoundedStop,
274
size: 20,
275
color: theme.colorScheme.error,
276
),
@@ -283,7 +284,7 @@ class TtsPlayerBar extends ConsumerWidget {
284
Row(
285
children: [
286
_TtsSkipButton(
286
- icon: Icons.fast_rewind_rounded,
287
+ icon: HugeIcons.strokeRoundedGoBackward10Sec,
288
tooltip: '-${skipSeconds}s',
289
isLoading: ttsState.isSeekPending && !ttsState.canSeek,
290
onPressed: notifier.skipBackward,
@@ -299,7 +300,7 @@ class TtsPlayerBar extends ConsumerWidget {
300
),
301
),
302
_TtsSkipButton(
302
- icon: Icons.fast_forward_rounded,
303
+ icon: HugeIcons.strokeRoundedGoForward10Sec,
304
tooltip: '+${skipSeconds}s',
305
isLoading: ttsState.isSeekPending && !ttsState.canSeek,
306
onPressed: notifier.skipForward,
@@ -322,7 +323,7 @@ class _TtsSkipButton extends StatelessWidget {
323
this.isLoading = false,
324
});
325
325
- final IconData icon;
326
+ final List<List<dynamic>> icon;
327
final String tooltip;
328
final Future<void> Function() onPressed;
329
final bool isLoading;
@@ -339,7 +340,7 @@ class _TtsSkipButton extends StatelessWidget {
340
height: 18,
341
child: CircularProgressIndicator(strokeWidth: 2),
342
)
342
- : Icon(icon, size: 22),
343
+ : HugeIcon(icon: icon, size: 22),
344
);
345
}
346
}
@@ -526,4 +527,4 @@ class _WaveformIndicatorState extends State<_WaveformIndicator>
527
),
528
);
529
}
529
-}
530
+}
\ No newline at end of file
lib/features/tts/views/tts_model_manager_screen.dart
+18
-17
@@ -1,3 +1,4 @@
1
+import 'package:hugeicons/hugeicons.dart';
2
import 'dart:async';
3
4
import 'package:flutter/material.dart';
@@ -48,7 +49,7 @@ class TtsModelManagerScreen extends ConsumerWidget {
49
children: [
50
Builder(
51
builder: (context) => IconButton(
51
- icon: const Icon(Icons.menu),
52
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedMenu01),
53
onPressed: () => Scaffold.of(context).openDrawer(),
54
),
55
),
@@ -138,8 +139,8 @@ class _SystemVoicesList extends ConsumerWidget {
139
),
140
const SizedBox(height: 12),
141
ShadAlert(
141
- icon: Icon(
142
- Icons.info_outline,
142
+ icon: HugeIcon(icon:
143
+ HugeIcons.strokeRoundedInformationCircle,
144
color: theme.colorScheme.onSurface.withValues(alpha: 0.7),
145
),
146
description: Text(
@@ -204,7 +205,7 @@ class _KittenEngineCard extends ConsumerWidget {
205
child: Row(
206
mainAxisSize: MainAxisSize.min,
207
children: [
207
- const Icon(Icons.music_note, size: 12),
208
+ const HugeIcon(icon: HugeIcons.strokeRoundedMusicNote01, size: 12),
209
const SizedBox(width: 4),
210
Text(
211
l10n.tts_supports_background,
@@ -268,7 +269,7 @@ class _KittenEngineCard extends ConsumerWidget {
269
const SizedBox(width: 8),
270
ShadIconButton.ghost(
271
padding: EdgeInsets.zero,
271
- icon: const Icon(Icons.delete_outline, color: Colors.red, size: 20),
272
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red, size: 20),
273
onPressed: () => _confirmDelete(context, ref, model),
274
),
275
],
@@ -436,7 +437,7 @@ class _PiperEngineCard extends ConsumerWidget {
437
child: Row(
438
mainAxisSize: MainAxisSize.min,
439
children: [
439
- const Icon(Icons.music_note, size: 12),
440
+ const HugeIcon(icon: HugeIcons.strokeRoundedMusicNote01, size: 12),
441
const SizedBox(width: 4),
442
Text(
443
l10n.tts_supports_background,
@@ -530,7 +531,7 @@ class _PiperEngineCard extends ConsumerWidget {
531
const SizedBox(width: 8),
532
ShadIconButton.ghost(
533
padding: EdgeInsets.zero,
533
- icon: const Icon(Icons.delete_outline, color: Colors.red, size: 20),
534
+ icon: const HugeIcon(icon: HugeIcons.strokeRoundedDelete01, color: Colors.red, size: 20),
535
onPressed: () => _confirmDelete(context, ref, variant),
536
),
537
],
@@ -688,7 +689,7 @@ class _PiperVariantChip extends StatelessWidget {
689
),
690
if (installed) ...[
691
const SizedBox(width: 6),
691
- const Icon(Icons.check_circle, size: 14, color: Colors.green),
692
+ const HugeIcon(icon: HugeIcons.strokeRoundedCheckmarkCircle01, size: 14, color: Colors.green),
693
],
694
],
695
),
@@ -750,8 +751,8 @@ class _EngineCard extends StatelessWidget {
751
color: accentColor.withValues(alpha: 0.15),
752
borderRadius: BorderRadius.circular(8),
753
),
753
- child: Icon(
754
- Icons.record_voice_over,
754
+ child: HugeIcon(icon:
755
+ HugeIcons.strokeRoundedVoice,
756
size: 18,
757
color: accentColor,
758
),
@@ -971,8 +972,8 @@ class _VoiceChipsState extends ConsumerState<_VoiceChips> {
972
child: Row(
973
children: [
974
if (isSelected) ...[
974
- const Icon(
975
- Icons.check_circle,
975
+ const HugeIcon(icon:
976
+ HugeIcons.strokeRoundedCheckmarkCircle01,
977
size: 16,
978
color: Colors.green,
979
),
@@ -1014,8 +1015,8 @@ class _VoiceChipsState extends ConsumerState<_VoiceChips> {
1015
horizontal: 10,
1016
vertical: 8,
1017
),
1017
- child: Icon(
1018
- isPlaying ? Icons.stop : Icons.play_arrow,
1018
+ child: HugeIcon(icon:
1019
+ isPlaying ? HugeIcons.strokeRoundedStop : HugeIcons.strokeRoundedPlay,
1020
size: 16,
1021
color: isPlaying
1022
? accent
@@ -1115,14 +1116,14 @@ class _TtsTestSectionState extends ConsumerState<_TtsTestSection> {
1116
Expanded(
1117
child: ShadButton(
1118
onPressed: _speak,
1118
- leading: const Icon(Icons.volume_up),
1119
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedVolumeUp),
1120
child: Text(l10n.test_speak_button),
1121
),
1122
),
1123
const SizedBox(width: 8),
1124
ShadButton.outline(
1125
onPressed: () => ref.read(tts.ttsProvider.notifier).stop(),
1125
- leading: const Icon(Icons.stop),
1126
+ leading: const HugeIcon(icon: HugeIcons.strokeRoundedStop),
1127
child: Text(l10n.stop),
1128
),
1129
],
@@ -1130,4 +1131,4 @@ class _TtsTestSectionState extends ConsumerState<_TtsTestSection> {
1131
],
1132
);
1133
}
1133
-}
1134
+}
\ No newline at end of file