Line data Source code
1 : // ignore_for_file: prefer-first
2 :
3 : import 'package:flutter/material.dart';
4 : import 'package:folly_fields/util/date_time_extension.dart';
5 :
6 : ///
7 : ///
8 : ///
9 : class FollyUtils {
10 : ///
11 : ///
12 : ///
13 : // TODO(edufolly): Remove in version 1.0.0.
14 0 : @Deprecated('Prefer to use DateTime.time. '
15 : 'This class will be removed in version 1.0.0.')
16 0 : static TimeOfDay? getTime(DateTime? dateTime) => dateTime?.time;
17 :
18 : ///
19 : ///
20 : ///
21 : // TODO(edufolly): Remove in version 1.0.0.
22 0 : @Deprecated('Prefer to use DateTime.mergeStartSeconds '
23 : 'This class will be removed in version 1.0.0.')
24 : static DateTime? dateTimeMergeStart({
25 : required DateTime? date,
26 : int second = 0,
27 : int millisecond = 0,
28 : int microsecond = 0,
29 : }) =>
30 0 : date?.mergeStartSeconds(
31 : second: second,
32 : millisecond: millisecond,
33 : microsecond: microsecond,
34 : );
35 :
36 : ///
37 : ///
38 : ///
39 : // TODO(edufolly): Remove in version 1.0.0.
40 0 : @Deprecated('Prefer to use DateTime.mergeStart '
41 : 'This class will be removed in version 1.0.0.')
42 : static DateTime? dateMergeStart({
43 : required DateTime? date,
44 : TimeOfDay time = const TimeOfDay(hour: 0, minute: 0),
45 : int second = 0,
46 : int millisecond = 0,
47 : int microsecond = 0,
48 : }) =>
49 0 : date?.mergeStart(
50 : time: time,
51 : second: second,
52 : millisecond: millisecond,
53 : microsecond: microsecond,
54 : );
55 :
56 : ///
57 : ///
58 : ///
59 : // TODO(edufolly): Remove in version 1.0.0.
60 0 : @Deprecated('Prefer to use DateTime.mergeEndSeconds '
61 : 'This class will be removed in version 1.0.0.')
62 : static DateTime? dateTimeMergeEnd({
63 : required DateTime? date,
64 : int second = 59,
65 : int millisecond = 999,
66 : int microsecond = 0,
67 : }) =>
68 0 : date?.mergeEndSeconds(
69 : second: second,
70 : millisecond: millisecond,
71 : microsecond: microsecond,
72 : );
73 :
74 : ///
75 : ///
76 : ///
77 : // TODO(edufolly): Remove in version 1.0.0.
78 0 : @Deprecated('Prefer to use DateTime.mergeEnd '
79 : 'This class will be removed in version 1.0.0.')
80 : static DateTime? dateMergeEnd({
81 : required DateTime? date,
82 : TimeOfDay time = const TimeOfDay(hour: 23, minute: 59),
83 : int second = 59,
84 : int millisecond = 999,
85 : int microsecond = 0,
86 : }) =>
87 0 : date?.mergeEnd(
88 : time: time,
89 : second: second,
90 : millisecond: millisecond,
91 : microsecond: microsecond,
92 : );
93 :
94 : ///
95 : ///
96 : ///
97 1 : static String? validDate(String value) {
98 1 : if (value.isEmpty) {
99 : return 'Informe uma data.';
100 : }
101 :
102 1 : List<String> parts = value.split('/');
103 :
104 2 : if (parts.length != 3) {
105 : return 'Data inválida.';
106 : }
107 :
108 3 : if (parts[2].length != 4) {
109 : return 'Ano inválido.';
110 : }
111 :
112 2 : int? year = int.tryParse(parts[2]);
113 : if (year == null) {
114 : return 'Ano inválido.';
115 : }
116 :
117 2 : int? month = int.tryParse(parts[1]);
118 2 : if (month == null || month < 1 || month > 12) {
119 : return 'Mês inválido.';
120 : }
121 :
122 2 : int? day = int.tryParse(parts[0]);
123 4 : if (day == null || day < 1 || day > DateTime(year, month).daysInMonth) {
124 : return 'Dia inválido.';
125 : }
126 :
127 : return null;
128 : }
129 :
130 : ///
131 : ///
132 : ///
133 : // TODO(edufolly): Remove in version 1.0.0.
134 0 : @Deprecated('Prefer to use DateTime.daysInMonth '
135 : 'This class will be removed in version 1.0.0.')
136 : static int getDaysInMonth(int year, int month) {
137 0 : if (month == DateTime.february) {
138 0 : return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)
139 : ? 29
140 : : 28;
141 : }
142 0 : List<int> days = <int>[31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
143 :
144 0 : return days[month - 1];
145 : }
146 :
147 : ///
148 : ///
149 : ///
150 1 : static String? validTime(String value) {
151 2 : if (value.length != 5) {
152 : return 'Informe uma hora.';
153 : }
154 :
155 1 : List<String> parts = value.split(':');
156 :
157 2 : if (parts.length != 2) {
158 : return 'Hora inválida.';
159 : }
160 :
161 2 : int? hour = int.tryParse(parts[0]);
162 :
163 2 : if (hour == null || hour < 0 || hour > 23) {
164 : return 'Horas inválidas.';
165 : }
166 :
167 2 : int? minute = int.tryParse(parts[1]);
168 :
169 2 : if (minute == null || minute < 0 || minute > 59) {
170 : return 'Minutos inválidos.';
171 : }
172 :
173 : return null;
174 : }
175 :
176 : ///
177 : ///
178 : ///
179 1 : static bool isPascalCase(String value) =>
180 1 : !(value.isEmpty ||
181 2 : value.contains(RegExp('[^a-zA-Z0-9]+')) ||
182 2 : value.startsWith(RegExp('[0-9]+'))) &&
183 4 : value[0].toUpperCase() == value[0];
184 :
185 : ///
186 : ///
187 : ///
188 1 : static bool isCamelCase(String value) =>
189 1 : !(value.isEmpty ||
190 2 : value.contains(RegExp('[^a-zA-Z0-9]+')) ||
191 2 : value.startsWith(RegExp('[0-9]+'))) &&
192 4 : value[0].toLowerCase() == value[0];
193 :
194 : ///
195 : ///
196 : ///
197 2 : static bool isSnakeCase(String value) => !(value.isEmpty ||
198 2 : value.contains(RegExp('[^_a-z0-9]+')) ||
199 2 : value.startsWith(RegExp('[0-9]+')));
200 :
201 : ///
202 : ///
203 : ///
204 1 : static String camel2Snake(String camel, {bool internal = false}) =>
205 1 : internal || isCamelCase(camel)
206 1 : ? camel.splitMapJoin(
207 1 : RegExp('[A-Z]'),
208 4 : onMatch: (Match m) => '_${m.group(0)!.toLowerCase()}',
209 1 : onNonMatch: (String n) => n,
210 : )
211 : : '';
212 :
213 : ///
214 : ///
215 : ///
216 2 : static String snake2Camel(String snake) => isSnakeCase(snake)
217 2 : ? pascal2Camel(snake2Pascal(snake, internal: true), internal: true)
218 : : '';
219 :
220 : ///
221 : ///
222 : ///
223 1 : static String pascal2Camel(String pascal, {bool internal = false}) =>
224 1 : internal || isPascalCase(pascal)
225 4 : ? pascal[0].toLowerCase() + pascal.substring(1)
226 : : '';
227 :
228 : ///
229 : ///
230 : ///
231 1 : static String camel2Pascal(String camel) =>
232 5 : isCamelCase(camel) ? camel[0].toUpperCase() + camel.substring(1) : '';
233 :
234 : ///
235 : ///
236 : ///
237 2 : static String pascal2Snake(String pascal) => isPascalCase(pascal)
238 2 : ? camel2Snake(pascal, internal: true).substring(1)
239 : : '';
240 :
241 : ///
242 : ///
243 : ///
244 1 : static String snake2Pascal(String snake, {bool internal = false}) =>
245 1 : internal || isSnakeCase(snake)
246 2 : ? snake.toLowerCase().splitMapJoin(
247 1 : RegExp('_'),
248 1 : onMatch: (Match m) => '',
249 1 : onNonMatch: (String n) =>
250 4 : n.substring(0, 1).toUpperCase() + n.substring(1),
251 : )
252 : : '';
253 :
254 : ///
255 : ///
256 : ///
257 1 : static Color textColorByLuminance(
258 : Color color, {
259 : Color darkColor = Colors.black,
260 : Color lightColor = Colors.white,
261 : double redFactor = 0.299,
262 : double greenFactor = 0.587,
263 : double blueFactor = 0.114,
264 : double threshold = 186,
265 : }) =>
266 3 : color.red * redFactor +
267 3 : color.green * greenFactor +
268 3 : color.blue * blueFactor >
269 : threshold
270 : ? darkColor
271 : : lightColor;
272 :
273 : ///
274 : ///
275 : ///
276 1 : static Color? colorParse(String? text, [int? defaultColor]) {
277 1 : if (text == null || text.isEmpty) {
278 1 : return defaultColor == null ? null : Color(defaultColor);
279 : } else {
280 : try {
281 1 : if (!text.startsWith('0x')) {
282 3 : text = text.replaceAll('#', '').trim().toUpperCase();
283 :
284 2 : if (text.length < 3) {
285 1 : throw Exception('Length less than 3.');
286 : }
287 :
288 2 : if (text.length == 3) {
289 11 : text = text[0] + text[0] + text[1] + text[1] + text[2] + text[2];
290 : }
291 :
292 2 : if (text.length == 4) {
293 2 : text = text[0] +
294 2 : text[0] +
295 2 : text[1] +
296 2 : text[1] +
297 2 : text[2] +
298 2 : text[2] +
299 2 : text[3] +
300 1 : text[3];
301 : }
302 :
303 2 : if (text.length == 6) {
304 1 : text = 'FF$text';
305 : }
306 :
307 2 : if (text.length > 8) {
308 1 : text = text.substring(0, 8);
309 : }
310 :
311 1 : text = '0x$text';
312 : }
313 :
314 2 : return Color(int.parse(text));
315 1 : } on Exception catch (_) {
316 1 : return defaultColor == null ? null : Color(defaultColor);
317 : }
318 : }
319 : }
320 :
321 : ///
322 : ///
323 : ///
324 1 : static MaterialColor? createMaterialColor({
325 : int? intColor,
326 : Color? color,
327 : }) {
328 : if (intColor != null) {
329 1 : color = Color(intColor);
330 : }
331 :
332 : if (color == null) {
333 : return null;
334 : }
335 :
336 1 : return MaterialColor(
337 1 : color.value,
338 1 : <int, Color>{
339 : 50: color,
340 : 100: color,
341 : 200: color,
342 : 300: color,
343 : 400: color,
344 : 500: color,
345 : 600: color,
346 : 700: color,
347 : 800: color,
348 : 900: color,
349 : },
350 : );
351 : }
352 : }
|