|
1 | | -import 'dart:async'; |
2 | 1 |
|
| 2 | +import 'package:auto_size_text/auto_size_text.dart'; |
3 | 3 | import 'package:flutter/material.dart'; |
4 | | -import 'package:stream_transform/stream_transform.dart'; |
5 | 4 | import 'package:super_tooltip/super_tooltip.dart'; |
6 | 5 | import 'package:thingsboard_app/config/themes/app_colors.dart'; |
7 | 6 | import 'package:thingsboard_app/core/context/tb_context_widget.dart'; |
8 | | -import 'package:thingsboard_app/generated/l10n.dart'; |
9 | 7 | import 'package:thingsboard_app/utils/ui/tb_text_styles.dart'; |
10 | | -import 'package:thingsboard_app/widgets/text_overflow_builder.dart'; |
11 | 8 |
|
12 | 9 | class TbAppBar extends TbContextWidget implements PreferredSizeWidget { |
13 | 10 | TbAppBar( |
@@ -111,173 +108,56 @@ class _TbAppBarState extends TbContextState<TbAppBar> { |
111 | 108 | } |
112 | 109 |
|
113 | 110 | Widget buildTooltip(Text text) { |
114 | | - return DetectTextOverflowBuilder( |
115 | | - textWidget: text, |
116 | | - builder: (context, overflow) { |
117 | | - final padding = MediaQueryData.fromView(View.of(context)).padding.top; |
118 | | - return overflow |
119 | | - ? Row( |
120 | | - children: [ |
121 | | - Flexible(child: text), |
122 | | - SuperTooltip( |
123 | | - borderRadius: 4, |
124 | | - arrowLength: 8, |
125 | | - arrowBaseWidth: 16, |
126 | | - top: padding, |
127 | | - borderColor: Colors.transparent, |
128 | | - popupDirection: TooltipDirection.left, |
129 | | - |
130 | | - boxShadows: [ |
131 | | - BoxShadow( |
132 | | - color: AppColors.black.withValues(alpha: .15), |
133 | | - blurRadius: 6, |
134 | | - spreadRadius: 2, |
135 | | - ), |
136 | | - BoxShadow( |
137 | | - color: AppColors.black.withValues(alpha: .3), |
138 | | - blurRadius: 2, |
139 | | - offset: const Offset(0, 1), |
140 | | - ), |
141 | | - ], |
142 | | - shadowColor: Colors.transparent, |
143 | | - content: Text( |
144 | | - text.data ?? '', |
145 | | - style: TbTextStyles.labelSmall.copyWith( |
146 | | - fontWeight: FontWeight.w500, |
147 | | - ), |
148 | | - ), |
149 | | - controller: _controller, |
150 | | - barrierColor: Colors.transparent, |
151 | | - child: InkWell( |
152 | | - |
153 | | - onTap: () { |
154 | | - _controller.showTooltip(); |
155 | | - }, |
156 | | - child: const Padding( |
157 | | - padding: EdgeInsets.all(4), |
158 | | - child: Icon(Icons.info_outline), |
159 | | - ), |
160 | | - ), |
161 | | - ), |
162 | | - ], |
163 | | - ) |
164 | | - : text; |
165 | | - }, |
166 | | - ); |
167 | | - } |
168 | | -} |
169 | | - |
170 | | -class TbAppSearchBar extends TbContextWidget implements PreferredSizeWidget { |
171 | | - TbAppSearchBar( |
172 | | - super.tbContext, { |
173 | | - super.key, |
174 | | - this.elevation = 8, |
175 | | - this.shadowColor, |
176 | | - this.showLoadingIndicator = false, |
177 | | - this.searchHint, |
178 | | - this.onSearch, |
179 | | - this.leading, |
180 | | - }) : preferredSize = Size.fromHeight( |
181 | | - kToolbarHeight + (showLoadingIndicator ? 4 : 0), |
182 | | - ); |
183 | | - final double? elevation; |
184 | | - final Color? shadowColor; |
185 | | - final bool showLoadingIndicator; |
186 | | - final String? searchHint; |
187 | | - final void Function(String searchText)? onSearch; |
188 | | - final Widget? leading; |
189 | | - |
190 | | - @override |
191 | | - final Size preferredSize; |
192 | | - |
193 | | - @override |
194 | | - State<StatefulWidget> createState() => _TbAppSearchBarState(); |
195 | | -} |
196 | | - |
197 | | -class _TbAppSearchBarState extends TbContextState<TbAppSearchBar> { |
198 | | - final TextEditingController _filter = TextEditingController(); |
199 | | - final _textUpdates = StreamController<String>(); |
200 | | - |
201 | | - @override |
202 | | - void initState() { |
203 | | - super.initState(); |
204 | | - _filter.addListener(() { |
205 | | - _textUpdates.add(_filter.text); |
206 | | - }); |
207 | | - _textUpdates.stream |
208 | | - .skip(1) |
209 | | - .debounce(const Duration(milliseconds: 150)) |
210 | | - .distinct() |
211 | | - .forEach((element) => widget.onSearch!(element)); |
212 | | - } |
213 | | - |
214 | | - @override |
215 | | - void dispose() { |
216 | | - _filter.dispose(); |
217 | | - super.dispose(); |
218 | | - } |
219 | | - |
220 | | - @override |
221 | | - Widget build(BuildContext context) { |
222 | | - final List<Widget> children = <Widget>[]; |
223 | | - children.add(buildSearchBar()); |
224 | | - if (widget.showLoadingIndicator) { |
225 | | - children.add( |
226 | | - ValueListenableBuilder( |
227 | | - valueListenable: loadingNotifier, |
228 | | - builder: (context, bool loading, child) { |
229 | | - if (loading) { |
230 | | - return const LinearProgressIndicator(); |
231 | | - } else { |
232 | | - return Container(height: 4); |
233 | | - } |
234 | | - }, |
235 | | - ), |
236 | | - ); |
237 | | - } |
238 | | - return Column(children: children); |
239 | | - } |
240 | | - |
241 | | - AppBar buildSearchBar() { |
242 | | - return AppBar( |
243 | | - centerTitle: true, |
244 | | - elevation: widget.elevation ?? 8, |
245 | | - shadowColor: widget.shadowColor ?? const Color(0xFFFFFFFF).withAlpha(150), |
246 | | - title: TextField( |
247 | | - controller: _filter, |
248 | | - autofocus: true, |
249 | | - decoration: InputDecoration( |
250 | | - border: InputBorder.none, |
251 | | - hintStyle: TextStyle( |
252 | | - color: const Color(0xFF282828).withAlpha((255 * 0.38).ceil()), |
| 111 | + final padding = MediaQueryData.fromView(View.of(context)).padding.top; |
| 112 | + return AutoSizeText( |
| 113 | + text.data ?? '', |
| 114 | + maxLines: 1, |
| 115 | + style: text.style, |
| 116 | + overflowReplacement: Row( |
| 117 | + children: [ |
| 118 | + Flexible(child: text), |
| 119 | + SuperTooltip( |
| 120 | + borderRadius: 4, |
| 121 | + arrowLength: 8, |
| 122 | + arrowBaseWidth: 16, |
| 123 | + top: padding, |
| 124 | + borderColor: Colors.transparent, |
| 125 | + popupDirection: TooltipDirection.left, |
| 126 | + |
| 127 | + boxShadows: [ |
| 128 | + BoxShadow( |
| 129 | + color: AppColors.black.withValues(alpha: .15), |
| 130 | + blurRadius: 6, |
| 131 | + spreadRadius: 2, |
| 132 | + ), |
| 133 | + BoxShadow( |
| 134 | + color: AppColors.black.withValues(alpha: .3), |
| 135 | + blurRadius: 2, |
| 136 | + offset: const Offset(0, 1), |
| 137 | + ), |
| 138 | + ], |
| 139 | + shadowColor: Colors.transparent, |
| 140 | + content: Text( |
| 141 | + text.data ?? '', |
| 142 | + style: TbTextStyles.labelSmall.copyWith( |
| 143 | + fontWeight: FontWeight.w500, |
| 144 | + ), |
| 145 | + ), |
| 146 | + controller: _controller, |
| 147 | + barrierColor: Colors.transparent, |
| 148 | + child: InkWell( |
| 149 | + onTap: () { |
| 150 | + _controller.showTooltip(); |
| 151 | + }, |
| 152 | + child: const Padding( |
| 153 | + padding: EdgeInsets.all(4), |
| 154 | + child: Icon(Icons.info_outline), |
| 155 | + ), |
| 156 | + ), |
253 | 157 | ), |
254 | | - contentPadding: const EdgeInsets.only( |
255 | | - left: 15, |
256 | | - bottom: 11, |
257 | | - top: 15, |
258 | | - right: 15, |
259 | | - ), |
260 | | - hintText: widget.searchHint ?? S.of(context).search, |
261 | | - ), |
| 158 | + ], |
262 | 159 | ), |
263 | | - leading: widget.leading, |
264 | | - actions: [ |
265 | | - ValueListenableBuilder( |
266 | | - valueListenable: _filter, |
267 | | - builder: (context, value, child) { |
268 | | - if (_filter.text.isNotEmpty) { |
269 | | - return IconButton( |
270 | | - icon: const Icon(Icons.clear), |
271 | | - onPressed: () { |
272 | | - _filter.text = ''; |
273 | | - }, |
274 | | - ); |
275 | | - } else { |
276 | | - return Container(); |
277 | | - } |
278 | | - }, |
279 | | - ), |
280 | | - ], |
| 160 | + minFontSize: text.style?.fontSize ?? 12, |
281 | 161 | ); |
282 | 162 | } |
283 | 163 | } |
0 commit comments