Skip to content

Instantly share code, notes, and snippets.

View xinthink's full-sized avatar

Yingxin Wu xinthink

View GitHub Profile
@xinthink
xinthink / build.gradle
Created September 5, 2018 10:16 — forked from gpeal/build.gradle
Airbnb Gradle Flavors
...
apply from: './flavors.gradle'
...
android {
buildTypes {
productFlavors {
project.flavors.each { flavor, config ->
"$flavor" {
dimension 'scope'
if (flavor != 'full') {
extension NoteStateX on NoteState {
/// Checks if a note in this state can be edited.
bool get canEdit => this < NoteState.deleted;
/// Returns true if this state is preceding to the other one.
bool operator <(NoteState other) => (this?.index ?? 0) < (other?.index ?? 0);
/// Message describes the state transition.
String get message {
switch (this) {
// The editor of a [Note], also shows every detail about a single note.
class NoteEditor extends StatefulWidget {
/// Create a [NoteEditor],
/// provides an existed [note] in edit mode, or `null` to create a new one.
const NoteEditor({Key key, this.note}) : super(key: key);
final Note note;
@override
State<StatefulWidget> createState() => _NoteEditorState(note);
void main() => runApp(NotesApp());
/// Root widget of the application.
class NotesApp extends StatelessWidget {
@override
Widget build(BuildContext context) => StreamProvider.value(
initialData: CurrentUser.initial,
value: FirebaseAuth.instance.onAuthStateChanged.map((user) => CurrentUser.create(user)),
child: Consumer<CurrentUser>(
builder: (context, user, _) => MaterialApp(
/// Save the note before the editor is dismissed
Future<dynamic> _onPop(String uid) => _isDirty
? _note.saveToFireStore(uid)
: Future.value();
extension NoteStore on Note {
/// Save this note to FireStore.
Future<dynamic> saveToFireStore(String uid) async {
final col = notesCollection(uid);
return id == null
? col.add(toJson())
: col.document(id).updateData(toJson());
}
...
}
class _HomeScreenState extends State<HomeScreen> with CommandHandler {
Widget _fab(BuildContext context) => FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () async {
final command = await Navigator.pushNamed(context, '/note');
processNoteCommand(_scaffoldKey.currentState, command);
},
);
...
}
mixin CommandHandler<T extends StatefulWidget> on State<T> {
/// Processes the given [command].
Future<void> processNoteCommand(ScaffoldState scaffoldState, NoteCommand command) async {
if (command == null) {
return;
}
await command.execute();
final msg = command.message;
if (mounted && msg?.isNotEmpty == true) {
scaffoldState?.showSnackBar(SnackBar(
@override
Widget build(BuildContext context) {
final uid = Provider.of<CurrentUser>(context).data.uid;
return ChangeNotifierProvider.value(
value: _note,
child: Consumer<Note>(
builder: (_, __, ___) => Hero(
tag: 'NoteItem${_note.id}',
child: DefaultTextStyle(
style: ...
// in the note list
@override
Widget build(BuildContext context) => Hero(
tag: 'NoteItem${note.id}',
child: DefaultTextStyle(
style: kNoteTextLight,
child: Container(
...
),
),