Skip to content
This repository has been archived by the owner on Sep 14, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/new_recipe_screen'
Browse files Browse the repository at this point in the history
  • Loading branch information
Teifun2 committed Aug 15, 2020
2 parents 63d3416 + f7cd859 commit 5954117
Show file tree
Hide file tree
Showing 13 changed files with 462 additions and 117 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.nextcloud_cookbook_flutter"
minSdkVersion 18
targetSdkVersion 28
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
23 changes: 18 additions & 5 deletions lib/src/blocs/recipe/recipe_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,30 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
Stream<RecipeState> mapEventToState(RecipeEvent event) async* {
if (event is RecipeLoaded) {
yield* _mapRecipeLoadedToState(event);
} else if (event is RecipeUpdated) {
yield* _mapRecipeUpdatedToState(event);
}
}


Stream<RecipeState> _mapRecipeLoadedToState(RecipeLoaded recipeLoaded) async* {
Stream<RecipeState> _mapRecipeLoadedToState(
RecipeLoaded recipeLoaded) async* {
try {
yield RecipeLoadInProgress();
final recipe = await dataRepository.fetchRecipe(recipeLoaded.recipeId);
yield RecipeLoadSuccess(recipe: recipe);
yield RecipeLoadSuccess(recipe);
} catch (_) {
yield RecipeLoadFailure(_.toString());
}
}

Stream<RecipeState> _mapRecipeUpdatedToState(
RecipeUpdated recipeUpdated) async* {
try {
yield RecipeUpdateInProgress();
int recipeId = await dataRepository.updateRecipe(recipeUpdated.recipe);
yield RecipeUpdateSuccess(recipeId);
} catch (_) {
yield RecipeLoadFailure();
yield RecipeUpdateFailure(_.toString());
}
}
}
}
12 changes: 11 additions & 1 deletion lib/src/blocs/recipe/recipe_event.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:nextcloud_cookbook_flutter/src/models/recipe.dart';

abstract class RecipeEvent extends Equatable {
const RecipeEvent();
Expand All @@ -15,4 +16,13 @@ class RecipeLoaded extends RecipeEvent {

@override
List<Object> get props => [recipeId];
}
}

class RecipeUpdated extends RecipeEvent {
final Recipe recipe;

const RecipeUpdated(this.recipe);

@override
List<Object> get props => [recipe];
}
39 changes: 34 additions & 5 deletions lib/src/blocs/recipe/recipe_state.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:nextcloud_cookbook_flutter/src/models/recipe.dart';

