Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Created February 12, 2020 18:35
Show Gist options
  • Save lukepighetti/1bda67aed0dfdd5446f485b616adbdaf to your computer and use it in GitHub Desktop.
Save lukepighetti/1bda67aed0dfdd5446f485b616adbdaf to your computer and use it in GitHub Desktop.
Quick example of what an extensions file might look like in one of my projects
import 'package:email_validator/email_validator.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as material;
import 'package:intl/intl.dart';
import 'package:rxdart/rxdart.dart';
extension BuildContextExtensions on BuildContext {
dynamic get arguments => ModalRoute.of(this).settings.arguments;
bool dismissModalBottomSheet<T>([T result]) => navigator.pop<T>(result);
Future<T> search<T>({String query, SearchDelegate<T> delegate}) =>
showSearch(context: this, delegate: delegate, query: query);
Future<T> showModalBottomSheet<T>(WidgetBuilder builder) =>
material.showModalBottomSheet<T>(context: this, builder: builder);
TextTheme get textTheme => Theme.of(this).textTheme;
ThemeData get theme => Theme.of(this);
NavigatorState get navigator => Navigator.of(this);
}
extension ColorExtensions on Color {
Color get withSuperLightOpacity => this.withOpacity(0.15);
Color get withLightOpacity => this.withOpacity(0.25);
HSVColor get toHsv => HSVColor.fromColor(this);
Gradient get asGradient => LinearGradient(
colors: [
this,
this
.toHsv
.withSaturation((this.toHsv.saturation + 0.2).clamp(0.0, 1.0))
.toColor()
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
);
}
/// Turns the firebase_dynamic_links read API into a ValueStream
extension FirebaseDynamicLinksExtensions on FirebaseDynamicLinks {
static final _linkSubject = BehaviorSubject<PendingDynamicLinkData>();
/// This lets us access onLinkSubject naiively without having to worry about
/// our onSuccess/onError handlers getting replaced with new ones
static bool _didSetupLinkSubject = false;
/// Convert the onLink handler into a BehaviorSubject
ValueStream<PendingDynamicLinkData> get onLinkStream {
if (_didSetupLinkSubject == false) {
/// Add launching link
FirebaseDynamicLinks.instance.getInitialLink().then((v) {
if (v != null) _linkSubject.add(v);
});
/// Add all subsequent links
FirebaseDynamicLinks.instance.onLink(
onSuccess: (v) async => _linkSubject.add(v),
onError: (e) async => _linkSubject.addError(e),
);
_didSetupLinkSubject = true;
}
return _linkSubject;
}
dispose() {
_linkSubject.close();
}
}
extension IntExtensions on int {
bool isBetween(int max, int min) => this > max && this < min;
}
extension IterableExtensions<E> on Iterable<E> {
List<T> mapList<T>(T Function(E) f) => this.map<T>(f).toList();
}
extension ListExtensions<E> on List<E> {
/// Converts list into a table with specified `width`.
/// `this.length` must be evenly divisible by `width`.
List<List<E>> asTable(int width) {
final table = List<List<E>>();
for (int i = 0; i < this.length; i += width) {
final row = this.sublist(i, i + width);
table.add(row);
}
return table;
}
List<E> whereList(bool Function(E) test) => this.where(test).toList();
}
extension NumExtensions on num {
String get withCommas => NumberFormat.decimalPattern().format(this);
}
extension ObjectExtensions on Object {
bool get isNull => this == null;
bool get isNotNull => this != null;
}
extension SizedBoxExtensions on SizedBox {
SizedBox square(double dimension) =>
SizedBox.fromSize(size: Size.square(dimension));
SizedBox get eight => square(8);
SizedBox get twentyFour => square(24);
SizedBox get forty => square(40);
}
extension StringExtensions on String {
/// Matches `^[a-zA-Z ]+$`
bool get isLetters => RegExp(r"^[a-zA-Z ]+$").hasMatch(this);
/// Matches `^[0-9]+$`
bool get isNumbers => RegExp(r"^[0-9]+$").hasMatch(this);
/// Matches emails using [EmailValidator]
bool get isEmail => EmailValidator.validate(this);
/// Is between `1899` and `2222`
bool get isSchoolYear =>
this.isNumbers && int.parse(this).isBetween(1899, 2222);
/// Fuzzy search, usually used for mocking search services.
bool fuzzyContains(String query) =>
this.toLowerCase().contains(query.toLowerCase());
}
extension WidgetExtensions on Widget {
/// Convenience method to delay the display of a widget. Useful for
/// items that might display for a split second before it's replaced
/// with another widget, eg when loading data.
Widget delayed([Duration duration = const Duration(seconds: 1)]) {
return FutureBuilder<bool>(
future: Future.delayed(duration, () => true),
initialData: false,
builder: (context, snapshot) {
final isVisible = snapshot.data;
return Opacity(
opacity: isVisible ? 1 : 0,
child: this,
);
},
);
}
Widget nudge({double x = 0, double y = 0}) =>
Transform.translate(offset: Offset(x, y), child: this);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment