new change to use intaleq_map sdk 04-16-4
This commit is contained in:
4
packages/get/lib/get_utils/get_utils.dart
Normal file
4
packages/get/lib/get_utils/get_utils.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
export 'src/extensions/export.dart';
|
||||
export 'src/get_utils/get_utils.dart';
|
||||
export 'src/platform/platform.dart';
|
||||
export 'src/queue/get_queue.dart';
|
||||
@@ -0,0 +1,141 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../platform/platform.dart';
|
||||
|
||||
extension ContextExtensionss on BuildContext {
|
||||
/// The same of [MediaQuery.of(context).size]
|
||||
Size get mediaQuerySize => MediaQuery.of(this).size;
|
||||
|
||||
/// The same of [MediaQuery.of(context).size.height]
|
||||
/// Note: updates when you rezise your screen (like on a browser or
|
||||
/// desktop window)
|
||||
double get height => mediaQuerySize.height;
|
||||
|
||||
/// The same of [MediaQuery.of(context).size.width]
|
||||
/// Note: updates when you rezise your screen (like on a browser or
|
||||
/// desktop window)
|
||||
double get width => mediaQuerySize.width;
|
||||
|
||||
/// Gives you the power to get a portion of the height.
|
||||
/// Useful for responsive applications.
|
||||
///
|
||||
/// [dividedBy] is for when you want to have a portion of the value you
|
||||
/// would get like for example: if you want a value that represents a third
|
||||
/// of the screen you can set it to 3, and you will get a third of the height
|
||||
///
|
||||
/// [reducedBy] is a percentage value of how much of the height you want
|
||||
/// if you for example want 46% of the height, then you reduce it by 56%.
|
||||
double heightTransformer({double dividedBy = 1, double reducedBy = 0.0}) {
|
||||
return (mediaQuerySize.height -
|
||||
((mediaQuerySize.height / 100) * reducedBy)) /
|
||||
dividedBy;
|
||||
}
|
||||
|
||||
/// Gives you the power to get a portion of the width.
|
||||
/// Useful for responsive applications.
|
||||
///
|
||||
/// [dividedBy] is for when you want to have a portion of the value you
|
||||
/// would get like for example: if you want a value that represents a third
|
||||
/// of the screen you can set it to 3, and you will get a third of the width
|
||||
///
|
||||
/// [reducedBy] is a percentage value of how much of the width you want
|
||||
/// if you for example want 46% of the width, then you reduce it by 56%.
|
||||
double widthTransformer({double dividedBy = 1, double reducedBy = 0.0}) {
|
||||
return (mediaQuerySize.width - ((mediaQuerySize.width / 100) * reducedBy)) /
|
||||
dividedBy;
|
||||
}
|
||||
|
||||
/// Divide the height proportionally by the given value
|
||||
double ratio({
|
||||
double dividedBy = 1,
|
||||
double reducedByW = 0.0,
|
||||
double reducedByH = 0.0,
|
||||
}) {
|
||||
return heightTransformer(dividedBy: dividedBy, reducedBy: reducedByH) /
|
||||
widthTransformer(dividedBy: dividedBy, reducedBy: reducedByW);
|
||||
}
|
||||
|
||||
/// similar to [MediaQuery.of(context).padding]
|
||||
ThemeData get theme => Theme.of(this);
|
||||
|
||||
/// Check if dark mode theme is enable
|
||||
bool get isDarkMode => (theme.brightness == Brightness.dark);
|
||||
|
||||
/// give access to Theme.of(context).iconTheme.color
|
||||
Color? get iconColor => theme.iconTheme.color;
|
||||
|
||||
/// similar to [MediaQuery.of(context).padding]
|
||||
TextTheme get textTheme => Theme.of(this).textTheme;
|
||||
|
||||
/// similar to [MediaQuery.of(context).padding]
|
||||
EdgeInsets get mediaQueryPadding => MediaQuery.of(this).padding;
|
||||
|
||||
/// similar to [MediaQuery.of(context).padding]
|
||||
MediaQueryData get mediaQuery => MediaQuery.of(this);
|
||||
|
||||
/// similar to [MediaQuery.of(context).viewPadding]
|
||||
EdgeInsets get mediaQueryViewPadding => MediaQuery.of(this).viewPadding;
|
||||
|
||||
/// similar to [MediaQuery.of(context).viewInsets]
|
||||
EdgeInsets get mediaQueryViewInsets => MediaQuery.of(this).viewInsets;
|
||||
|
||||
/// similar to [MediaQuery.of(context).orientation]
|
||||
Orientation get orientation => MediaQuery.of(this).orientation;
|
||||
|
||||
/// check if device is on landscape mode
|
||||
bool get isLandscape => orientation == Orientation.landscape;
|
||||
|
||||
/// check if device is on portrait mode
|
||||
bool get isPortrait => orientation == Orientation.portrait;
|
||||
|
||||
/// similar to [MediaQuery.of(this).devicePixelRatio]
|
||||
double get devicePixelRatio => MediaQuery.of(this).devicePixelRatio;
|
||||
|
||||
/// similar to [MediaQuery.of(this).textScaleFactor]
|
||||
double get textScaleFactor => MediaQuery.of(this).textScaleFactor;
|
||||
|
||||
/// get the shortestSide from screen
|
||||
double get mediaQueryShortestSide => mediaQuerySize.shortestSide;
|
||||
|
||||
/// True if width be larger than 800
|
||||
bool get showNavbar => (width > 800);
|
||||
|
||||
/// True if the shortestSide is smaller than 600p
|
||||
bool get isPhone => (mediaQueryShortestSide < 600);
|
||||
|
||||
/// True if the shortestSide is largest than 600p
|
||||
bool get isSmallTablet => (mediaQueryShortestSide >= 600);
|
||||
|
||||
/// True if the shortestSide is largest than 720p
|
||||
bool get isLargeTablet => (mediaQueryShortestSide >= 720);
|
||||
|
||||
/// True if the current device is Tablet
|
||||
bool get isTablet => isSmallTablet || isLargeTablet;
|
||||
|
||||
/// Returns a specific value according to the screen size
|
||||
/// if the device width is higher than or equal to 1200 return
|
||||
/// [desktop] value. if the device width is higher than or equal to 600
|
||||
/// and less than 1200 return [tablet] value.
|
||||
/// if the device width is less than 300 return [watch] value.
|
||||
/// in other cases return [mobile] value.
|
||||
T responsiveValue<T>({
|
||||
T? mobile,
|
||||
T? tablet,
|
||||
T? desktop,
|
||||
T? watch,
|
||||
}) {
|
||||
var deviceWidth = mediaQuerySize.shortestSide;
|
||||
if (GetPlatform.isDesktop) {
|
||||
deviceWidth = mediaQuerySize.width;
|
||||
}
|
||||
if (deviceWidth >= 1200 && desktop != null) {
|
||||
return desktop;
|
||||
} else if (deviceWidth >= 600 && tablet != null) {
|
||||
return tablet;
|
||||
} else if (deviceWidth < 300 && watch != null) {
|
||||
return watch;
|
||||
} else {
|
||||
return mobile!;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'dart:math';
|
||||
|
||||
extension Precision on double {
|
||||
double toPrecision(int fractionDigits) {
|
||||
var mod = pow(10, fractionDigits.toDouble()).toDouble();
|
||||
return ((this * mod).round().toDouble() / mod);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'dart:async';
|
||||
|
||||
/// Duration utilities.
|
||||
extension GetDurationUtils on Duration {
|
||||
/// Utility to delay some callback (or code execution).
|
||||
///
|
||||
/// Sample:
|
||||
/// ```
|
||||
/// void main() async {
|
||||
/// final _delay = 3.seconds;
|
||||
/// print('+ wait $_delay');
|
||||
/// await _delay.delay();
|
||||
/// print('- finish wait $_delay');
|
||||
/// print('+ callback in 700ms');
|
||||
/// await 0.7.seconds.delay(() {
|
||||
/// }
|
||||
///```
|
||||
Future delay([FutureOr Function()? callback]) async =>
|
||||
Future.delayed(this, callback);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import '../get_utils/get_utils.dart';
|
||||
|
||||
extension GetDynamicUtils on dynamic {
|
||||
@Deprecated('isNull is deprecated and cannot be used, use "==" operator')
|
||||
bool get isNull => GetUtils.isNull(this);
|
||||
|
||||
bool? get isBlank => GetUtils.isBlank(this);
|
||||
|
||||
@Deprecated(
|
||||
'isNullOrBlank is deprecated and cannot be used, use "isBlank" instead')
|
||||
bool? get isNullOrBlank => GetUtils.isNullOrBlank(this);
|
||||
|
||||
void printError(
|
||||
{String info = '', Function logFunction = GetUtils.printFunction}) =>
|
||||
// ignore: unnecessary_this
|
||||
logFunction('Error: ${this.runtimeType}', this, info, isError: true);
|
||||
|
||||
void printInfo(
|
||||
{String info = '',
|
||||
Function printFunction = GetUtils.printFunction}) =>
|
||||
// ignore: unnecessary_this
|
||||
printFunction('Info: ${this.runtimeType}', this, info);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'dart:async';
|
||||
|
||||
import '../../../get_core/src/get_interface.dart';
|
||||
|
||||
extension LoopEventsExt on GetInterface {
|
||||
Future<T> toEnd<T>(FutureOr<T> Function() computation) async {
|
||||
await Future.delayed(Duration.zero);
|
||||
final val = computation();
|
||||
return val;
|
||||
}
|
||||
|
||||
FutureOr<T> asap<T>(T Function() computation,
|
||||
{bool Function()? condition}) async {
|
||||
T val;
|
||||
if (condition == null || !condition()) {
|
||||
await Future.delayed(Duration.zero);
|
||||
val = computation();
|
||||
} else {
|
||||
val = computation();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
10
packages/get/lib/get_utils/src/extensions/export.dart
Normal file
10
packages/get/lib/get_utils/src/extensions/export.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
export 'context_extensions.dart';
|
||||
export 'double_extensions.dart';
|
||||
export 'duration_extensions.dart';
|
||||
export 'dynamic_extensions.dart';
|
||||
export 'event_loop_extensions.dart';
|
||||
export 'internacionalization.dart';
|
||||
export 'iterable_extensions.dart';
|
||||
export 'num_extensions.dart';
|
||||
export 'string_extensions.dart';
|
||||
export 'widget_extensions.dart';
|
||||
@@ -0,0 +1,145 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import '../../../get_core/get_core.dart';
|
||||
|
||||
class _IntlHost {
|
||||
Locale? locale;
|
||||
|
||||
Locale? fallbackLocale;
|
||||
|
||||
Map<String, Map<String, String>> translations = {};
|
||||
}
|
||||
|
||||
extension FirstWhereExt<T> on List<T> {
|
||||
/// The first element satisfying [test], or `null` if there are none.
|
||||
T? firstWhereOrNull(bool Function(T element) test) {
|
||||
for (var element in this) {
|
||||
if (test(element)) return element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalesIntl on GetInterface {
|
||||
static final _intlHost = _IntlHost();
|
||||
|
||||
Locale? get locale => _intlHost.locale;
|
||||
|
||||
Locale? get fallbackLocale => _intlHost.fallbackLocale;
|
||||
|
||||
set locale(Locale? newLocale) => _intlHost.locale = newLocale;
|
||||
|
||||
set fallbackLocale(Locale? newLocale) => _intlHost.fallbackLocale = newLocale;
|
||||
|
||||
Map<String, Map<String, String>> get translations => _intlHost.translations;
|
||||
|
||||
void addTranslations(Map<String, Map<String, String>> tr) {
|
||||
translations.addAll(tr);
|
||||
}
|
||||
|
||||
void clearTranslations() {
|
||||
translations.clear();
|
||||
}
|
||||
|
||||
void appendTranslations(Map<String, Map<String, String>> tr) {
|
||||
tr.forEach((key, map) {
|
||||
if (translations.containsKey(key)) {
|
||||
translations[key]!.addAll(map);
|
||||
} else {
|
||||
translations[key] = map;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension Trans on String {
|
||||
// Checks whether the language code and country code are present, and
|
||||
// whether the key is also present.
|
||||
bool get _fullLocaleAndKey {
|
||||
return Get.translations.containsKey(
|
||||
"${Get.locale!.languageCode}_${Get.locale!.countryCode}") &&
|
||||
Get.translations[
|
||||
"${Get.locale!.languageCode}_${Get.locale!.countryCode}"]!
|
||||
.containsKey(this);
|
||||
}
|
||||
|
||||
// Checks if there is a callback language in the absence of the specific
|
||||
// country, and if it contains that key.
|
||||
Map<String, String>? get _getSimilarLanguageTranslation {
|
||||
final translationsWithNoCountry = Get.translations
|
||||
.map((key, value) => MapEntry(key.split("_").first, value));
|
||||
final containsKey = translationsWithNoCountry
|
||||
.containsKey(Get.locale!.languageCode.split("_").first);
|
||||
|
||||
if (!containsKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return translationsWithNoCountry[Get.locale!.languageCode.split("_").first];
|
||||
}
|
||||
|
||||
String get tr {
|
||||
// print('language');
|
||||
// print(Get.locale!.languageCode);
|
||||
// print('contains');
|
||||
// print(Get.translations.containsKey(Get.locale!.languageCode));
|
||||
// print(Get.translations.keys);
|
||||
// Returns the key if locale is null.
|
||||
if (Get.locale?.languageCode == null) return this;
|
||||
|
||||
if (_fullLocaleAndKey) {
|
||||
return Get.translations[
|
||||
"${Get.locale!.languageCode}_${Get.locale!.countryCode}"]![this]!;
|
||||
}
|
||||
final similarTranslation = _getSimilarLanguageTranslation;
|
||||
if (similarTranslation != null && similarTranslation.containsKey(this)) {
|
||||
return similarTranslation[this]!;
|
||||
// If there is no corresponding language or corresponding key, return
|
||||
// the key.
|
||||
} else if (Get.fallbackLocale != null) {
|
||||
final fallback = Get.fallbackLocale!;
|
||||
final key = "${fallback.languageCode}_${fallback.countryCode}";
|
||||
|
||||
if (Get.translations.containsKey(key) &&
|
||||
Get.translations[key]!.containsKey(this)) {
|
||||
return Get.translations[key]![this]!;
|
||||
}
|
||||
if (Get.translations.containsKey(fallback.languageCode) &&
|
||||
Get.translations[fallback.languageCode]!.containsKey(this)) {
|
||||
return Get.translations[fallback.languageCode]![this]!;
|
||||
}
|
||||
return this;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
String trArgs([List<String> args = const []]) {
|
||||
var key = tr;
|
||||
if (args.isNotEmpty) {
|
||||
for (final arg in args) {
|
||||
key = key.replaceFirst(RegExp(r'%s'), arg.toString());
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
String trPlural([String? pluralKey, int? i, List<String> args = const []]) {
|
||||
return i == 1 ? trArgs(args) : pluralKey!.trArgs(args);
|
||||
}
|
||||
|
||||
String trParams([Map<String, String> params = const {}]) {
|
||||
var trans = tr;
|
||||
if (params.isNotEmpty) {
|
||||
params.forEach((key, value) {
|
||||
trans = trans.replaceAll('@$key', value);
|
||||
});
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
|
||||
String trPluralParams(
|
||||
[String? pluralKey, int? i, Map<String, String> params = const {}]) {
|
||||
return i == 1 ? trParams(params) : pluralKey!.trParams(params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
extension IterableExtensions<T> on Iterable<T> {
|
||||
Iterable<TRes> mapMany<TRes>(
|
||||
Iterable<TRes>? Function(T item) selector) sync* {
|
||||
for (var item in this) {
|
||||
final res = selector(item);
|
||||
if (res != null) yield* res;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import 'dart:async';
|
||||
|
||||
import '../get_utils/get_utils.dart';
|
||||
|
||||
extension GetNumUtils on num {
|
||||
bool isLowerThan(num b) => GetUtils.isLowerThan(this, b);
|
||||
|
||||
bool isGreaterThan(num b) => GetUtils.isGreaterThan(this, b);
|
||||
|
||||
bool isEqual(num b) => GetUtils.isEqual(this, b);
|
||||
|
||||
/// Utility to delay some callback (or code execution).
|
||||
/// TODO: Add a separated implementation of delay() with the ability
|
||||
/// to stop it.
|
||||
///
|
||||
/// Sample:
|
||||
/// ```
|
||||
/// void main() async {
|
||||
/// print('+ wait for 2 seconds');
|
||||
/// await 2.delay();
|
||||
/// print('- 2 seconds completed');
|
||||
/// print('+ callback in 1.2sec');
|
||||
/// 1.delay(() => print('- 1.2sec callback called'));
|
||||
/// print('currently running callback 1.2sec');
|
||||
/// }
|
||||
///```
|
||||
Future delay([FutureOr Function()? callback]) async => Future.delayed(
|
||||
Duration(milliseconds: (this * 1000).round()),
|
||||
callback,
|
||||
);
|
||||
|
||||
/// Easy way to make Durations from numbers.
|
||||
///
|
||||
/// Sample:
|
||||
/// ```
|
||||
/// print(1.seconds + 200.milliseconds);
|
||||
/// print(1.hours + 30.minutes);
|
||||
/// print(1.5.hours);
|
||||
///```
|
||||
Duration get milliseconds => Duration(microseconds: (this * 1000).round());
|
||||
|
||||
Duration get seconds => Duration(milliseconds: (this * 1000).round());
|
||||
|
||||
Duration get minutes =>
|
||||
Duration(seconds: (this * Duration.secondsPerMinute).round());
|
||||
|
||||
Duration get hours =>
|
||||
Duration(minutes: (this * Duration.minutesPerHour).round());
|
||||
|
||||
Duration get days => Duration(hours: (this * Duration.hoursPerDay).round());
|
||||
|
||||
//final _delayMaps = <Function, Future>{};
|
||||
// TODO: create a proper Future and control the Timer.
|
||||
// Future delay([double seconds = 0, VoidCallback callback]) async {
|
||||
// final ms = (seconds * 1000).round();
|
||||
// return Future.delayed(Duration(milliseconds: ms), callback);
|
||||
// return _delayMaps[callback];
|
||||
// }
|
||||
//killDelay(VoidCallback callback) {
|
||||
// if (_delayMaps.containsKey(callback)) {
|
||||
// _delayMaps[callback]?.timeout(Duration.zero, onTimeout: () {
|
||||
// print('callbacl eliminado!');
|
||||
// });
|
||||
// _delayMaps.remove(callback);
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import '../get_utils/get_utils.dart';
|
||||
|
||||
extension GetStringUtils on String {
|
||||
bool get isNum => GetUtils.isNum(this);
|
||||
|
||||
bool get isNumericOnly => GetUtils.isNumericOnly(this);
|
||||
|
||||
bool get isAlphabetOnly => GetUtils.isAlphabetOnly(this);
|
||||
|
||||
bool get isBool => GetUtils.isBool(this);
|
||||
|
||||
bool get isVectorFileName => GetUtils.isVector(this);
|
||||
|
||||
bool get isImageFileName => GetUtils.isImage(this);
|
||||
|
||||
bool get isAudioFileName => GetUtils.isAudio(this);
|
||||
|
||||
bool get isVideoFileName => GetUtils.isVideo(this);
|
||||
|
||||
bool get isTxtFileName => GetUtils.isTxt(this);
|
||||
|
||||
bool get isDocumentFileName => GetUtils.isWord(this);
|
||||
|
||||
bool get isExcelFileName => GetUtils.isExcel(this);
|
||||
|
||||
bool get isPPTFileName => GetUtils.isPPT(this);
|
||||
|
||||
bool get isAPKFileName => GetUtils.isAPK(this);
|
||||
|
||||
bool get isPDFFileName => GetUtils.isPDF(this);
|
||||
|
||||
bool get isHTMLFileName => GetUtils.isHTML(this);
|
||||
|
||||
bool get isURL => GetUtils.isURL(this);
|
||||
|
||||
bool get isEmail => GetUtils.isEmail(this);
|
||||
|
||||
bool get isPhoneNumber => GetUtils.isPhoneNumber(this);
|
||||
|
||||
bool get isDateTime => GetUtils.isDateTime(this);
|
||||
|
||||
bool get isMD5 => GetUtils.isMD5(this);
|
||||
|
||||
bool get isSHA1 => GetUtils.isSHA1(this);
|
||||
|
||||
bool get isSHA256 => GetUtils.isSHA256(this);
|
||||
|
||||
bool get isBinary => GetUtils.isBinary(this);
|
||||
|
||||
bool get isIPv4 => GetUtils.isIPv4(this);
|
||||
|
||||
bool get isIPv6 => GetUtils.isIPv6(this);
|
||||
|
||||
bool get isHexadecimal => GetUtils.isHexadecimal(this);
|
||||
|
||||
bool get isPalindrom => GetUtils.isPalindrom(this);
|
||||
|
||||
bool get isPassport => GetUtils.isPassport(this);
|
||||
|
||||
bool get isCurrency => GetUtils.isCurrency(this);
|
||||
|
||||
bool get isCpf => GetUtils.isCpf(this);
|
||||
|
||||
bool get isCnpj => GetUtils.isCnpj(this);
|
||||
|
||||
bool isCaseInsensitiveContains(String b) =>
|
||||
GetUtils.isCaseInsensitiveContains(this, b);
|
||||
|
||||
bool isCaseInsensitiveContainsAny(String b) =>
|
||||
GetUtils.isCaseInsensitiveContainsAny(this, b);
|
||||
|
||||
String? get capitalize => GetUtils.capitalize(this);
|
||||
|
||||
String? get capitalizeFirst => GetUtils.capitalizeFirst(this);
|
||||
|
||||
String get removeAllWhitespace => GetUtils.removeAllWhitespace(this);
|
||||
|
||||
String? get camelCase => GetUtils.camelCase(this);
|
||||
|
||||
String? get paramCase => GetUtils.paramCase(this);
|
||||
|
||||
String numericOnly({bool firstWordOnly = false}) =>
|
||||
GetUtils.numericOnly(this, firstWordOnly: firstWordOnly);
|
||||
|
||||
String createPath([Iterable? segments]) {
|
||||
final path = startsWith('/') ? this : '/$this';
|
||||
return GetUtils.createPath(path, segments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// add Padding Property to widget
|
||||
extension WidgetPaddingX on Widget {
|
||||
Widget paddingAll(double padding) =>
|
||||
Padding(padding: EdgeInsets.all(padding), child: this);
|
||||
|
||||
Widget paddingSymmetric({double horizontal = 0.0, double vertical = 0.0}) =>
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical),
|
||||
child: this);
|
||||
|
||||
Widget paddingOnly({
|
||||
double left = 0.0,
|
||||
double top = 0.0,
|
||||
double right = 0.0,
|
||||
double bottom = 0.0,
|
||||
}) =>
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: top, left: left, right: right, bottom: bottom),
|
||||
child: this);
|
||||
|
||||
Widget get paddingZero => Padding(padding: EdgeInsets.zero, child: this);
|
||||
}
|
||||
|
||||
/// Add margin property to widget
|
||||
extension WidgetMarginX on Widget {
|
||||
Widget marginAll(double margin) =>
|
||||
Container(margin: EdgeInsets.all(margin), child: this);
|
||||
|
||||
Widget marginSymmetric({double horizontal = 0.0, double vertical = 0.0}) =>
|
||||
Container(
|
||||
margin:
|
||||
EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical),
|
||||
child: this);
|
||||
|
||||
Widget marginOnly({
|
||||
double left = 0.0,
|
||||
double top = 0.0,
|
||||
double right = 0.0,
|
||||
double bottom = 0.0,
|
||||
}) =>
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: top, left: left, right: right, bottom: bottom),
|
||||
child: this);
|
||||
|
||||
Widget get marginZero => Container(margin: EdgeInsets.zero, child: this);
|
||||
}
|
||||
|
||||
/// Allows you to insert widgets inside a CustomScrollView
|
||||
extension WidgetSliverBoxX on Widget {
|
||||
Widget get sliverBox => SliverToBoxAdapter(child: this);
|
||||
}
|
||||
639
packages/get/lib/get_utils/src/get_utils/get_utils.dart
Normal file
639
packages/get/lib/get_utils/src/get_utils/get_utils.dart
Normal file
@@ -0,0 +1,639 @@
|
||||
import '../../../get_core/get_core.dart';
|
||||
|
||||
/// Returns whether a dynamic value PROBABLY
|
||||
/// has the isEmpty getter/method by checking
|
||||
/// standard dart types that contains it.
|
||||
///
|
||||
/// This is here to for the 'DRY'
|
||||
bool? _isEmpty(dynamic value) {
|
||||
if (value is String) {
|
||||
return value.toString().trim().isEmpty;
|
||||
}
|
||||
if (value is Iterable || value is Map) {
|
||||
return value.isEmpty as bool?;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns whether a dynamic value PROBABLY
|
||||
/// has the length getter/method by checking
|
||||
/// standard dart types that contains it.
|
||||
///
|
||||
/// This is here to for the 'DRY'
|
||||
bool _hasLength(dynamic value) {
|
||||
return value is Iterable || value is String || value is Map;
|
||||
}
|
||||
|
||||
/// Obtains a length of a dynamic value
|
||||
/// by previously validating it's type
|
||||
///
|
||||
/// Note: if [value] is double/int
|
||||
/// it will be taking the .toString
|
||||
/// length of the given value.
|
||||
///
|
||||
/// Note 2: **this may return null!**
|
||||
///
|
||||
/// Note 3: null [value] returns null.
|
||||
int? _obtainDynamicLength(dynamic value) {
|
||||
if (value == null) {
|
||||
// ignore: avoid_returning_null
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_hasLength(value)) {
|
||||
return value.length as int?;
|
||||
}
|
||||
|
||||
if (value is int) {
|
||||
return value.toString().length;
|
||||
}
|
||||
|
||||
if (value is double) {
|
||||
return value.toString().replaceAll('.', '').length;
|
||||
}
|
||||
|
||||
// ignore: avoid_returning_null
|
||||
return null;
|
||||
}
|
||||
|
||||
class GetUtils {
|
||||
GetUtils._();
|
||||
|
||||
/// Checks if data is null.
|
||||
static bool isNull(dynamic value) => value == null;
|
||||
|
||||
/// In dart2js (in flutter v1.17) a var by default is undefined.
|
||||
/// *Use this only if you are in version <- 1.17*.
|
||||
/// So we assure the null type in json convertions to avoid the
|
||||
/// "value":value==null?null:value; someVar.nil will force the null type
|
||||
/// if the var is null or undefined.
|
||||
/// `nil` taken from ObjC just to have a shorter sintax.
|
||||
static dynamic nil(dynamic s) => s == null ? null : s;
|
||||
|
||||
/// Checks if data is null or blank (empty or only contains whitespace).
|
||||
static bool? isNullOrBlank(dynamic value) {
|
||||
if (isNull(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pretty sure that isNullOrBlank should't be validating
|
||||
// iterables... but I'm going to keep this for compatibility.
|
||||
return _isEmpty(value);
|
||||
}
|
||||
|
||||
/// Checks if data is null or blank (empty or only contains whitespace).
|
||||
static bool? isBlank(dynamic value) {
|
||||
return _isEmpty(value);
|
||||
}
|
||||
|
||||
/// Checks if string is int or double.
|
||||
static bool isNum(String value) {
|
||||
if (isNull(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return num.tryParse(value) is num;
|
||||
}
|
||||
|
||||
/// Checks if string consist only numeric.
|
||||
/// Numeric only doesn't accepting "." which double data type have
|
||||
static bool isNumericOnly(String s) => hasMatch(s, r'^\d+$');
|
||||
|
||||
/// Checks if string consist only Alphabet. (No Whitespace)
|
||||
static bool isAlphabetOnly(String s) => hasMatch(s, r'^[a-zA-Z]+$');
|
||||
|
||||
/// Checks if string contains at least one Capital Letter
|
||||
static bool hasCapitalletter(String s) => hasMatch(s, r'[A-Z]');
|
||||
|
||||
/// Checks if string is boolean.
|
||||
static bool isBool(String value) {
|
||||
if (isNull(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (value == 'true' || value == 'false');
|
||||
}
|
||||
|
||||
/// Checks if string is an video file.
|
||||
static bool isVideo(String filePath) {
|
||||
var ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".mp4") ||
|
||||
ext.endsWith(".avi") ||
|
||||
ext.endsWith(".wmv") ||
|
||||
ext.endsWith(".rmvb") ||
|
||||
ext.endsWith(".mpg") ||
|
||||
ext.endsWith(".mpeg") ||
|
||||
ext.endsWith(".3gp");
|
||||
}
|
||||
|
||||
/// Checks if string is an image file.
|
||||
static bool isImage(String filePath) {
|
||||
final ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".jpg") ||
|
||||
ext.endsWith(".jpeg") ||
|
||||
ext.endsWith(".png") ||
|
||||
ext.endsWith(".gif") ||
|
||||
ext.endsWith(".bmp");
|
||||
}
|
||||
|
||||
/// Checks if string is an audio file.
|
||||
static bool isAudio(String filePath) {
|
||||
final ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".mp3") ||
|
||||
ext.endsWith(".wav") ||
|
||||
ext.endsWith(".wma") ||
|
||||
ext.endsWith(".amr") ||
|
||||
ext.endsWith(".ogg");
|
||||
}
|
||||
|
||||
/// Checks if string is an powerpoint file.
|
||||
static bool isPPT(String filePath) {
|
||||
final ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".ppt") || ext.endsWith(".pptx");
|
||||
}
|
||||
|
||||
/// Checks if string is an word file.
|
||||
static bool isWord(String filePath) {
|
||||
final ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".doc") || ext.endsWith(".docx");
|
||||
}
|
||||
|
||||
/// Checks if string is an excel file.
|
||||
static bool isExcel(String filePath) {
|
||||
final ext = filePath.toLowerCase();
|
||||
|
||||
return ext.endsWith(".xls") || ext.endsWith(".xlsx");
|
||||
}
|
||||
|
||||
/// Checks if string is an apk file.
|
||||
static bool isAPK(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".apk");
|
||||
}
|
||||
|
||||
/// Checks if string is an pdf file.
|
||||
static bool isPDF(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".pdf");
|
||||
}
|
||||
|
||||
/// Checks if string is an txt file.
|
||||
static bool isTxt(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".txt");
|
||||
}
|
||||
|
||||
/// Checks if string is an chm file.
|
||||
static bool isChm(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".chm");
|
||||
}
|
||||
|
||||
/// Checks if string is a vector file.
|
||||
static bool isVector(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".svg");
|
||||
}
|
||||
|
||||
/// Checks if string is an html file.
|
||||
static bool isHTML(String filePath) {
|
||||
return filePath.toLowerCase().endsWith(".html");
|
||||
}
|
||||
|
||||
/// Checks if string is a valid username.
|
||||
static bool isUsername(String s) =>
|
||||
hasMatch(s, r'^[a-zA-Z0-9][a-zA-Z0-9_.]+[a-zA-Z0-9]$');
|
||||
|
||||
/// Checks if string is URL.
|
||||
static bool isURL(String s) => hasMatch(s,
|
||||
r"^((((H|h)(T|t)|(F|f))(T|t)(P|p)((S|s)?))\://)?(www.|[a-zA-Z0-9].)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,6}(\:[0-9]{1,5})*(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$");
|
||||
|
||||
/// Checks if string is email.
|
||||
static bool isEmail(String s) => hasMatch(s,
|
||||
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');
|
||||
|
||||
/// Checks if string is phone number.
|
||||
static bool isPhoneNumber(String s) {
|
||||
if (s.length > 16 || s.length < 9) return false;
|
||||
return hasMatch(s, r'^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$');
|
||||
}
|
||||
|
||||
/// Checks if string is DateTime (UTC or Iso8601).
|
||||
static bool isDateTime(String s) =>
|
||||
hasMatch(s, r'^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}.\d{3}Z?$');
|
||||
|
||||
/// Checks if string is MD5 hash.
|
||||
static bool isMD5(String s) => hasMatch(s, r'^[a-f0-9]{32}$');
|
||||
|
||||
/// Checks if string is SHA1 hash.
|
||||
static bool isSHA1(String s) =>
|
||||
hasMatch(s, r'(([A-Fa-f0-9]{2}\:){19}[A-Fa-f0-9]{2}|[A-Fa-f0-9]{40})');
|
||||
|
||||
/// Checks if string is SHA256 hash.
|
||||
static bool isSHA256(String s) =>
|
||||
hasMatch(s, r'([A-Fa-f0-9]{2}\:){31}[A-Fa-f0-9]{2}|[A-Fa-f0-9]{64}');
|
||||
|
||||
/// Checks if string is SSN (Social Security Number).
|
||||
static bool isSSN(String s) => hasMatch(s,
|
||||
r'^(?!0{3}|6{3}|9[0-9]{2})[0-9]{3}-?(?!0{2})[0-9]{2}-?(?!0{4})[0-9]{4}$');
|
||||
|
||||
/// Checks if string is binary.
|
||||
static bool isBinary(String s) => hasMatch(s, r'^[0-1]+$');
|
||||
|
||||
/// Checks if string is IPv4.
|
||||
static bool isIPv4(String s) =>
|
||||
hasMatch(s, r'^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$');
|
||||
|
||||
/// Checks if string is IPv6.
|
||||
static bool isIPv6(String s) => hasMatch(s,
|
||||
r'^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$');
|
||||
|
||||
/// Checks if string is hexadecimal.
|
||||
/// Example: HexColor => #12F
|
||||
static bool isHexadecimal(String s) =>
|
||||
hasMatch(s, r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$');
|
||||
|
||||
/// Checks if string is Palindrom.
|
||||
static bool isPalindrom(String string) {
|
||||
final cleanString = string
|
||||
.toLowerCase()
|
||||
.replaceAll(RegExp(r"\s+"), '')
|
||||
.replaceAll(RegExp(r"[^0-9a-zA-Z]+"), "");
|
||||
|
||||
for (var i = 0; i < cleanString.length; i++) {
|
||||
if (cleanString[i] != cleanString[cleanString.length - i - 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Checks if all data have same value.
|
||||
/// Example: 111111 -> true, wwwww -> true, 1,1,1,1 -> true
|
||||
static bool isOneAKind(dynamic value) {
|
||||
if ((value is String || value is List) && !isNullOrBlank(value)!) {
|
||||
final first = value[0];
|
||||
final len = value.length as num;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (value[i] != first) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value is int) {
|
||||
final stringValue = value.toString();
|
||||
final first = stringValue[0];
|
||||
|
||||
for (var i = 0; i < stringValue.length; i++) {
|
||||
if (stringValue[i] != first) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Checks if string is Passport No.
|
||||
static bool isPassport(String s) =>
|
||||
hasMatch(s, r'^(?!^0+$)[a-zA-Z0-9]{6,9}$');
|
||||
|
||||
/// Checks if string is Currency.
|
||||
static bool isCurrency(String s) => hasMatch(s,
|
||||
r'^(S?\$|\₩|Rp|\¥|\€|\₹|\₽|fr|R\$|R)?[ ]?[-]?([0-9]{1,3}[,.]([0-9]{3}[,.])*[0-9]{3}|[0-9]+)([,.][0-9]{1,2})?( ?(USD?|AUD|NZD|CAD|CHF|GBP|CNY|EUR|JPY|IDR|MXN|NOK|KRW|TRY|INR|RUB|BRL|ZAR|SGD|MYR))?$');
|
||||
|
||||
/// Checks if length of data is GREATER than maxLength.
|
||||
static bool isLengthGreaterThan(dynamic value, int maxLength) {
|
||||
final length = _obtainDynamicLength(value);
|
||||
|
||||
if (length == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return length > maxLength;
|
||||
}
|
||||
|
||||
/// Checks if length of data is GREATER OR EQUAL to maxLength.
|
||||
static bool isLengthGreaterOrEqual(dynamic value, int maxLength) {
|
||||
final length = _obtainDynamicLength(value);
|
||||
|
||||
if (length == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return length >= maxLength;
|
||||
}
|
||||
|
||||
/// Checks if length of data is LOWER than maxLength.
|
||||
///
|
||||
/// This method is deprecated, use [isLengthLessThan] instead
|
||||
@deprecated
|
||||
static bool isLengthLowerThan(dynamic value, int maxLength) =>
|
||||
isLengthLessThan(value, maxLength);
|
||||
|
||||
/// Checks if length of data is LESS than maxLength.
|
||||
static bool isLengthLessThan(dynamic value, int maxLength) {
|
||||
final length = _obtainDynamicLength(value);
|
||||
if (length == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return length < maxLength;
|
||||
}
|
||||
|
||||
/// Checks if length of data is LOWER OR EQUAL to maxLength.
|
||||
///
|
||||
/// This method is deprecated, use [isLengthLessOrEqual] instead
|
||||
@deprecated
|
||||
static bool isLengthLowerOrEqual(dynamic value, int maxLength) =>
|
||||
isLengthLessOrEqual(value, maxLength);
|
||||
|
||||
/// Checks if length of data is LESS OR EQUAL to maxLength.
|
||||
static bool isLengthLessOrEqual(dynamic value, int maxLength) {
|
||||
final length = _obtainDynamicLength(value);
|
||||
|
||||
if (length == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return length <= maxLength;
|
||||
}
|
||||
|
||||
/// Checks if length of data is EQUAL to maxLength.
|
||||
static bool isLengthEqualTo(dynamic value, int otherLength) {
|
||||
final length = _obtainDynamicLength(value);
|
||||
|
||||
if (length == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return length == otherLength;
|
||||
}
|
||||
|
||||
/// Checks if length of data is BETWEEN minLength to maxLength.
|
||||
static bool isLengthBetween(dynamic value, int minLength, int maxLength) {
|
||||
if (isNull(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isLengthGreaterOrEqual(value, minLength) &&
|
||||
isLengthLessOrEqual(value, maxLength);
|
||||
}
|
||||
|
||||
/// Checks if a contains b (Treating or interpreting upper- and lowercase
|
||||
/// letters as being the same).
|
||||
static bool isCaseInsensitiveContains(String a, String b) {
|
||||
return a.toLowerCase().contains(b.toLowerCase());
|
||||
}
|
||||
|
||||
/// Checks if a contains b or b contains a (Treating or
|
||||
/// interpreting upper- and lowercase letters as being the same).
|
||||
static bool isCaseInsensitiveContainsAny(String a, String b) {
|
||||
final lowA = a.toLowerCase();
|
||||
final lowB = b.toLowerCase();
|
||||
|
||||
return lowA.contains(lowB) || lowB.contains(lowA);
|
||||
}
|
||||
|
||||
/// Checks if num a LOWER than num b.
|
||||
static bool isLowerThan(num a, num b) => a < b;
|
||||
|
||||
/// Checks if num a GREATER than num b.
|
||||
static bool isGreaterThan(num a, num b) => a > b;
|
||||
|
||||
/// Checks if num a EQUAL than num b.
|
||||
static bool isEqual(num a, num b) => a == b;
|
||||
|
||||
//Check if num is a cnpj
|
||||
static bool isCnpj(String cnpj) {
|
||||
// Obter somente os números do CNPJ
|
||||
final numbers = cnpj.replaceAll(RegExp(r'[^0-9]'), '');
|
||||
|
||||
// Testar se o CNPJ possui 14 dígitos
|
||||
if (numbers.length != 14) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Testar se todos os dígitos do CNPJ são iguais
|
||||
if (RegExp(r'^(\d)\1*$').hasMatch(numbers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dividir dígitos
|
||||
final digits = numbers.split('').map(int.parse).toList();
|
||||
|
||||
// Calcular o primeiro dígito verificador
|
||||
var calcDv1 = 0;
|
||||
var j = 0;
|
||||
for (var i in Iterable<int>.generate(12, (i) => i < 4 ? 5 - i : 13 - i)) {
|
||||
calcDv1 += digits[j++] * i;
|
||||
}
|
||||
calcDv1 %= 11;
|
||||
final dv1 = calcDv1 < 2 ? 0 : 11 - calcDv1;
|
||||
|
||||
// Testar o primeiro dígito verificado
|
||||
if (digits[12] != dv1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calcular o segundo dígito verificador
|
||||
var calcDv2 = 0;
|
||||
j = 0;
|
||||
for (var i in Iterable<int>.generate(13, (i) => i < 5 ? 6 - i : 14 - i)) {
|
||||
calcDv2 += digits[j++] * i;
|
||||
}
|
||||
calcDv2 %= 11;
|
||||
final dv2 = calcDv2 < 2 ? 0 : 11 - calcDv2;
|
||||
|
||||
// Testar o segundo dígito verificador
|
||||
if (digits[13] != dv2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Checks if the cpf is valid.
|
||||
static bool isCpf(String cpf) {
|
||||
// if (cpf == null) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// get only the numbers
|
||||
final numbers = cpf.replaceAll(RegExp(r'[^0-9]'), '');
|
||||
// Test if the CPF has 11 digits
|
||||
if (numbers.length != 11) {
|
||||
return false;
|
||||
}
|
||||
// Test if all CPF digits are the same
|
||||
if (RegExp(r'^(\d)\1*$').hasMatch(numbers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// split the digits
|
||||
final digits = numbers.split('').map(int.parse).toList();
|
||||
|
||||
// Calculate the first verifier digit
|
||||
var calcDv1 = 0;
|
||||
for (var i in Iterable<int>.generate(9, (i) => 10 - i)) {
|
||||
calcDv1 += digits[10 - i] * i;
|
||||
}
|
||||
calcDv1 %= 11;
|
||||
|
||||
final dv1 = calcDv1 < 2 ? 0 : 11 - calcDv1;
|
||||
|
||||
// Tests the first verifier digit
|
||||
if (digits[9] != dv1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate the second verifier digit
|
||||
var calcDv2 = 0;
|
||||
for (var i in Iterable<int>.generate(10, (i) => 11 - i)) {
|
||||
calcDv2 += digits[11 - i] * i;
|
||||
}
|
||||
calcDv2 %= 11;
|
||||
|
||||
final dv2 = calcDv2 < 2 ? 0 : 11 - calcDv2;
|
||||
|
||||
// Test the second verifier digit
|
||||
if (digits[10] != dv2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Capitalize each word inside string
|
||||
/// Example: your name => Your Name, your name => Your name
|
||||
static String? capitalize(String value) {
|
||||
if (isNull(value)) return null;
|
||||
if (isBlank(value)!) return value;
|
||||
return value.split(' ').map(capitalizeFirst).join(' ');
|
||||
}
|
||||
|
||||
/// Uppercase first letter inside string and let the others lowercase
|
||||
/// Example: your name => Your name
|
||||
static String? capitalizeFirst(String s) {
|
||||
if (isNull(s)) return null;
|
||||
if (isBlank(s)!) return s;
|
||||
return s[0].toUpperCase() + s.substring(1).toLowerCase();
|
||||
}
|
||||
|
||||
/// Remove all whitespace inside string
|
||||
/// Example: your name => yourname
|
||||
static String removeAllWhitespace(String value) {
|
||||
return value.replaceAll(' ', '');
|
||||
}
|
||||
|
||||
/// Camelcase string
|
||||
/// Example: your name => yourName
|
||||
static String? camelCase(String value) {
|
||||
if (isNullOrBlank(value)!) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final separatedWords =
|
||||
value.split(RegExp(r'[!@#<>?":`~;[\]\\|=+)(*&^%-\s_]+'));
|
||||
var newString = '';
|
||||
|
||||
for (final word in separatedWords) {
|
||||
newString += word[0].toUpperCase() + word.substring(1).toLowerCase();
|
||||
}
|
||||
|
||||
return newString[0].toLowerCase() + newString.substring(1);
|
||||
}
|
||||
|
||||
/// credits to "ReCase" package.
|
||||
static final RegExp _upperAlphaRegex = RegExp(r'[A-Z]');
|
||||
static final _symbolSet = {' ', '.', '/', '_', '\\', '-'};
|
||||
static List<String> _groupIntoWords(String text) {
|
||||
var sb = StringBuffer();
|
||||
var words = <String>[];
|
||||
var isAllCaps = text.toUpperCase() == text;
|
||||
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var char = text[i];
|
||||
var nextChar = i + 1 == text.length ? null : text[i + 1];
|
||||
if (_symbolSet.contains(char)) {
|
||||
continue;
|
||||
}
|
||||
sb.write(char);
|
||||
var isEndOfWord = nextChar == null ||
|
||||
(_upperAlphaRegex.hasMatch(nextChar) && !isAllCaps) ||
|
||||
_symbolSet.contains(nextChar);
|
||||
if (isEndOfWord) {
|
||||
words.add('$sb');
|
||||
sb.clear();
|
||||
}
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
/// snake_case
|
||||
static String? snakeCase(String? text, {String separator = '_'}) {
|
||||
if (isNullOrBlank(text)!) {
|
||||
return null;
|
||||
}
|
||||
return _groupIntoWords(text!)
|
||||
.map((word) => word.toLowerCase())
|
||||
.join(separator);
|
||||
}
|
||||
|
||||
/// param-case
|
||||
static String? paramCase(String? text) => snakeCase(text, separator: '-');
|
||||
|
||||
/// Extract numeric value of string
|
||||
/// Example: OTP 12312 27/04/2020 => 1231227042020ß
|
||||
/// If firstword only is true, then the example return is "12312"
|
||||
/// (first found numeric word)
|
||||
static String numericOnly(String s, {bool firstWordOnly = false}) {
|
||||
var numericOnlyStr = '';
|
||||
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (isNumericOnly(s[i])) {
|
||||
numericOnlyStr += s[i];
|
||||
}
|
||||
if (firstWordOnly && numericOnlyStr.isNotEmpty && s[i] == " ") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numericOnlyStr;
|
||||
}
|
||||
|
||||
static bool hasMatch(String? value, String pattern) {
|
||||
return (value == null) ? false : RegExp(pattern).hasMatch(value);
|
||||
}
|
||||
|
||||
static String createPath(String path, [Iterable? segments]) {
|
||||
if (segments == null || segments.isEmpty) {
|
||||
return path;
|
||||
}
|
||||
final list = segments.map((e) => '/$e');
|
||||
return path + list.join();
|
||||
}
|
||||
|
||||
static void printFunction(
|
||||
String prefix,
|
||||
dynamic value,
|
||||
String info, {
|
||||
bool isError = false,
|
||||
}) {
|
||||
Get.log('$prefix $value $info'.trim(), isError: isError);
|
||||
}
|
||||
}
|
||||
|
||||
typedef PrintFunctionCallback = void Function(
|
||||
String prefix,
|
||||
dynamic value,
|
||||
String info, {
|
||||
bool? isError,
|
||||
});
|
||||
23
packages/get/lib/get_utils/src/platform/platform.dart
Normal file
23
packages/get/lib/get_utils/src/platform/platform.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'platform_web.dart' if (dart.library.io) 'platform_io.dart';
|
||||
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class GetPlatform {
|
||||
static bool get isWeb => GeneralPlatform.isWeb;
|
||||
|
||||
static bool get isMacOS => GeneralPlatform.isMacOS;
|
||||
|
||||
static bool get isWindows => GeneralPlatform.isWindows;
|
||||
|
||||
static bool get isLinux => GeneralPlatform.isLinux;
|
||||
|
||||
static bool get isAndroid => GeneralPlatform.isAndroid;
|
||||
|
||||
static bool get isIOS => GeneralPlatform.isIOS;
|
||||
|
||||
static bool get isFuchsia => GeneralPlatform.isFuchsia;
|
||||
|
||||
static bool get isMobile => GetPlatform.isIOS || GetPlatform.isAndroid;
|
||||
|
||||
static bool get isDesktop =>
|
||||
GetPlatform.isMacOS || GetPlatform.isWindows || GetPlatform.isLinux;
|
||||
}
|
||||
21
packages/get/lib/get_utils/src/platform/platform_io.dart
Normal file
21
packages/get/lib/get_utils/src/platform/platform_io.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'dart:io';
|
||||
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class GeneralPlatform {
|
||||
static bool get isWeb => false;
|
||||
|
||||
static bool get isMacOS => Platform.isMacOS;
|
||||
|
||||
static bool get isWindows => Platform.isWindows;
|
||||
|
||||
static bool get isLinux => Platform.isLinux;
|
||||
|
||||
static bool get isAndroid => Platform.isAndroid;
|
||||
|
||||
static bool get isIOS => Platform.isIOS;
|
||||
|
||||
static bool get isFuchsia => Platform.isFuchsia;
|
||||
|
||||
static bool get isDesktop =>
|
||||
Platform.isMacOS || Platform.isWindows || Platform.isLinux;
|
||||
}
|
||||
35
packages/get/lib/get_utils/src/platform/platform_web.dart
Normal file
35
packages/get/lib/get_utils/src/platform/platform_web.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
// TODO: resolve platform/desktop by JS browser agent.
|
||||
// ignore: avoid_web_libraries_in_flutter
|
||||
import 'dart:html' as html;
|
||||
|
||||
import '../../get_utils.dart';
|
||||
|
||||
html.Navigator _navigator = html.window.navigator;
|
||||
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class GeneralPlatform {
|
||||
static bool get isWeb => true;
|
||||
|
||||
static bool get isMacOS =>
|
||||
_navigator.appVersion.contains('Mac OS') && !GeneralPlatform.isIOS;
|
||||
|
||||
static bool get isWindows => _navigator.appVersion.contains('Win');
|
||||
|
||||
static bool get isLinux =>
|
||||
(_navigator.appVersion.contains('Linux') ||
|
||||
_navigator.appVersion.contains('x11')) &&
|
||||
!isAndroid;
|
||||
|
||||
// @check https://developer.chrome.com/multidevice/user-agent
|
||||
static bool get isAndroid => _navigator.appVersion.contains('Android ');
|
||||
|
||||
static bool get isIOS {
|
||||
// maxTouchPoints is needed to separate iPad iOS13 vs new MacOS
|
||||
return GetUtils.hasMatch(_navigator.platform, r'/iPad|iPhone|iPod/') ||
|
||||
(_navigator.platform == 'MacIntel' && _navigator.maxTouchPoints! > 1);
|
||||
}
|
||||
|
||||
static bool get isFuchsia => false;
|
||||
|
||||
static bool get isDesktop => isMacOS || isWindows || isLinux;
|
||||
}
|
||||
57
packages/get/lib/get_utils/src/queue/get_queue.dart
Normal file
57
packages/get/lib/get_utils/src/queue/get_queue.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'dart:async';
|
||||
|
||||
class GetMicrotask {
|
||||
int _version = 0;
|
||||
int _microtask = 0;
|
||||
|
||||
int get microtask => _microtask;
|
||||
int get version => _version;
|
||||
|
||||
void exec(Function callback) {
|
||||
if (_microtask == _version) {
|
||||
_microtask++;
|
||||
scheduleMicrotask(() {
|
||||
_version++;
|
||||
_microtask = _version;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetQueue {
|
||||
final List<_Item> _queue = [];
|
||||
bool _active = false;
|
||||
|
||||
Future<T> add<T>(Function job) {
|
||||
var completer = Completer<T>();
|
||||
_queue.add(_Item(completer, job));
|
||||
_check();
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void cancelAllJobs() {
|
||||
_queue.clear();
|
||||
}
|
||||
|
||||
void _check() async {
|
||||
if (!_active && _queue.isNotEmpty) {
|
||||
_active = true;
|
||||
var item = _queue.removeAt(0);
|
||||
try {
|
||||
item.completer.complete(await item.job());
|
||||
} on Exception catch (e) {
|
||||
item.completer.completeError(e);
|
||||
}
|
||||
_active = false;
|
||||
_check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _Item {
|
||||
final dynamic completer;
|
||||
final dynamic job;
|
||||
|
||||
_Item(this.completer, this.job);
|
||||
}
|
||||
Reference in New Issue
Block a user