abstract class RecipeState extends Equatable {
Expand All @@ -11,15 +10,45 @@ abstract class RecipeState extends Equatable {

class RecipeInitial extends RecipeState {}

class RecipeLoadSuccess extends RecipeState {
class RecipeFailure extends RecipeState {
final String errorMsg;

const RecipeFailure(this.errorMsg);

@override
List<Object> get props => [errorMsg];
}

class RecipeSuccess extends RecipeState {
final Recipe recipe;

RecipeLoadSuccess({@required this.recipe});
const RecipeSuccess(this.recipe);

@override
List<Object> get props => [recipe];
}

class RecipeLoadFailure extends RecipeState {}
class RecipeLoadSuccess extends RecipeSuccess {
RecipeLoadSuccess(Recipe recipe) : super(recipe);
}

class RecipeLoadFailure extends RecipeFailure {
RecipeLoadFailure(String errorMsg) : super(errorMsg);
}

class RecipeLoadInProgress extends RecipeState {}

class RecipeUpdateFailure extends RecipeFailure {
RecipeUpdateFailure(String errorMsg) : super(errorMsg);
}

class RecipeUpdateSuccess extends RecipeState {
final int recipeId;

const RecipeUpdateSuccess(this.recipeId);

@override
List<Object> get props => [recipeId];
}

class RecipeLoadInProgress extends RecipeState {}
class RecipeUpdateInProgress extends RecipeState {}
104 changes: 97 additions & 7 deletions lib/src/models/recipe.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ class Recipe extends Equatable {
final String description;
final List<String> recipeIngredient;
final List<String> recipeInstructions;
final List<String> tool;
final int recipeYield;
final Duration prepTime;
final Duration cookTime;
final Duration totalTime;
final String keywords;
final String image;
final String url;

const Recipe._(
this.id,
Expand All @@ -24,10 +28,14 @@ class Recipe extends Equatable {
this.description,
this.recipeIngredient,
this.recipeInstructions,
this.tool,
this.recipeYield,
this.prepTime,
this.cookTime,
this.totalTime);
this.totalTime,
this.keywords,
this.image,
this.url);

factory Recipe(String jsonString) {
Map<String, dynamic> data = json.decode(jsonString);
Expand All @@ -41,16 +49,21 @@ class Recipe extends Equatable {
data["recipeIngredient"].cast<String>().toList();
List<String> recipeInstructions =
data["recipeInstructions"].cast<String>().toList();
List<String> tool = data["tool"].cast<String>().toList();
int recipeYield = data["recipeYield"];
Duration prepTime = data.containsKey("prepTime")
Duration prepTime = data.containsKey("prepTime") && data["prepTime"] != ""
? IsoTimeFormat.toDuration(data["prepTime"])
: null;
Duration cookTime = data.containsKey("cookTime")
Duration cookTime = data.containsKey("cookTime") && data["cookTime"] != ""
? IsoTimeFormat.toDuration(data["cookTime"])
: null;
Duration totalTime = data.containsKey("totalTime")
? IsoTimeFormat.toDuration(data["totalTime"])
: null;
Duration totalTime =
data.containsKey("totalTime") && data["totalTime"] != ""
? IsoTimeFormat.toDuration(data["totalTime"])
: null;
String keywords = data["keywords"];
String image = data["image"];
String url = data["url"];

return Recipe._(
id,
Expand All @@ -60,12 +73,89 @@ class Recipe extends Equatable {
description,
recipeIngredient,
recipeInstructions,
tool,
recipeYield,
prepTime,
cookTime,
totalTime);
totalTime,
keywords,
image,
url);
}

Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'imageUrl': imageUrl,
'recipeCategory': recipeCategory,
'description': description,
'recipeIngredient': recipeIngredient,
'recipeInstructions': recipeInstructions,
'tool': tool,
'recipeYield': recipeYield,
'prepTime': prepTime,
'cookTime': cookTime,
'totalTime': totalTime,
'keywords': keywords,
'image': image,
'url': url
};

MutableRecipe toMutableRecipe() {
MutableRecipe mutableRecipe = MutableRecipe();

mutableRecipe.id = this.id;
mutableRecipe.name = this.name;
mutableRecipe.imageUrl = this.imageUrl;
mutableRecipe.recipeCategory = this.recipeCategory;
mutableRecipe.description = this.description;
mutableRecipe.recipeIngredient = this.recipeIngredient;
mutableRecipe.recipeInstructions = this.recipeInstructions;
mutableRecipe.recipeYield = this.recipeYield;
mutableRecipe.prepTime = this.prepTime;
mutableRecipe.cookTime = this.cookTime;
mutableRecipe.totalTime = this.totalTime;

return mutableRecipe;
}

@override
List<Object> get props => [id];
}

class MutableRecipe {
int id;
String name;
String imageUrl;
String recipeCategory;
String description;
List<String> recipeIngredient;
List<String> recipeInstructions;
List<String> tool;
int recipeYield;
Duration prepTime;
Duration cookTime;
Duration totalTime;
String keywords;
String image;
String url;

Recipe toRecipe() {
return Recipe._(
id,
name,
imageUrl,
recipeCategory,
description,
recipeIngredient,
recipeInstructions,
tool,
recipeYield,
prepTime,
cookTime,
totalTime,
keywords,
image,
url);
}
}
4 changes: 3 additions & 1 deletion lib/src/models/recipe_short.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ class RecipeShort extends Equatable {
String get imageUrl => _imageUrl;

RecipeShort.fromJson(Map<String, dynamic> json)
: _recipeId = int.parse(json["recipe_id"]),
: _recipeId = json["recipe_id"] is int
? json["recipe_id"]
: int.parse(json["recipe_id"]),
_name = json["name"],
_imageUrl = json["imageUrl"];

Expand Down
65 changes: 65 additions & 0 deletions lib/src/screens/form/recipe_form.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nextcloud_cookbook_flutter/src/blocs/recipe/recipe.dart';
import 'package:nextcloud_cookbook_flutter/src/models/recipe.dart';
import 'package:validators/validators.dart';

class RecipeForm extends StatefulWidget {
final Recipe recipe;

const RecipeForm(this.recipe);

@override
_RecipeFormState createState() => _RecipeFormState();
}

class _RecipeFormState extends State<RecipeForm> {
final _formKey = GlobalKey<FormState>();
Recipe recipe;
MutableRecipe _mutableRecipe;

@override
void initState() {
recipe = widget.recipe;
_mutableRecipe = recipe.toMutableRecipe();

super.initState();
}

@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
initialValue: recipe.name,
decoration: InputDecoration(hintText: "Recipe Name"),
onSaved: (value) {
_mutableRecipe.name = value;
},
),
TextFormField(
initialValue: recipe.recipeYield.toString(),
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: "Recipe Yield"),
validator: (value) =>
isNumeric(value) ? null : "Recipe Yield should be a number",
onSaved: (value) => _mutableRecipe.recipeYield = int.parse(value),
),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();

BlocProvider.of<RecipeBloc>(context)
.add(RecipeUpdated(_mutableRecipe.toRecipe()));
}
},
child: Text("Update"),
)
],
),
);
}
}
3 changes: 1 addition & 2 deletions lib/src/screens/login_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';

import 'package:flutter_bloc/flutter_bloc.dart';

import '../blocs/authentication/authentication_bloc.dart';
Expand All @@ -13,7 +12,7 @@ class LoginPage extends StatelessWidget {
appBar: AppBar(
title: Text('Login'),
),
body: BlocProvider(
body: BlocProvider<LoginBloc>(
create: (context) {
return LoginBloc(
authenticationBloc: BlocProvider.of<AuthenticationBloc>(context),
Expand Down
Loading

0 comments on commit 5954117

Please sign in to comment.